summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2007-03-24 16:24:43 +0000
committerBjørn Lindeijer <bjorn@lindeijer.nl>2007-03-24 16:24:43 +0000
commitbfbb797e6c528e0650826e917d498c52362abbb0 (patch)
tree8d111b92eefe8451a66b57599217829b4127318e
parentdae5c721bf974792db526f1d736384d95a75635e (diff)
downloadmana-bfbb797e6c528e0650826e917d498c52362abbb0.tar.gz
mana-bfbb797e6c528e0650826e917d498c52362abbb0.tar.bz2
mana-bfbb797e6c528e0650826e917d498c52362abbb0.tar.xz
mana-bfbb797e6c528e0650826e917d498c52362abbb0.zip
Merged 0.0 changes from revision 3177 to 3234 to trunk.
-rw-r--r--ChangeLog162
-rw-r--r--data/graphics/gui/deepbox.pngbin266 -> 270 bytes
-rw-r--r--data/graphics/gui/mouse.pngbin984 -> 1134 bytes
-rw-r--r--data/graphics/gui/slider.pngbin502 -> 571 bytes
-rw-r--r--data/graphics/gui/thickborder.pngbin480 -> 530 bytes
-rw-r--r--data/graphics/gui/vscroll_blue.pngbin368 -> 395 bytes
-rw-r--r--data/graphics/gui/vscroll_grey.pngbin342 -> 371 bytes
-rw-r--r--data/graphics/gui/vscroll_red.pngbin367 -> 394 bytes
-rw-r--r--data/icons/CMakeLists.txt6
-rw-r--r--data/icons/Makefile.am7
-rw-r--r--data/icons/tmw-icon.icobin2238 -> 0 bytes
-rw-r--r--data/icons/tmw-icon.pngbin1103 -> 0 bytes
-rw-r--r--data/icons/tmw-icon.xpm56
-rw-r--r--data/icons/tmw.icobin0 -> 22382 bytes
-rw-r--r--data/icons/tmw.pngbin0 -> 18176 bytes
-rw-r--r--data/icons/tmw.xpm784
-rw-r--r--docs/Makefile.am2
-rw-r--r--docs/tmw.674
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/Makefile.am6
-rw-r--r--src/animatedsprite.cpp1
-rw-r--r--src/being.cpp14
-rw-r--r--src/being.h4
-rw-r--r--src/engine.cpp4
-rw-r--r--src/floor_item.cpp1
-rw-r--r--src/gui/char_select.cpp65
-rw-r--r--src/gui/char_select.h12
-rw-r--r--src/gui/equipmentwindow.cpp1
-rw-r--r--src/gui/itemcontainer.cpp8
-rw-r--r--src/gui/login.cpp87
-rw-r--r--src/gui/login.h30
-rw-r--r--src/gui/register.cpp89
-rw-r--r--src/gui/register.h37
-rw-r--r--src/gui/unregisterdialog.cpp2
-rw-r--r--src/gui/viewport.cpp110
-rw-r--r--src/gui/viewport.h24
-rw-r--r--src/localplayer.cpp1
-rw-r--r--src/localplayer.h12
-rw-r--r--src/logindata.h4
-rw-r--r--src/main.cpp101
-rw-r--r--src/monster.h1
-rw-r--r--src/net/charserverhandler.cpp24
-rw-r--r--src/net/charserverhandler.h13
-rw-r--r--src/net/equipmenthandler.cpp5
-rw-r--r--src/net/loginhandler.cpp2
-rw-r--r--src/net/protocol.h1
-rw-r--r--src/npc.cpp2
-rw-r--r--src/resources/animation.h1
-rw-r--r--src/resources/image.cpp124
-rw-r--r--src/resources/image.h6
-rw-r--r--src/resources/imageset.cpp (renamed from src/resources/spriteset.cpp)18
-rw-r--r--src/resources/imageset.h (renamed from src/resources/spriteset.h)23
-rw-r--r--src/resources/monsterdb.h2
-rw-r--r--src/resources/monsterinfo.h157
-rw-r--r--src/resources/resourcemanager.cpp22
-rw-r--r--src/resources/resourcemanager.h8
-rw-r--r--src/resources/spritedef.cpp34
-rw-r--r--src/resources/spritedef.h10
-rw-r--r--src/simpleanimation.cpp50
-rw-r--r--src/simpleanimation.h65
-rw-r--r--src/tileset.h8
-rw-r--r--src/tmw.rc2
-rw-r--r--tmw.cbp22
63 files changed, 1810 insertions, 500 deletions
diff --git a/ChangeLog b/ChangeLog
index 95cf4044..d0f661a9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,23 @@
-2007-03-23 Eugenio Favalli <elvenprogrammer@gmail.com>
+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 Eugenio Favalli <elvenprogrammer@gmail.com>
* tmw.cbp: Updated and fixed Code::Blocks project file.
@@ -6,19 +25,116 @@
* src/gui/char_select.cpp, src/gui/inventorywindow.cpp,
src/gui/ministatus.cpp, src/gui/ministatus.h, src/gui/skill.cpp,
- src/gui/skill.h, src/gui/status.cpp, src/gui/status.h, src/localplayer.cpp
- , src/localplayer.h, src/net/buysellhandler: Redesigned the localplayer
- class to use getters and setters instead of direct access to the member
- variables.
- src/net/charserverhandler.cpp, src/net/playerhandler.cpp,
- src/net/protocol.h: Implemented communication of attributes between server
- and client.
+ src/gui/skill.h, src/gui/status.cpp, src/gui/status.h,
+ src/localplayer.cpp, src/localplayer.h, src/net/buysellhandler:
+ Redesigned the localplayer class to use getters and setters instead of
+ direct access to the member variables.
+ * src/net/charserverhandler.cpp, src/net/playerhandler.cpp,
+ src/net/protocol.h: Implemented communication of attributes between
+ server and client.
+
+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 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.
* src/gui/char_select.cpp, src/gui/char_select.h,
- src/net/charserverhandler.cpp, src/net/protocol.h: Implemented a GUI for
- distributing the characters attributes at character creation.
+ src/net/charserverhandler.cpp, src/net/protocol.h: Implemented a GUI
+ for distributing the characters attributes at character creation.
+
+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-16 Philipp Sehmisch <tmw@crushnet.org>
@@ -26,6 +142,25 @@
src/net/accountserver/account.hpp: Implemented 7 atribute system
in character creation.
+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.
+
+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
@@ -34,10 +169,11 @@
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/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.
+ data/graphics/sprites/chest-cotton-female.png: Replaced cotton shirt
+ with improved version by Pauan.
2007-03-03 Rogier Polak <rogier.l.a.polak@gmail.com>
diff --git a/data/graphics/gui/deepbox.png b/data/graphics/gui/deepbox.png
index 814236ed..ed3231f3 100644
--- a/data/graphics/gui/deepbox.png
+++ b/data/graphics/gui/deepbox.png
Binary files differ
diff --git a/data/graphics/gui/mouse.png b/data/graphics/gui/mouse.png
index 9276fc7c..2eeb0e51 100644
--- a/data/graphics/gui/mouse.png
+++ b/data/graphics/gui/mouse.png
Binary files differ
diff --git a/data/graphics/gui/slider.png b/data/graphics/gui/slider.png
index 60ec2392..1f6e6b35 100644
--- a/data/graphics/gui/slider.png
+++ b/data/graphics/gui/slider.png
Binary files differ
diff --git a/data/graphics/gui/thickborder.png b/data/graphics/gui/thickborder.png
index 2bbd7a50..da72c92f 100644
--- a/data/graphics/gui/thickborder.png
+++ b/data/graphics/gui/thickborder.png
Binary files differ
diff --git a/data/graphics/gui/vscroll_blue.png b/data/graphics/gui/vscroll_blue.png
index aa236883..397501ce 100644
--- a/data/graphics/gui/vscroll_blue.png
+++ b/data/graphics/gui/vscroll_blue.png
Binary files differ
diff --git a/data/graphics/gui/vscroll_grey.png b/data/graphics/gui/vscroll_grey.png
index 6bb6bc3f..87ba8758 100644
--- a/data/graphics/gui/vscroll_grey.png
+++ b/data/graphics/gui/vscroll_grey.png
Binary files differ
diff --git a/data/graphics/gui/vscroll_red.png b/data/graphics/gui/vscroll_red.png
index aadf6925..d7ad4a90 100644
--- a/data/graphics/gui/vscroll_red.png
+++ b/data/graphics/gui/vscroll_red.png
Binary files differ
diff --git a/data/icons/CMakeLists.txt b/data/icons/CMakeLists.txt
index 30d96d86..e50c7ab9 100644
--- a/data/icons/CMakeLists.txt
+++ b/data/icons/CMakeLists.txt
@@ -1,9 +1,7 @@
SET(FILES
- tmw-icon.ico
- tmw-icon.png
- tmw-icon.xpm
+ tmw.png
)
INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}/icons)
-INSTALL(FILES "tmw-icon.png" DESTINATION share/pixmaps RENAME tmw.png)
+INSTALL(FILES "tmw.png" DESTINATION share/pixmaps)
diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am
index 26dcd623..375edef7 100644
--- a/data/icons/Makefile.am
+++ b/data/icons/Makefile.am
@@ -1,14 +1,11 @@
iconsdir = $(pkgdatadir)/data/icons
-icons_DATA = \
- tmw-icon.ico \
- tmw-icon.png \
- tmw-icon.xpm
+icons_DATA = tmw.png
install-data-local:
$(mkinstalldirs) $(DESTDIR)$(datadir)/pixmaps
- $(INSTALL) $(srcdir)/tmw-icon.png $(DESTDIR)$(datadir)/pixmaps/tmw.png
+ $(INSTALL) $(srcdir)/tmw.png $(DESTDIR)$(datadir)/pixmaps/tmw.png
uninstall-local:
rm -f $(DESTDIR)$(datadir)/pixmaps/tmw.png
diff --git a/data/icons/tmw-icon.ico b/data/icons/tmw-icon.ico
deleted file mode 100644
index 5ba6e1b7..00000000
--- a/data/icons/tmw-icon.ico
+++ /dev/null
Binary files differ
diff --git a/data/icons/tmw-icon.png b/data/icons/tmw-icon.png
deleted file mode 100644
index 2598a620..00000000
--- a/data/icons/tmw-icon.png
+++ /dev/null
Binary files differ
diff --git a/data/icons/tmw-icon.xpm b/data/icons/tmw-icon.xpm
deleted file mode 100644
index a9e91161..00000000
--- a/data/icons/tmw-icon.xpm
+++ /dev/null
@@ -1,56 +0,0 @@
-/* XPM */
-static char *dummy[]={
-"32 32 21 1",
-". c None",
-"f c #003300",
-"s c #003333",
-"# c #003366",
-"d c #006600",
-"h c #009933",
-"c c #040404",
-"m c #0c0c0c",
-"a c #3366cc",
-"e c #339933",
-"g c #33cc33",
-"o c #66cc99",
-"r c #993300",
-"n c #996633",
-"b c #99ccff",
-"j c #c0c0c0",
-"k c #cc6666",
-"q c #cc9933",
-"i c #cc9999",
-"p c #cccc66",
-"l c #efd6c6",
-"................................",
-".........................#......",
-"........#................a......",
-".......#a..............#aba#....",
-"...#.......cccccccc......a......",
-"...a......ccdeddcfdcc....#......",
-".#ab#....ccccegdheefc...........",
-"...#...cccdheeeeehdddc..........",
-".......cheheegeeehddfcc.cc......",
-"........ccdhedeeehhdcc..cic.....",
-".......ccdhgeeeheeddfc.cijc.....",
-".......cfddhehhhddfccc.cikcc....",
-".......ccccfdhedfdffc..cjliccm..",
-"..........cccdfdfcccc.cciiknc...",
-".....cccc...cccccc...cceciiicc..",
-"....cgoggccccnpqrc..mcgogeckcec.",
-"....ccggogggccqpqccmccecciidogcm",
-"....cjncgggecpncnrcccnijijikdec.",
-".....ciikceccrqqcncrciiliikcnc..",
-"....ccccccrcpqpqnrnkdkiiiiiinc..",
-"..cccgogeccnqpccpqncdcseinikrc..",
-"..cgooogggecnqcnqcpneedddsknegc.",
-"..ccccggoooggcnegeceeegdedseogg.",
-"...ccrkggggggoogggoeggegeeddcec.",
-".....ccrcceggggeggggeggegeeckcc.",
-".....mcnilkcgepccceggecceeecic..",
-"......mcriikccinkcpeeencceciic..",
-"........cijiilikiikccciknccrkc..",
-".......cckiknccckiijiiknrc.cc...",
-"........cccncc.ccnkknrccc...c...",
-"..........ccc....ccccc..........",
-"...........m...................."};
diff --git a/data/icons/tmw.ico b/data/icons/tmw.ico
new file mode 100644
index 00000000..61d559a3
--- /dev/null
+++ b/data/icons/tmw.ico
Binary files differ
diff --git a/data/icons/tmw.png b/data/icons/tmw.png
new file mode 100644
index 00000000..93e6c9ae
--- /dev/null
+++ b/data/icons/tmw.png
Binary files differ
diff --git a/data/icons/tmw.xpm b/data/icons/tmw.xpm
new file mode 100644
index 00000000..06ec2865
--- /dev/null
+++ b/data/icons/tmw.xpm
@@ -0,0 +1,784 @@
+/* XPM */
+static char * tmw_xpm[] = {
+"32 32 749 2",
+" c None",
+". c #E4EB6D",
+"+ c #EFF271",
+"@ c #E7EF65",
+"# c #DDED61",
+"$ c #D6E955",
+"% c #DAED4D",
+"& c #F6F5A0",
+"* c #EFEF89",
+"= c #ECF084",
+"- c #EDF077",
+"; c #EAF075",
+"> c #E0E960",
+", c #D9E757",
+"' c #D4EA52",
+") c #CFE74D",
+"! c #BEE140",
+"~ c #C2E43E",
+"{ c #B6DF33",
+"] c #F8F7C2",
+"^ c #F9F7AB",
+"/ c #F2F099",
+"( c #EEEF80",
+"_ c #F3F077",
+": c #F8F8B1",
+"< c #E8EE6F",
+"[ c #E1EB69",
+"} c #DBEB5E",
+"| c #D5E852",
+"1 c #CDE445",
+"2 c #CEE843",
+"3 c #B6DC34",
+"4 c #A9DA2F",
+"5 c #B3E02F",
+"6 c #B6E630",
+"7 c #F1F2E2",
+"8 c #F9F9D4",
+"9 c #F9F8C5",
+"0 c #F8F8CE",
+"a c #F9F8D6",
+"b c #F9F7CB",
+"c c #F9F7B1",
+"d c #F9F7A7",
+"e c #E7EE73",
+"f c #E4EC69",
+"g c #DEEB60",
+"h c #D8E755",
+"i c #D5EB55",
+"j c #C2E33F",
+"k c #BEE33C",
+"l c #B5E339",
+"m c #A7DF2E",
+"n c #9BDA28",
+"o c #95DA24",
+"p c #8DD724",
+"q c #F9F9F5",
+"r c #F9F9EA",
+"s c #F9F9E1",
+"t c #F9F9F4",
+"u c #F9F7DF",
+"v c #F9F7D1",
+"w c #F9F7C9",
+"x c #F9F7B6",
+"y c #F9F7AE",
+"z c #D7E363",
+"A c #E1EC6B",
+"B c #DDEC60",
+"C c #D8EC61",
+"D c #CDE552",
+"E c #C6E543",
+"F c #BCE440",
+"G c #BEE73E",
+"H c #ABDF30",
+"I c #ACE230",
+"J c #8FD720",
+"K c #80D01C",
+"L c #80D51A",
+"M c #F9F9F7",
+"N c #F9F9EB",
+"O c #F9F9F9",
+"P c #F9F7E6",
+"Q c #F9F7D3",
+"R c #F9F7CE",
+"S c #F9F7BF",
+"T c #F9F8B9",
+"U c #E6EF8F",
+"V c #E1EB65",
+"W c #E0ED63",
+"X c #D1E452",
+"Y c #D3E84D",
+"Z c #C3E340",
+"` c #BBE13E",
+" . c #B0DD35",
+".. c #ABDD2E",
+"+. c #A0DB2A",
+"@. c #95D923",
+"#. c #7ED31C",
+"$. c #7ED31A",
+"%. c #80DA18",
+"&. c #F4F3EF",
+"*. c #F9F9F6",
+"=. c #F9F8F5",
+"-. c #F9F7EE",
+";. c #F9F7E2",
+">. c #F9F7D5",
+",. c #F9F6C2",
+"'. c #F8F69C",
+"). c #D4E56D",
+"!. c #E4ED73",
+"~. c #DBEA60",
+"{. c #DDE961",
+"]. c #C9E54E",
+"^. c #BFE242",
+"/. c #BEE33E",
+"(. c #B1DE34",
+"_. c #ABDE33",
+":. c #95D826",
+"<. c #8DD620",
+"[. c #8DDB20",
+"}. c #91DD1E",
+"|. c #71D116",
+"1. c #50B910",
+"2. c #F9F8F7",
+"3. c #F9F8F4",
+"4. c #F9F7EB",
+"5. c #F9F7E1",
+"6. c #F9F5CF",
+"7. c #F9F6C9",
+"8. c #F9F6BF",
+"9. c #D6E471",
+"0. c #E9F075",
+"a. c #E3EC6B",
+"b. c #D9E96D",
+"c. c #CEE558",
+"d. c #CBE44E",
+"e. c #BEDE3E",
+"f. c #ACDA37",
+"g. c #BCE639",
+"h. c #AEE135",
+"i. c #9EDB2A",
+"j. c #8FD822",
+"k. c #7CD31B",
+"l. c #82DA1C",
+"m. c #63CE13",
+"n. c #61CE12",
+"o. c #F9F9F8",
+"p. c #F9F7F5",
+"q. c #F9F4DD",
+"r. c #F9F5D7",
+"s. c #F9F5C9",
+"t. c #F9F5B6",
+"u. c #E3ED8D",
+"v. c #DEE865",
+"w. c #E3ED6D",
+"x. c #DDEB5E",
+"y. c #D3E755",
+"z. c #CAE349",
+"A. c #CFEB4D",
+"B. c #C1E33B",
+"C. c #BCE743",
+"D. c #B0E02D",
+"E. c #95DB28",
+"F. c #95DB26",
+"G. c #C6E627",
+"H. c #E8F433",
+"I. c #CAED26",
+"J. c #60CD0F",
+"K. c #58CD0E",
+"L. c #F9F7EC",
+"M. c #F9F7F1",
+"N. c #F9F4E4",
+"O. c #F9F3D7",
+"P. c #F9F3CA",
+"Q. c #F9F5CA",
+"R. c #F9F5BB",
+"S. c #F9F8B6",
+"T. c #F6F89E",
+"U. c #DFEB5C",
+"V. c #CEE453",
+"W. c #D0E753",
+"X. c #CDE543",
+"Y. c #C7E842",
+"Z. c #C1E53C",
+"`. c #A7DC30",
+" + c #E6F453",
+".+ c #E2F448",
+"++ c #D8F03C",
+"@+ c #D1ED2E",
+"#+ c #D0F033",
+"$+ c #CAED2C",
+"%+ c #ACE51F",
+"&+ c #55CF0F",
+"*+ c #F5F6EF",
+"=+ c #F9F9F2",
+"-+ c #F9F9F1",
+";+ c #F9F8F0",
+">+ c #F9F7E7",
+",+ c #F9F5F0",
+"'+ c #F9F3E1",
+")+ c #F9F5DB",
+"!+ c #F9F6DB",
+"~+ c #F9F6BE",
+"{+ c #F8F59B",
+"]+ c #F9F5A2",
+"^+ c #F8F68D",
+"/+ c #F7F689",
+"(+ c #D7EC65",
+"_+ c #CEE84E",
+":+ c #BBE23F",
+"<+ c #B6E238",
+"[+ c #A2DC30",
+"}+ c #EBF553",
+"|+ c #E4F443",
+"1+ c #DCF340",
+"2+ c #D4F033",
+"3+ c #CEEF2D",
+"4+ c #C2E926",
+"5+ c #BEEB20",
+"6+ c #5CD50E",
+"7+ c #53CE0D",
+"8+ c #F9F7D9",
+"9+ c #F9F6F2",
+"0+ c #F9F5EB",
+"a+ c #F9F3DA",
+"b+ c #F9F6DF",
+"c+ c #F9F7D0",
+"d+ c #F9F7C2",
+"e+ c #F9F7BB",
+"f+ c #F8F68F",
+"g+ c #F7F58D",
+"h+ c #F6F58B",
+"i+ c #EEF68B",
+"j+ c #BFDF43",
+"k+ c #B5DE37",
+"l+ c #B5E234",
+"m+ c #A7DD30",
+"n+ c #E7F248",
+"o+ c #D6EF40",
+"p+ c #DBF239",
+"q+ c #D0ED2F",
+"r+ c #C3EB2A",
+"s+ c #BCEB26",
+"t+ c #B5E81E",
+"u+ c #52CE0F",
+"v+ c #4ECB0B",
+"w+ c #F9F9D9",
+"x+ c #F9F9D7",
+"y+ c #F9F8F8",
+"z+ c #F9F7E9",
+"A+ c #F9F6E9",
+"B+ c #F9F5E0",
+"C+ c #F8F2D6",
+"D+ c #F9F3CE",
+"E+ c #F9F7CA",
+"F+ c #F9F8B5",
+"G+ c #F6F691",
+"H+ c #F9F699",
+"I+ c #F5F68F",
+"J+ c #F3F579",
+"K+ c #E8F575",
+"L+ c #C7E646",
+"M+ c #B5DF37",
+"N+ c #B9E438",
+"O+ c #9CD928",
+"P+ c #D7F348",
+"Q+ c #DBEF3B",
+"R+ c #D1EF35",
+"S+ c #D7F230",
+"T+ c #C1EA25",
+"U+ c #B5E91F",
+"V+ c #63DC1E",
+"W+ c #48CA0C",
+"X+ c #F4F4DC",
+"Y+ c #F9F9C3",
+"Z+ c #F9F9C5",
+"`+ c #F9F9C7",
+" @ c #F9F9E8",
+".@ c #F9F6DD",
+"+@ c #F9F6D6",
+"@@ c #F9F3C1",
+"#@ c #F9F3BF",
+"$@ c #F9F5B8",
+"%@ c #F8F8A6",
+"&@ c #F6F68F",
+"*@ c #F4F791",
+"=@ c #ABD746",
+"-@ c #C5E449",
+";@ c #C1E448",
+">@ c #BBE23E",
+",@ c #BBE237",
+"'@ c #A9DC30",
+")@ c #99D927",
+"!@ c #D3E32C",
+"~@ c #E2F340",
+"{@ c #D3ED2D",
+"]@ c #CAED2B",
+"^@ c #CDF028",
+"/@ c #C5EB27",
+"(@ c #B0E51C",
+"_@ c #91DC13",
+":@ c #49CA08",
+"<@ c #25B305",
+"[@ c #F5F6BE",
+"}@ c #F5F5A9",
+"|@ c #F3F4B0",
+"1@ c #F6F6B0",
+"2@ c #F7F8B5",
+"3@ c #EDF097",
+"4@ c #F5F18F",
+"5@ c #F9F7B8",
+"6@ c #F9F4B0",
+"7@ c #F9F3AE",
+"8@ c #F9F3A4",
+"9@ c #F9F7A4",
+"0@ c #F7F7A0",
+"a@ c #F5F682",
+"b@ c #D3E75E",
+"c@ c #CAE646",
+"d@ c #CBE846",
+"e@ c #EDF05A",
+"f@ c #C6E432",
+"g@ c #A9E02E",
+"h@ c #99DA27",
+"i@ c #B9DB20",
+"j@ c #E1F33F",
+"k@ c #CEEB2E",
+"l@ c #C7EB27",
+"m@ c #BBEA26",
+"n@ c #B9E722",
+"o@ c #A6DF19",
+"p@ c #ABE815",
+"q@ c #48CB09",
+"r@ c #3ECA08",
+"s@ c #F8F7A7",
+"t@ c #F3F4A0",
+"u@ c #F4F59C",
+"v@ c #F0F49C",
+"w@ c #F2F5A4",
+"x@ c #F5F6A0",
+"y@ c #EFF28F",
+"z@ c #F9F8CD",
+"A@ c #F9F6A7",
+"B@ c #F9F3A0",
+"C@ c #F8F399",
+"D@ c #F8F493",
+"E@ c #F8F693",
+"F@ c #F7F58B",
+"G@ c #E8EF65",
+"H@ c #C7E445",
+"I@ c #C7DB30",
+"J@ c #E1ED48",
+"K@ c #E8F353",
+"L@ c #C3E227",
+"M@ c #D9EB2E",
+"N@ c #E7F549",
+"O@ c #D3EE3B",
+"P@ c #CBED2D",
+"Q@ c #CDEF27",
+"R@ c #BFEC23",
+"S@ c #B6E81E",
+"T@ c #A9E518",
+"U@ c #B1EB1B",
+"V@ c #35BE06",
+"W@ c #38C306",
+"X@ c #F9F9A7",
+"Y@ c #F2F38F",
+"Z@ c #F2F495",
+"`@ c #F3F38D",
+" # c #F9F9E9",
+".# c #F7F8C5",
+"+# c #F8F7D1",
+"@# c #F8F6A2",
+"## c #F9F7A9",
+"$# c #F8F59C",
+"%# c #F8F291",
+"&# c #F8F58F",
+"*# c #F6F789",
+"=# c #F2F477",
+"-# c #F0F571",
+";# c #EAEE52",
+"># c #DCEA45",
+",# c #EBEF43",
+"'# c #E4F04D",
+")# c #DEEF45",
+"!# c #E1F246",
+"~# c #E4F448",
+"{# c #DBF039",
+"]# c #D9F235",
+"^# c #C9ED2B",
+"/# c #CAEF2C",
+"(# c #CEF22B",
+"_# c #B6E91E",
+":# c #B1EB21",
+"<# c #A9E815",
+"[# c #48CF09",
+"}# c #40CD06",
+"|# c #EDEF6B",
+"1# c #EBF07C",
+"2# c #E7EB71",
+"3# c #E8E865",
+"4# c #F8F79E",
+"5# c #F8F7A4",
+"6# c #F9F69E",
+"7# c #F8F48F",
+"8# c #F6F280",
+"9# c #F6F482",
+"0# c #F3F473",
+"a# c #EFF169",
+"b# c #EDF467",
+"c# c #EAF35C",
+"d# c #EAF258",
+"e# c #E4F052",
+"f# c #E4F046",
+"g# c #E0F03F",
+"h# c #D5EE3B",
+"i# c #DFF23E",
+"j# c #D7F137",
+"k# c #CEED2E",
+"l# c #C9EF28",
+"m# c #CAF025",
+"n# c #B9EA1E",
+"o# c #B3E91D",
+"p# c #B1EB1A",
+"q# c #A6E817",
+"r# c #39C506",
+"s# c #35C505",
+"t# c #B3BC3E",
+"u# c #E9F07C",
+"v# c #DEE867",
+"w# c #F9F79E",
+"x# c #F8F793",
+"y# c #F8F78F",
+"z# c #F7F684",
+"A# c #F5F27E",
+"B# c #F4F26D",
+"C# c #F4F36F",
+"D# c #EDF061",
+"E# c #EEF363",
+"F# c #EDF35C",
+"G# c #EEF45C",
+"H# c #EAF357",
+"I# c #E8F34B",
+"J# c #DCEE43",
+"K# c #E1F03F",
+"L# c #D6ED37",
+"M# c #D5EE33",
+"N# c #D5F134",
+"O# c #D9F232",
+"P# c #CEF22D",
+"Q# c #C7F22A",
+"R# c #9BDB18",
+"S# c #A7E518",
+"T# c #AEEB1B",
+"U# c #95E514",
+"V# c #37C306",
+"W# c #3CC705",
+"X# c #E0EC60",
+"Y# c #D1E455",
+"Z# c #F7F78F",
+"`# c #F7F891",
+" $ c #F8F78B",
+".$ c #F5F782",
+"+$ c #F8F791",
+"@$ c #EFF06B",
+"#$ c #F3F36D",
+"$$ c #EFF36D",
+"%$ c #F1F56F",
+"&$ c #EDF260",
+"*$ c #EDF461",
+"=$ c #E7F150",
+"-$ c #E9F355",
+";$ c #E8F349",
+">$ c #E8F442",
+",$ c #DDF13E",
+"'$ c #DAF038",
+")$ c #CEEB26",
+"!$ c #D0EE2C",
+"~$ c #B9E82A",
+"{$ c #C1ED26",
+"]$ c #A0E41C",
+"^$ c #ABE71B",
+"/$ c #99E315",
+"($ c #99E415",
+"_$ c #33B306",
+":$ c #2BBB05",
+"<$ c #D9EB5E",
+"[$ c #CDE44E",
+"}$ c #F6F579",
+"|$ c #F4F577",
+"1$ c #F3F571",
+"2$ c #F4F57C",
+"3$ c #F3F363",
+"4$ c #F2F475",
+"5$ c #F0F567",
+"6$ c #A2D93F",
+"7$ c #C3E43F",
+"8$ c #B6D92E",
+"9$ c #A7CD1F",
+"0$ c #E4F042",
+"a$ c #E4F248",
+"b$ c #E5F348",
+"c$ c #D7EC39",
+"d$ c #DBF33C",
+"e$ c #DDF23E",
+"f$ c #D1EF2D",
+"g$ c #C1E825",
+"h$ c #BFEB26",
+"i$ c #AEE61B",
+"j$ c #A7E318",
+"k$ c #B0E818",
+"l$ c #9EE615",
+"m$ c #6DD30D",
+"n$ c #27A603",
+"o$ c #2CBE05",
+"p$ c #E2ED50",
+"q$ c #CBE348",
+"r$ c #F6F780",
+"s$ c #F5F577",
+"t$ c #F3F56F",
+"u$ c #EFF469",
+"v$ c #F3F471",
+"w$ c #F3F46F",
+"x$ c #EFF461",
+"y$ c #E7F053",
+"z$ c #C6E83F",
+"A$ c #A4D733",
+"B$ c #ABDD2F",
+"C$ c #B0DF2E",
+"D$ c #A7DD2B",
+"E$ c #E4F240",
+"F$ c #E8F555",
+"G$ c #DDF33C",
+"H$ c #E1F53E",
+"I$ c #D4F032",
+"J$ c #CEF02E",
+"K$ c #CAEF2D",
+"L$ c #C2EF28",
+"M$ c #B5E91B",
+"N$ c #93DD13",
+"O$ c #93E215",
+"P$ c #93E213",
+"Q$ c #80DB0D",
+"R$ c #45CA05",
+"S$ c #2FC204",
+"T$ c #CEE743",
+"U$ c #C1E23E",
+"V$ c #F0F365",
+"W$ c #F5F473",
+"X$ c #F2F269",
+"Y$ c #E9EF57",
+"Z$ c #EFF363",
+"`$ c #E8F052",
+" % c #EBF358",
+".% c #B8E439",
+"+% c #BCE839",
+"@% c #A4DC2A",
+"#% c #ABE22D",
+"$% c #95D822",
+"%% c #E1F240",
+"&% c #D6ED32",
+"*% c #CFEC2C",
+"=% c #D4F02F",
+"-% c #CAEE2B",
+";% c #C3EB27",
+">% c #C6EE25",
+",% c #C3EE21",
+"'% c #B8ED21",
+")% c #AEEA16",
+"!% c #79D90F",
+"~% c #2EB106",
+"{% c #26B808",
+"]% c #2CBF05",
+"^% c #C9E73B",
+"/% c #C5E63C",
+"(% c #F0F56B",
+"_% c #EEF258",
+":% c #F0F265",
+"<% c #EFF155",
+"[% c #EDF358",
+"}% c #EBF550",
+"|% c #EBF54D",
+"1% c #C9E83B",
+"2% c #A4DB28",
+"3% c #9EDC2B",
+"4% c #8FD622",
+"5% c #82D01E",
+"6% c #7EC512",
+"7% c #C9E827",
+"8% c #D0EE2E",
+"9% c #C7ED2C",
+"0% c #C7EE27",
+"a% c #C1EE2A",
+"b% c #C2EF24",
+"c% c #BEED22",
+"d% c #A9E718",
+"e% c #3EC307",
+"f% c #39C306",
+"g% c #38C606",
+"h% c #23B603",
+"i% c #ACDB2F",
+"j% c #B0DF34",
+"k% c #EDF35A",
+"l% c #EDF553",
+"m% c #E2F045",
+"n% c #E6F350",
+"o% c #E6F448",
+"p% c #9CD01E",
+"q% c #8BC916",
+"r% c #B8DC1B",
+"s% c #7CBC0F",
+"t% c #95D618",
+"u% c #7ED319",
+"v% c #BFE118",
+"w% c #C6ED2A",
+"x% c #C1EA21",
+"y% c #C1ED22",
+"z% c #B8EA1D",
+"A% c #B6EB1D",
+"B% c #BCEF1F",
+"C% c #53CA07",
+"D% c #3FC708",
+"E% c #2EBC05",
+"F% c #2FBE04",
+"G% c #2DBF04",
+"H% c #A2CF1F",
+"I% c #B1E12F",
+"J% c #B5E32E",
+"K% c #E8F243",
+"L% c #D7EB45",
+"M% c #E8F245",
+"N% c #DDEF40",
+"O% c #E2F342",
+"P% c #DFF33E",
+"Q% c #E4F542",
+"R% c #DAF138",
+"S% c #D8F230",
+"T% c #CBEB28",
+"U% c #D1F02E",
+"V% c #C6EC24",
+"W% c #CAEF25",
+"X% c #BCEB21",
+"Y% c #B6EB1E",
+"Z% c #ABE91B",
+"`% c #A2E616",
+" & c #3CC508",
+".& c #3EC906",
+"+& c #37C305",
+"@& c #27B903",
+"#& c #209B02",
+"$& c #A9DF27",
+"%& c #A4DD27",
+"&& c #91D623",
+"*& c #E3F13C",
+"=& c #E4F340",
+"-& c #E4F33F",
+";& c #E4F43E",
+">& c #E2F439",
+",& c #D6F033",
+"'& c #D5F034",
+")& c #CEEF2E",
+"!& c #CBED26",
+"~& c #CFEF27",
+"{& c #D5F22E",
+"]& c #B5E620",
+"^& c #B9EA1F",
+"/& c #84E620",
+"(& c #3EB508",
+"_& c #58CE0D",
+":& c #39CA11",
+"<& c #3EC607",
+"[& c #3BCA08",
+"}& c #28BB04",
+"|& c #28BC03",
+"1& c #8FD620",
+"2& c #97D823",
+"3& c #A6E22B",
+"4& c #69CB1D",
+"5& c #86D61F",
+"6& c #E5F740",
+"7& c #DCF338",
+"8& c #CAEC2D",
+"9& c #CDED2B",
+"0& c #D1F02C",
+"a& c #CDEE27",
+"b& c #C1EB22",
+"c& c #CFF228",
+"d& c #BCE922",
+"e& c #3CBB09",
+"f& c #50CD0C",
+"g& c #4BCD0B",
+"h& c #3CC207",
+"i& c #42CD09",
+"j& c #2EBB04",
+"k& c #28B905",
+"l& c #28B903",
+"m& c #61B113",
+"n& c #7ED41A",
+"o& c #89D71B",
+"p& c #8DDB1A",
+"q& c #7CD518",
+"r& c #8FDA1B",
+"s& c #71D314",
+"t& c #7CDA18",
+"u& c #BEF232",
+"v& c #8BD715",
+"w& c #63C207",
+"x& c #55C108",
+"y& c #5AD111",
+"z& c #4BC90B",
+"A& c #3EC108",
+"B& c #46C908",
+"C& c #40CB08",
+"D& c #34C205",
+"E& c #32C505",
+"F& c #22A003",
+"G& c #79D818",
+"H& c #75D314",
+"I& c #67D012",
+"J& c #69D313",
+"K& c #71D613",
+"L& c #67D413",
+"M& c #4BC20C",
+"N& c #4DCB0E",
+"O& c #5AD510",
+"P& c #50CA0B",
+"Q& c #4BC909",
+"R& c #3CC708",
+"S& c #42C906",
+"T& c #35C206",
+"U& c #33C306",
+"V& c #30C504",
+"W& c #49C30E",
+"X& c #71D913",
+"Y& c #84E318",
+"Z& c #5ECF0E",
+"`& c #58D00D",
+" * c #5ED40D",
+".* c #48C70A",
+"+* c #57D40B",
+"@* c #37BE06",
+"#* c #39C707",
+"$* c #37C505",
+"%* c #34C705",
+"&* c #49BE0B",
+"** c #4BD00C",
+"=* c #46C609",
+"-* c #46D00A",
+";* c #33BE06",
+">* c #20A904",
+" . + @ # $ % ",
+" & * = - ; > , ' ) ! ~ { ",
+" ] ^ / ( _ : < [ } | 1 2 3 4 5 6 ",
+" 7 8 9 0 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 M N O P u Q R S T U V W X Y Z ` ...+.@.#.$.%. ",
+" &.O *.O =.-.;.>.R ,.'.).!.~.{.].^./.(._.:.<.[.}.|.1. ",
+" O O O 2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n. ",
+" o.O *.p.p.3.-.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K. ",
+" O o.q L.p.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+++@+#+$+%+&+ ",
+" *+=+-+;+>+p.,+'+)+!+~+8.{+]+^+/+(+_+:+<+[+}+|+1+2+3+4+5+6+7+ ",
+" r N N 8+p.9+0+a+b+c+d+e+d f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+u+v+ ",
+" w+x+w+y+z+A+B+C+D+E+S F+G+H+I+J+K+L+M+N+O+P+Q+R+S+$+T+U+V+W+ ",
+"X+Y+Z+`+ @.@+@6.@@#@$@^ %@&@*@=@-@;@>@,@'@)@!@~@{@]@^@/@(@_@:@<@",
+"[@}@|@1@2@3@4@5@6@7@8@9@0@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@`@ #.#+#@###$#%#&#*#=#-#;#>#,#'#)#!#~#{#]#^#/#(#_#:#<#[#}#",
+"|#1#2#3#4###5#'.6#7#8#9#0#a#b#c#d#e#f#g#h#i#j#k#l#m#n#o#p#q#r#s#",
+"t#u#v#w#s@x#y#z#a@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#`# $.$+$@$#$$$%$&$*$=$-$I#;$>$,$'$)$!$~${$]$^$/$($_$:$ ",
+" <$[$}$|$*#1$2$3$4$5$6$7$8$9$0$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$`$ %.%+%@%#%$%%%&%*%=%-%;%>%,%'%)%!%~%{%]% ",
+" ^%/%(%_%:%<%[%}%|%1%2%3%4%5%6%7%8%9%0%a%b%c%d%($e%f%g%h% ",
+" i%j%k%l%a$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%G$R%S%T%U%V%W%X%Y%Z%`% &.&+&@&#& ",
+" $&%&&&*&=&-&;&>&,&'&)&!&~&{&]&^&/&(&_&:&<&[&}&|& ",
+" 1&2&3&4&5&6&7&8&9&0&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&`& *.*+*@*#*$*%* ",
+" &***=*-*;*>* "};
diff --git a/docs/Makefile.am b/docs/Makefile.am
index e106768b..8b57d5bb 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -1,3 +1,5 @@
+man6_MANS = tmw.6
+
EXTRA_DIST = packages.txt \
FAQ.txt \
HACKING.txt \
diff --git a/docs/tmw.6 b/docs/tmw.6
new file mode 100644
index 00000000..0dee82c7
--- /dev/null
+++ b/docs/tmw.6
@@ -0,0 +1,74 @@
+.TH "TMW" "6"
+.SH "NAME"
+tmw \- tmw is The Mana World: A fantasy online game
+.SH "SYNOPSIS"
+\fBtmw\fR
+.SH "DESCRIPTION"
+This manual page documents briefly the
+\fBtmw\fR ingame
+commands.
+\fBtmw\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 \-h, \-\-help
+Show summary of options.
+.TP
+.B \-v, \-\-version
+Show version of the program.
+.TP
+.B \-u, \-\-skipupdate
+Skip the update process.
+.TP
+.B \-U, \-\-username
+Login with this username.
+.TP
+.B \-P, \-\-password
+Login with this password.
+.TP
+.B \-D, \-\-default
+Bypass the login process with default settings.
+.TP
+.B \-p, \-\-playername
+Login with this player.
+.TP
+.B \-C, \-\-configfile
+Configuration file to use
+.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 World 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/src/CMakeLists.txt b/src/CMakeLists.txt
index 4b5bad01..e28e235e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -268,10 +268,10 @@ SET(SRCS
resources/sdlimageloader.h
resources/soundeffect.cpp
resources/soundeffect.h
- resources/spriteset.cpp
resources/spritedef.h
resources/spritedef.cpp
- resources/spriteset.h
+ resources/imageset.h
+ resources/imageset.cpp
utils/base64.cpp
utils/base64.h
utils/dtor.h
@@ -330,6 +330,8 @@ SET(SRCS
player.h
properties.h
serverinfo.h
+ simpleanimation.cpp
+ simpleanimation.h
sound.cpp
sound.h
sprite.h
diff --git a/src/Makefile.am b/src/Makefile.am
index da1bc44d..f1f51b79 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -222,8 +222,8 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \
resources/soundeffect.cpp \
resources/spritedef.h \
resources/spritedef.cpp \
- resources/spriteset.h \
- resources/spriteset.cpp \
+ resources/imageset.h \
+ resources/imageset.cpp \
resources/buddylist.h \
resources/buddylist.cpp \
utils/base64.cpp \
@@ -284,6 +284,8 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \
player.h \
properties.h \
serverinfo.h \
+ simpleanimation.cpp \
+ simpleanimation.h \
sound.cpp \
sound.h \
sprite.h \
diff --git a/src/animatedsprite.cpp b/src/animatedsprite.cpp
index 3d1979a9..7260a512 100644
--- a/src/animatedsprite.cpp
+++ b/src/animatedsprite.cpp
@@ -30,7 +30,6 @@
#include "resources/animation.h"
#include "resources/image.h"
#include "resources/resourcemanager.h"
-#include "resources/spriteset.h"
#include "utils/xml.h"
diff --git a/src/being.cpp b/src/being.cpp
index e4a1e9fc..682daddb 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -34,7 +34,7 @@
#include "map.h"
#include "resources/resourcemanager.h"
-#include "resources/spriteset.h"
+#include "resources/imageset.h"
#include "gui/gui.h"
@@ -42,7 +42,7 @@
#include "utils/tostring.h"
int Being::instances = 0;
-Spriteset *Being::emotionset = NULL;
+ImageSet *Being::emotionSet = NULL;
Being::Being(Uint16 id, Uint16 job, Map *map):
mJob(job),
@@ -72,8 +72,8 @@ Being::Being(Uint16 id, Uint16 job, Map *map):
{
// Load the emotion set
ResourceManager *rm = ResourceManager::getInstance();
- emotionset = rm->getSpriteset("graphics/sprites/emotions.png", 30, 32);
- if (!emotionset) logger->error("Unable to load emotions spriteset!");
+ emotionSet = rm->getImageSet("graphics/sprites/emotions.png", 30, 32);
+ if (!emotionSet) logger->error("Unable to load emotions!");
}
instances++;
@@ -89,8 +89,8 @@ Being::~Being()
if (instances == 0)
{
- emotionset->decRef();
- emotionset = NULL;
+ emotionSet->decRef();
+ emotionSet = NULL;
}
}
@@ -515,7 +515,7 @@ Being::drawEmotion(Graphics *graphics, int offsetX, int offsetY)
int px = mPx + offsetX + 3;
int py = mPy + offsetY - 60;
- graphics->drawImage(emotionset->get(mEmotion - 1), px, py);
+ graphics->drawImage(emotionSet->get(mEmotion - 1), px, py);
}
void
diff --git a/src/being.h b/src/being.h
index c3cba247..332f1b4a 100644
--- a/src/being.h
+++ b/src/being.h
@@ -41,7 +41,7 @@ class Equipment;
class Item;
class Map;
class Graphics;
-class Spriteset;
+class ImageSet;
/**
* A position along a being's path.
@@ -397,7 +397,7 @@ class Being : public Sprite
Uint16 mStepTime;
static int instances; /**< Number of Being instances */
- static Spriteset *emotionset; /**< Emoticons used by beings */
+ static ImageSet *emotionSet; /**< Emoticons used by beings */
};
#endif
diff --git a/src/engine.cpp b/src/engine.cpp
index a3097d49..31bec9ff 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -44,7 +44,6 @@
#include "resources/mapreader.h"
#include "resources/monsterdb.h"
#include "resources/resourcemanager.h"
-#include "resources/spriteset.h"
#include "utils/dtor.h"
#include "utils/tostring.h"
@@ -77,7 +76,8 @@ void Engine::changeMap(const std::string &mapPath)
// Notify the minimap and beingManager about the map change
Image *mapImage = NULL;
- if (newMap->hasProperty("minimap")) {
+ if (newMap->hasProperty("minimap"))
+ {
ResourceManager *resman = ResourceManager::getInstance();
mapImage = resman->getImage(newMap->getProperty("minimap"));
}
diff --git a/src/floor_item.cpp b/src/floor_item.cpp
index f33f7eb4..5d83e1dd 100644
--- a/src/floor_item.cpp
+++ b/src/floor_item.cpp
@@ -27,7 +27,6 @@
#include "resources/itemdb.h"
#include "resources/iteminfo.h"
-#include "resources/spriteset.h"
FloorItem::FloorItem(unsigned int id,
diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp
index 09ce5b87..128a803e 100644
--- a/src/gui/char_select.cpp
+++ b/src/gui/char_select.cpp
@@ -42,9 +42,14 @@
#include "../logindata.h"
#include "../net/accountserver/account.h"
+#include "../net/charserverhandler.h"
+#include "../net/messageout.h"
#include "../utils/tostring.h"
+// Defined in main.cpp, used here for setting the char create dialog
+extern CharServerHandler charServerHandler;
+
/**
* Listener for confirming character deletion.
*/
@@ -155,14 +160,14 @@ void CharSelectDialog::action(const gcn::ActionEvent &event)
}
else if (event.getId() == "new")
{
- //TODO: search the first free slot, and start CharCreateDialog
- // maybe add that search to the constructor
+ // TODO: Search the first free slot, and start CharCreateDialog
+ // maybe add that search to the constructor.
if (!(mCharInfo->getEntry()))
{
// Start new character dialog
- mCharInfo->lock();
- new CharCreateDialog(this, mCharInfo->getPos());
- mCharInfo->unlock();
+ CharCreateDialog *charCreateDialog =
+ new CharCreateDialog(this, mCharInfo->getPos());
+ charServerHandler.setCharCreateDialog(charCreateDialog);
}
}
else if (event.getId() == "delete")
@@ -344,14 +349,19 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot):
setLocationRelativeTo(getParent());
setVisible(true);
+ mNameField->requestFocus();
}
CharCreateDialog::~CharCreateDialog()
{
delete mPlayer;
+
+ // Make sure the char server handler knows that we're gone
+ charServerHandler.setCharCreateDialog(0);
}
-void CharCreateDialog::action(const gcn::ActionEvent &event)
+void
+CharCreateDialog::action(const gcn::ActionEvent &event)
{
if (event.getId() == "create") {
if (getName().length() >= 4) {
@@ -362,15 +372,14 @@ void CharCreateDialog::action(const gcn::ActionEvent &event)
mPlayer->getHairStyle(),
mPlayer->getHairColor(),
0, // gender
- (int)mAttributeSlider[0]->getValue(), // STR
- (int)mAttributeSlider[1]->getValue(), // AGI
- (int)mAttributeSlider[2]->getValue(), // DEX
- (int)mAttributeSlider[3]->getValue(), // VIT
- (int)mAttributeSlider[4]->getValue(), // INT
- (int)mAttributeSlider[5]->getValue(), // WILL
- (int)mAttributeSlider[6]->getValue() // CHAR
+ (int) mAttributeSlider[0]->getValue(), // STR
+ (int) mAttributeSlider[1]->getValue(), // AGI
+ (int) mAttributeSlider[2]->getValue(), // DEX
+ (int) mAttributeSlider[3]->getValue(), // VIT
+ (int) mAttributeSlider[4]->getValue(), // INT
+ (int) mAttributeSlider[5]->getValue(), // WILL
+ (int) mAttributeSlider[6]->getValue() // CHAR
);
- scheduleDelete();
}
else {
new OkDialog("Error",
@@ -399,21 +408,23 @@ void CharCreateDialog::action(const gcn::ActionEvent &event)
}
}
-std::string CharCreateDialog::getName()
+const std::string&
+CharCreateDialog::getName()
{
return mNameField->getText();
}
void CharCreateDialog::UpdateSliders()
{
- for (int i=0; i<=6; i++)
+ for (int i = 0; i < 7; i++)
{
- // update captions
- mAttributeValue[i]->setCaption(toString((int)(mAttributeSlider[i]->getValue())));
+ // Update captions
+ mAttributeValue[i]->setCaption(
+ toString((int) (mAttributeSlider[i]->getValue())));
mAttributeValue[i]->adjustSize();
}
- // update distributed points
+ // Update distributed points
int pointsLeft = 70 - getDistributedPoints();
if (pointsLeft == 0)
{
@@ -425,24 +436,32 @@ void CharCreateDialog::UpdateSliders()
mCreateButton->setEnabled(false);
if (pointsLeft > 0)
{
- mAttributesLeft->setCaption(std::string("Please distribute " + toString(pointsLeft) + " points"));
+ mAttributesLeft->setCaption(std::string("Please distribute " +
+ toString(pointsLeft) + " points"));
}
else
{
- mAttributesLeft->setCaption(std::string("Please remove " + toString(-pointsLeft) + " points"));
+ mAttributesLeft->setCaption(std::string("Please remove " +
+ toString(-pointsLeft) + " points"));
}
}
mAttributesLeft->adjustSize();
}
+void
+CharCreateDialog::unlock()
+{
+ mCreateButton->setEnabled(true);
+}
+
int CharCreateDialog::getDistributedPoints()
{
int points = 0;
- for (int i=0; i<7; i++)
+ for (int i = 0; i < 7; i++)
{
- points += (int)mAttributeSlider[i]->getValue();
+ points += (int) mAttributeSlider[i]->getValue();
}
return points;
}
diff --git a/src/gui/char_select.h b/src/gui/char_select.h
index 5066897e..9d9184ea 100644
--- a/src/gui/char_select.h
+++ b/src/gui/char_select.h
@@ -114,9 +114,17 @@ class CharCreateDialog : public Window, public gcn::ActionListener
*/
~CharCreateDialog();
- void action(const gcn::ActionEvent &event);
+ void
+ action(const gcn::ActionEvent &event);
- std::string getName();
+ const std::string&
+ getName();
+
+ /**
+ * Unlocks the dialog, enabling the create character button again.
+ */
+ void
+ unlock();
private:
int getDistributedPoints();
diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp
index ec525c47..ec84491e 100644
--- a/src/gui/equipmentwindow.cpp
+++ b/src/gui/equipmentwindow.cpp
@@ -30,7 +30,6 @@
#include "../resources/iteminfo.h"
#include "../resources/resourcemanager.h"
-#include "../resources/spriteset.h"
#include "../utils/tostring.h"
diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp
index 308311b7..a176f226 100644
--- a/src/gui/itemcontainer.cpp
+++ b/src/gui/itemcontainer.cpp
@@ -35,7 +35,6 @@
#include "../resources/image.h"
#include "../resources/iteminfo.h"
#include "../resources/resourcemanager.h"
-#include "../resources/spriteset.h"
#include "../utils/tostring.h"
@@ -65,7 +64,8 @@ ItemContainer::logic()
int i = mInventory->getLastUsedSlot() + 1;
- if (i != mMaxItems) {
+ if (i != mMaxItems)
+ {
mMaxItems = i;
setWidth(getWidth());
}
@@ -192,9 +192,9 @@ ItemContainer::mousePressed(gcn::MouseEvent &event)
int my = event.getY();
int index = mx / gridWidth + ((my / gridHeight) * columns);
- if (index > INVENTORY_SIZE) {
+ if (index > INVENTORY_SIZE)
index = INVENTORY_SIZE - 1;
- }
+
setSelectedItem(mInventory->getItem(index));
}
}
diff --git a/src/gui/login.cpp b/src/gui/login.cpp
index 9df3b489..15ec6314 100644
--- a/src/gui/login.cpp
+++ b/src/gui/login.cpp
@@ -36,24 +36,6 @@
#include "passwordfield.h"
#include "textfield.h"
-void
-WrongDataNoticeListener::setTarget(gcn::TextField *textField)
-{
- mTarget = textField;
-}
-
-void
-WrongDataNoticeListener::action(const gcn::ActionEvent &event)
-{
- if (event.getId() == "ok")
- {
- // Reset the field
- mTarget->setText("");
- mTarget->setCaretPosition(0);
- mTarget->requestFocus();
- }
-}
-
LoginDialog::LoginDialog(LoginData *loginData):
Window("Login"), mLoginData(loginData)
{
@@ -66,28 +48,33 @@ LoginDialog::LoginDialog(LoginData *loginData):
mCancelButton = new Button("Cancel", "cancel", this);
mRegisterButton = new Button("Register", "register", this);
- setContentSize(200, 91);
+ const int width = 220;
+ const int height = 100;
+
+ setContentSize(width, height);
userLabel->setPosition(5, 5);
passLabel->setPosition(5, 14 + userLabel->getHeight());
mUserField->setPosition(65, 5);
mPassField->setPosition(65, 14 + userLabel->getHeight());
- mUserField->setWidth(130);
- mPassField->setWidth(130);
+ mUserField->setWidth(width - 70);
+ mPassField->setWidth(width - 70);
mKeepCheck->setPosition(4, 68);
mCancelButton->setPosition(
- 200 - mCancelButton->getWidth() - 5,
- 91 - mCancelButton->getHeight() - 5);
+ width - mCancelButton->getWidth() - 5,
+ height - mCancelButton->getHeight() - 5);
mOkButton->setPosition(
mCancelButton->getX() - mOkButton->getWidth() - 5,
- 91 - mOkButton->getHeight() - 5);
+ height - mOkButton->getHeight() - 5);
mRegisterButton->setPosition(
mKeepCheck->getX() + mKeepCheck->getWidth() + 10,
- 91 - mRegisterButton->getHeight() - 5);
+ height - mRegisterButton->getHeight() - 5);
mUserField->setActionEventId("ok");
mPassField->setActionEventId("ok");
+ mUserField->addKeyListener(this);
+ mPassField->addKeyListener(this);
mUserField->addActionListener(this);
mPassField->addActionListener(this);
mKeepCheck->addActionListener(this);
@@ -110,37 +97,27 @@ LoginDialog::LoginDialog(LoginData *loginData):
mPassField->requestFocus();
}
- mWrongDataNoticeListener = new WrongDataNoticeListener();
+ mOkButton->setEnabled(canSubmit());
}
LoginDialog::~LoginDialog()
{
- delete mWrongDataNoticeListener;
}
void
LoginDialog::action(const gcn::ActionEvent &event)
{
- if (event.getId() == "ok")
+ if (event.getId() == "ok" && canSubmit())
{
- // Check login
- if (mUserField->getText().empty())
- {
- mWrongDataNoticeListener->setTarget(mPassField);
- OkDialog *dlg = new OkDialog("Error", "Enter your username first");
- dlg->addActionListener(mWrongDataNoticeListener);
- }
- else
- {
- mLoginData->username = mUserField->getText();
- mLoginData->password = mPassField->getText();
- mLoginData->remember = mKeepCheck->isMarked();
-
- mOkButton->setEnabled(false);
- mRegisterButton->setEnabled(false);
-
- state = STATE_LOGIN_ATTEMPT;
- }
+ mLoginData->username = mUserField->getText();
+ mLoginData->password = mPassField->getText();
+ mLoginData->remember = mKeepCheck->isMarked();
+ mLoginData->registerLogin = false;
+
+ mOkButton->setEnabled(false);
+ mRegisterButton->setEnabled(false);
+
+ state = STATE_LOGIN_ATTEMPT;
}
else if (event.getId() == "cancel")
{
@@ -148,6 +125,24 @@ LoginDialog::action(const gcn::ActionEvent &event)
}
else if (event.getId() == "register")
{
+ // Transfer these fields on to the register dialog
+ mLoginData->username = mUserField->getText();
+ mLoginData->password = mPassField->getText();
+
state = STATE_REGISTER;
}
}
+
+void
+LoginDialog::keyPressed(gcn::KeyEvent &keyEvent)
+{
+ mOkButton->setEnabled(canSubmit());
+}
+
+bool
+LoginDialog::canSubmit()
+{
+ return !mUserField->getText().empty() &&
+ !mPassField->getText().empty() &&
+ state == STATE_LOGIN;
+}
diff --git a/src/gui/login.h b/src/gui/login.h
index 05c0da31..d8ae7eaf 100644
--- a/src/gui/login.h
+++ b/src/gui/login.h
@@ -26,6 +26,7 @@
#include <iosfwd>
#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
#include "window.h"
#include "../guichanfwd.h"
@@ -33,22 +34,13 @@
class LoginData;
/**
- * Listener used for handling wrong data.
- */
-class WrongDataNoticeListener : public gcn::ActionListener {
- public:
- void setTarget(gcn::TextField *textField);
- void action(const gcn::ActionEvent &event);
- private:
- gcn::TextField *mTarget;
-};
-
-/**
* The login dialog.
*
* \ingroup Interface
*/
-class LoginDialog : public Window, public gcn::ActionListener {
+class LoginDialog : public Window, public gcn::ActionListener,
+ public gcn::KeyListener
+{
public:
/**
* Constructor
@@ -67,7 +59,19 @@ class LoginDialog : public Window, public gcn::ActionListener {
*/
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 login
+ * state, when all necessary fields have some text.
+ */
+ bool
+ canSubmit();
+
gcn::TextField *mUserField;
gcn::TextField *mPassField;
gcn::CheckBox *mKeepCheck;
@@ -75,8 +79,6 @@ class LoginDialog : public Window, public gcn::ActionListener {
gcn::Button *mCancelButton;
gcn::Button *mRegisterButton;
- WrongDataNoticeListener *mWrongDataNoticeListener;
-
LoginData *mLoginData;
};
diff --git a/src/gui/register.cpp b/src/gui/register.cpp
index be15747d..c8e01a6c 100644
--- a/src/gui/register.cpp
+++ b/src/gui/register.cpp
@@ -41,6 +41,21 @@
#include "textfield.h"
#include "ok_dialog.h"
+void
+WrongDataNoticeListener::setTarget(gcn::TextField *textField)
+{
+ mTarget = textField;
+}
+
+void
+WrongDataNoticeListener::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "ok")
+ {
+ mTarget->requestFocus();
+ }
+}
+
RegisterDialog::RegisterDialog(LoginData *loginData):
Window("Register"),
mWrongDataNoticeListener(new WrongDataNoticeListener()),
@@ -50,28 +65,28 @@ RegisterDialog::RegisterDialog(LoginData *loginData):
gcn::Label *passwordLabel = new gcn::Label("Password:");
gcn::Label *confirmLabel = new gcn::Label("Confirm:");
gcn::Label *emailLabel = new gcn::Label("Email:");
- mUserField = new TextField("player");
- mPasswordField = new PasswordField();
+ mUserField = new TextField(loginData->username);
+ mPasswordField = new PasswordField(loginData->password);
mConfirmField = new PasswordField();
mEmailField = new TextField();
mRegisterButton = new Button("Register", "register", this);
mCancelButton = new Button("Cancel", "cancel", this);
- const int width = 200;
+ const int width = 220;
const int height = 130;
setContentSize(width, height);
mUserField->setPosition(65, 5);
- mUserField->setWidth(130);
+ mUserField->setWidth(width - 70);
mPasswordField->setPosition(
65, mUserField->getY() + mUserField->getHeight() + 7);
- mPasswordField->setWidth(130);
+ mPasswordField->setWidth(mUserField->getWidth());
mConfirmField->setPosition(
65, mPasswordField->getY() + mPasswordField->getHeight() + 7);
- mConfirmField->setWidth(130);
+ mConfirmField->setWidth(mUserField->getWidth());
mEmailField->setPosition(
65, mConfirmField->getY() + mConfirmField->getHeight() + 7);
- mEmailField->setWidth(130);
+ mEmailField->setWidth(mUserField->getWidth());
userLabel->setPosition(5, mUserField->getY() + 1);
passwordLabel->setPosition(5, mPasswordField->getY() + 1);
@@ -79,11 +94,30 @@ RegisterDialog::RegisterDialog(LoginData *loginData):
emailLabel->setPosition(5, mEmailField->getY() + 1);
mCancelButton->setPosition(
- width - 5 - mCancelButton->getWidth(),
- height - 5 - mCancelButton->getHeight());
+ width - mCancelButton->getWidth() - 5,
+ height - mCancelButton->getHeight() - 5);
mRegisterButton->setPosition(
- mCancelButton->getX() - 5 - mRegisterButton->getWidth(),
- mCancelButton->getY());
+ mCancelButton->getX() - mRegisterButton->getWidth() - 5,
+ height - mRegisterButton->getHeight() - 5);
+
+ mUserField->addKeyListener(this);
+ mPasswordField->addKeyListener(this);
+ mConfirmField->addKeyListener(this);
+ mEmailField->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");
+ mEmailField->setActionEventId("register");
+ mUserField->addActionListener(this);
+ mPasswordField->addActionListener(this);
+ mConfirmField->addActionListener(this);
+ mEmailField->addActionListener(this);
add(userLabel);
add(passwordLabel);
@@ -100,6 +134,8 @@ RegisterDialog::RegisterDialog(LoginData *loginData):
setVisible(true);
mUserField->requestFocus();
mUserField->setCaretPosition(mUserField->getText().length());
+
+ mRegisterButton->setEnabled(canSubmit());
}
RegisterDialog::~RegisterDialog()
@@ -114,7 +150,7 @@ RegisterDialog::action(const gcn::ActionEvent &event)
{
state = STATE_LOGIN;
}
- else if (event.getId() == "register")
+ else if (event.getId() == "register" && canSubmit())
{
const std::string user = mUserField->getText();
logger->log("RegisterDialog::register Username is %s", user.c_str());
@@ -122,14 +158,7 @@ RegisterDialog::action(const gcn::ActionEvent &event)
std::stringstream errorMsg;
int error = 0;
- // Check login
- if (user.empty())
- {
- // No username
- errorMsg << "Enter your username first.";
- error = 1;
- }
- else if (user.length() < LEN_MIN_USERNAME)
+ if (user.length() < LEN_MIN_USERNAME)
{
// Name too short
errorMsg << "The username needs to be at least "
@@ -178,9 +207,11 @@ RegisterDialog::action(const gcn::ActionEvent &event)
}
else if (error == 2)
{
- mWrongDataNoticeListener->setTarget(this->mPasswordField);
// Reset password confirmation
+ mPasswordField->setText("");
mConfirmField->setText("");
+
+ mWrongDataNoticeListener->setTarget(this->mPasswordField);
}
OkDialog *dlg = new OkDialog("Error", errorMsg.str());
@@ -191,7 +222,6 @@ RegisterDialog::action(const gcn::ActionEvent &event)
// No errors detected, register the new user.
mRegisterButton->setEnabled(false);
- mLoginData->port = (short)config.getValue("port", 0);
mLoginData->username = mUserField->getText();
mLoginData->password = mPasswordField->getText();
mLoginData->email = mEmailField->getText();
@@ -201,3 +231,18 @@ RegisterDialog::action(const gcn::ActionEvent &event)
}
}
}
+
+void
+RegisterDialog::keyPressed(gcn::KeyEvent &keyEvent)
+{
+ mRegisterButton->setEnabled(canSubmit());
+}
+
+bool
+RegisterDialog::canSubmit()
+{
+ return !mUserField->getText().empty() &&
+ !mPasswordField->getText().empty() &&
+ !mConfirmField->getText().empty() &&
+ state == STATE_REGISTER;
+}
diff --git a/src/gui/register.h b/src/gui/register.h
index 4ffe451f..088e8f9b 100644
--- a/src/gui/register.h
+++ b/src/gui/register.h
@@ -26,23 +26,39 @@
#include <iosfwd>
#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
#include "window.h"
#include "../guichanfwd.h"
class LoginData;
class OkDialog;
-class WrongDataNoticeListener;
/**
- * The login dialog.
+ * 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:
+ 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 {
+class RegisterDialog : public Window, public gcn::ActionListener,
+ public gcn::KeyListener
+{
public:
/**
- * Constructor
+ * Constructor. Name, password and server fields will be initialized to
+ * the information already present in the LoginData instance.
*
* @see Window::Window
*/
@@ -58,10 +74,19 @@ class RegisterDialog : public Window, public gcn::ActionListener {
*/
void action(const gcn::ActionEvent &event);
- // Made them public to have the possibility to request focus
- // from external functions.
+ /**
+ * 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();
+
gcn::TextField *mUserField;
gcn::TextField *mPasswordField;
gcn::TextField *mConfirmField;
diff --git a/src/gui/unregisterdialog.cpp b/src/gui/unregisterdialog.cpp
index 9a09389d..5558e8fc 100644
--- a/src/gui/unregisterdialog.cpp
+++ b/src/gui/unregisterdialog.cpp
@@ -34,7 +34,7 @@
#include "button.h"
#include "checkbox.h"
-#include "login.h"
+#include "register.h"
#include "passwordfield.h"
#include "textfield.h"
#include "ok_dialog.h"
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index bc635cce..f3e9031c 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -28,15 +28,20 @@
#include "gui.h"
#include "popupmenu.h"
+#include "../simpleanimation.h"
#include "../beingmanager.h"
#include "../configuration.h"
#include "../flooritemmanager.h"
#include "../graphics.h"
#include "../localplayer.h"
#include "../map.h"
+#include "../monster.h"
#include "../npc.h"
-#include "../resources/monsterdb.h"
+#include "../resources/animation.h"
+#include "../resources/monsterinfo.h"
+#include "../resources/resourcemanager.h"
+#include "../resources/imageset.h"
#include "../utils/tostring.h"
@@ -60,11 +65,39 @@ Viewport::Viewport():
config.addListener("ScrollRadius", this);
mPopupMenu = new PopupMenu();
+
+ // Load target cursors
+ ResourceManager *resman = ResourceManager::getInstance();
+ mInRangeImages = resman->getImageSet(
+ "graphics/gui/target-cursor-blue.png", 44, 35);
+ mOutRangeImages = resman->getImageSet(
+ "graphics/gui/target-cursor-red.png", 44, 35);
+ Animation *animInRange = new Animation();
+ Animation *animOutRange = new Animation();
+
+ for (unsigned int i = 0; i < mInRangeImages->size(); ++i)
+ {
+ animInRange->addFrame(mInRangeImages->get(i), 75, 0, 0);
+ }
+
+ for (unsigned int j = 0; j < mOutRangeImages->size(); ++j)
+ {
+ animOutRange->addFrame(mOutRangeImages->get(j), 75, 0, 0);
+ }
+
+ mTargetCursorInRange = new SimpleAnimation(animInRange);
+ mTargetCursorOutRange = new SimpleAnimation(animOutRange);
}
Viewport::~Viewport()
{
delete mPopupMenu;
+
+ delete mTargetCursorInRange;
+ delete mTargetCursorOutRange;
+
+ mInRangeImages->decRef();
+ mOutRangeImages->decRef();
}
void
@@ -158,10 +191,12 @@ Viewport::draw(gcn::Graphics *gcnGraphics)
if (mMap)
{
mMap->draw(graphics, mCameraX, mCameraY, 0);
+ drawTargetCursor(graphics);
mMap->draw(graphics, mCameraX, mCameraY, 1);
mMap->draw(graphics, mCameraX, mCameraY, 2);
mMap->drawOverlay(graphics, mViewX, mViewY,
(int) config.getValue("OverlayDetail", 2));
+ drawTargetName(graphics);
}
// Find a path from the player to the mouse, and draw it. This is for debug
@@ -201,28 +236,6 @@ Viewport::draw(gcn::Graphics *gcnGraphics)
(*i)->drawEmotion(graphics, -mCameraX, -mCameraY);
}
- // Draw target marker if needed
- Being *target = player_node->getTarget();
- if (target)
- {
- graphics->setFont(speechFont);
- graphics->setColor(gcn::Color(255, 32, 32));
- int dy = (target->getType() == Being::PLAYER) ? 80 : 42;
-
- std::string mobName = "";
-
- if (target->mJob >= 1002)
- {
- int mobId = target->mJob - 1002;
- mobName = MonsterDB::get(mobId).getName();
-
- graphics->drawText(mobName,
- target->getPixelX() - mCameraX + 15,
- target->getPixelY() - mCameraY - dy,
- gcn::Graphics::CENTER);
- }
- }
-
// Draw contained widgets
WindowContainer::draw(gcnGraphics);
}
@@ -245,6 +258,57 @@ Viewport::logic()
mouseY + mCameraY);
mWalkTime = player_node->mWalkTime;
}
+
+ mTargetCursorInRange->update(10);
+ mTargetCursorOutRange->update(10);
+}
+
+void
+Viewport::drawTargetCursor(Graphics *graphics)
+{
+ // Draw target marker if needed
+ Being *target = player_node->getTarget();
+ if (target)
+ {
+ // Find whether target is in range
+ int rangeX = abs(target->mX - player_node->mX);
+ int rangeY = abs(target->mY - player_node->mY);
+ int attackRange = player_node->getAttackRange();
+
+ // Draw the target cursor, which one depends if the target is in range
+ if (rangeX > attackRange || rangeY > attackRange)
+ {
+ // Draw the out of range cursor
+ graphics->drawImage(mTargetCursorOutRange->getCurrentImage(),
+ target->getPixelX() - mCameraX,
+ target->getPixelY() - mCameraY);
+ }
+ else
+ {
+ // Draw the in range cursor
+ graphics->drawImage(mTargetCursorInRange->getCurrentImage(),
+ target->getPixelX() - mCameraX,
+ target->getPixelY() - mCameraY);
+ }
+ }
+}
+
+void
+Viewport::drawTargetName(Graphics *graphics)
+{
+ // Draw target marker if needed
+ Being *target = player_node->getTarget();
+ if (target && target->getType() == Being::MONSTER)
+ {
+ graphics->setFont(speechFont);
+ graphics->setColor(gcn::Color(255, 32, 32));
+
+ const MonsterInfo &mi = static_cast<Monster*>(target)->getInfo();
+ graphics->drawText(mi.getName(),
+ target->getPixelX() - mCameraX + 15,
+ target->getPixelY() - mCameraY - 42,
+ gcn::Graphics::CENTER);
+ }
}
void
diff --git a/src/gui/viewport.h b/src/gui/viewport.h
index f1cadd98..84efeff3 100644
--- a/src/gui/viewport.h
+++ b/src/gui/viewport.h
@@ -33,8 +33,11 @@
class Map;
class Being;
class FloorItem;
+class ImageSet;
class Item;
class PopupMenu;
+class Graphics;
+class SimpleAnimation;
/**
* The viewport on the map. Displays the current map and handles mouse input
@@ -138,6 +141,18 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
*/
void showPopup(int x, int y, Being *being);
+ /**
+ * Draws range based target cursor
+ */
+ void
+ drawTargetCursor(Graphics *graphics);
+
+ /**
+ * Draws target name
+ */
+ void
+ drawTargetName(Graphics *graphics);
+
Map *mMap; /**< The current map. */
@@ -149,6 +164,15 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
int mCameraY; /**< Current viewpoint in tiles. */
bool mShowDebugPath; /**< Show a path from player to pointer. */
+ ImageSet *mInRangeImages; /**< Images of in range target cursor. */
+ ImageSet *mOutRangeImages; /**< Images of out of range target cursor.*/
+
+ /** Animated in range target cursor. */
+ SimpleAnimation *mTargetCursorInRange;
+
+ /** Animated out of range target cursor. */
+ SimpleAnimation *mTargetCursorOutRange;
+
bool mPlayerFollowMouse;
int mWalkTime;
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index 7f595ef1..97371677 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -38,6 +38,7 @@ LocalPlayer *player_node = NULL;
LocalPlayer::LocalPlayer():
Player(65535, 0, NULL),
+ mAttackRange(0),
mInventory(new Inventory()),
mAttributeBase(NB_BASE_ATTRIBUTES, 0),
mAttributeEffective(NB_BASE_ATTRIBUTES, 0),
diff --git a/src/localplayer.h b/src/localplayer.h
index 299cf85a..fb7703dd 100644
--- a/src/localplayer.h
+++ b/src/localplayer.h
@@ -153,6 +153,16 @@ class LocalPlayer : public Player
void pickUp(FloorItem *item);
/**
+ * Sets the attack range.
+ */
+ void setAttackRange(int range) { mAttackRange = range; }
+
+ /**
+ * Gets the attack range.
+ */
+ int getAttackRange() const { return mAttackRange; }
+
+ /**
* Sents a trade request to the given being.
*/
void trade(Being *being) const;
@@ -213,6 +223,8 @@ class LocalPlayer : public Player
int getMaxHP() const
{ return mMaxHP; }
+ Uint16 mAttackRange;
+
void setHP(int value)
{ mHP = value; }
diff --git a/src/logindata.h b/src/logindata.h
index 0a01331c..fbbbb573 100644
--- a/src/logindata.h
+++ b/src/logindata.h
@@ -36,8 +36,8 @@ struct LoginData
int session_ID1;
int session_ID2;
- bool remember;
- bool registerLogin;
+ bool remember; /**< Whether to store the username and host. */
+ bool registerLogin; /**< Whether an account is being registered. */
void clear()
{
diff --git a/src/main.cpp b/src/main.cpp
index aad6a68c..bbbf0fd1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -30,9 +30,13 @@
#include <vector>
#include <SDL_image.h>
-#include <guichan/actionlistener.hpp>
+#ifdef WIN32
+#include <SDL_syswm.h>
+#endif
+#include <guichan/actionlistener.hpp>
#include <guichan/sdl/sdlinput.hpp>
+#include <guichan/widgets/label.hpp>
#include <libxml/parser.h>
@@ -63,11 +67,11 @@
#include "gui/login.h"
#include "gui/quitdialog.h"
#include "gui/ok_dialog.h"
+#include "gui/progressbar.h"
#include "gui/register.h"
#include "gui/updatewindow.h"
#include "gui/textfield.h"
-
#include "net/charserverhandler.h"
#include "net/connection.h"
#include "net/loginhandler.h"
@@ -86,7 +90,6 @@
#include "resources/itemdb.h"
#include "resources/monsterdb.h"
#include "resources/resourcemanager.h"
-#include "resources/spriteset.h"
#include "utils/dtor.h"
#include "utils/tostring.h"
@@ -103,23 +106,13 @@ unsigned char screen_mode;
Sound sound;
Music *bgm;
-Configuration config; /**< Xml file configuration reader */
+Configuration config; /**< XML file configuration reader */
Logger *logger; /**< Log object */
Net::Connection *accountServerConnection = 0;
Net::Connection *gameServerConnection = 0;
Net::Connection *chatServerConnection = 0;
-namespace {
- struct ErrorListener : public gcn::ActionListener
- {
- void action(const gcn::ActionEvent &event)
- {
- state = STATE_CHOOSE_SERVER;
- }
- } errorListener;
-}
-
/**
* A structure holding the values of various options that can be passed from
* the command line.
@@ -131,12 +124,14 @@ struct Options
*/
Options():
printHelp(false),
+ printVersion(false),
skipUpdate(false),
chooseDefault(false),
serverPort(0)
{};
bool printHelp;
+ bool printVersion;
bool skipUpdate;
bool chooseDefault;
std::string playername;
@@ -237,7 +232,16 @@ void initEngine()
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
SDL_WM_SetCaption("The Mana World", NULL);
- SDL_WM_SetIcon(IMG_Load(TMW_DATADIR "data/icons/tmw-icon.png"), NULL);
+#ifdef WIN32
+ static SDL_SysWMinfo pInfo;
+ SDL_GetWMInfo(&pInfo);
+ HICON icon = LoadIcon(GetModuleHandle(NULL), "A");
+ SetClassLong(pInfo.window, GCL_HICON, (LONG) icon);
+#else
+ SDL_Surface *icon = IMG_Load(TMW_DATADIR "data/icons/tmw.png");
+ SDL_SetAlpha(icon, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
+ SDL_WM_SetIcon(icon, NULL);
+#endif
ResourceManager *resman = ResourceManager::getInstance();
@@ -356,6 +360,7 @@ void printHelp()
"tmw\n\n"
"Options:\n"
" -h --help : Display this help\n"
+ " -v --version : Display the version\n"
" -u --skipupdate : Skip the update process\n"
" -U --username : Login with this username\n"
" -P --password : Login with this password\n"
@@ -366,12 +371,23 @@ void printHelp()
" -C --configfile : Configuration file to use\n";
}
+void printVersion()
+{
+#ifdef PACKAGE_VERSION
+ std::cout << "The Mana World version " << PACKAGE_VERSION << std::endl;
+#else
+ std::cout << "The Mana World version " <<
+ "(local build?, PACKAGE_VERSION is not defined)" << std::endl;
+#endif
+}
+
void parseOptions(int argc, char *argv[], Options &options)
{
- const char *optstring = "huU:P:Dp:s:o:C:";
+ const char *optstring = "hvuU:P:Dp:s:o:C:";
const struct option long_options[] = {
{ "help", no_argument, 0, 'h' },
+ { "version", no_argument, 0, 'v' },
{ "skipupdate", no_argument, 0, 'u' },
{ "username", required_argument, 0, 'U' },
{ "password", required_argument, 0, 'P' },
@@ -395,6 +411,9 @@ void parseOptions(int argc, char *argv[], Options &options)
case 'h':
options.printHelp = true;
break;
+ case 'v':
+ options.printVersion = true;
+ break;
case 'u':
options.skipUpdate = true;
break;
@@ -449,6 +468,16 @@ LoginHandler loginHandler;
LogoutHandler logoutHandler;
LockedArray<LocalPlayer*> charInfo(MAX_SLOT + 1);
+namespace {
+ struct ErrorListener : public gcn::ActionListener
+ {
+ void action(const gcn::ActionEvent &event)
+ {
+ state = STATE_CHOOSE_SERVER;
+ }
+ } errorListener;
+}
+
// TODO Find some nice place for these functions
void accountLogin(LoginData *loginData)
{
@@ -466,15 +495,17 @@ void accountLogin(LoginData *loginData)
// Clear the password, avoids auto login when returning to login
loginData->password = "";
- //remove _M or _F from username after a login for registration purpose
+ // Remove _M or _F from username after a login for registration purpose
if (loginData->registerLogin)
{
- loginData->registerLogin = false;
- loginData->username = loginData->username.substr(0, loginData->username.length() - 2);
+ loginData->username =
+ loginData->username.substr(0, loginData->username.length() - 2);
}
+
// TODO This is not the best place to save the config, but at least better
// than the login gui window
- if (loginData->remember) {
+ if (loginData->remember)
+ {
config.setValue("host", loginData->hostname);
config.setValue("username", loginData->username);
}
@@ -557,7 +588,7 @@ void logoutThenExit()
logoutHandler.reset();
logoutHandler.setScenario(LOGOUT_EXIT);
- //Can't logout if we were not logged in ...
+ // Can't logout if we were not logged in ...
if (accountServerConnection->isConnected())
{
Net::AccountServer::logout();
@@ -616,10 +647,6 @@ void initXML()
/** Main */
int main(int argc, char *argv[])
{
-#ifdef PACKAGE_VERSION
- std::cout << "The Mana World v" << PACKAGE_VERSION << std::endl;
-#endif
-
// Parse command line options
Options options;
parseOptions(argc, argv, options);
@@ -628,6 +655,11 @@ int main(int argc, char *argv[])
printHelp();
return 0;
}
+ else if (options.printVersion)
+ {
+ printVersion();
+ return 0;
+ }
// Initialize PhysicsFS
PHYSFS_init(argv[0]);
@@ -647,10 +679,16 @@ int main(int argc, char *argv[])
initConfiguration(options);
initEngine();
+ Game *game = NULL;
Window *currentDialog = NULL;
QuitDialog* quitDialog = NULL;
Image *login_wallpaper = NULL;
- Game *game = NULL;
+
+ gcn::Container *top = static_cast<gcn::Container*>(gui->getTop());
+#ifdef PACKAGE_VERSION
+ gcn::Label *versionLabel = new gcn::Label(PACKAGE_VERSION);
+ top->add(versionLabel, 2, 2);
+#endif
sound.playMusic(TMW_DATADIR "data/music/Magick - Real.ogg");
@@ -715,8 +753,8 @@ int main(int argc, char *argv[])
guiInput->pushInput(event);
}
- gui->logic();
Net::flush();
+ gui->logic();
if (!login_wallpaper)
{
@@ -729,10 +767,6 @@ int main(int argc, char *argv[])
}
graphics->drawImage(login_wallpaper, 0, 0);
-#ifdef PACKAGE_VERSION
- graphics->setFont(gui->getFont());
- graphics->drawText(PACKAGE_VERSION, 0, 0);
-#endif
gui->draw();
graphics->updateScreen();
@@ -759,7 +793,6 @@ int main(int argc, char *argv[])
accountServerConnection->isConnected())
{
reconnectAccount(token);
-
state = STATE_WAIT;
}
@@ -936,6 +969,10 @@ int main(int argc, char *argv[])
Net::ChatServer::connect(chatServerConnection, token);
sound.fadeOutMusic(1000);
+#ifdef PACKAGE_VERSION
+ delete versionLabel;
+ versionLabel = NULL;
+#endif
currentDialog = NULL;
logger->log("State: GAME");
diff --git a/src/monster.h b/src/monster.h
index 18fa703e..39bbf3d7 100644
--- a/src/monster.h
+++ b/src/monster.h
@@ -43,7 +43,6 @@ class Monster : public Being
*/
virtual void handleAttack();
- protected:
/**
* Returns the MonsterInfo, with static data about this monster.
*/
diff --git a/src/net/charserverhandler.cpp b/src/net/charserverhandler.cpp
index 34fc188d..820aaea4 100644
--- a/src/net/charserverhandler.cpp
+++ b/src/net/charserverhandler.cpp
@@ -34,11 +34,13 @@
#include "../main.h"
#include "../gui/ok_dialog.h"
+#include "../gui/char_select.h"
extern Net::Connection *gameServerConnection;
extern Net::Connection *chatServerConnection;
-CharServerHandler::CharServerHandler()
+CharServerHandler::CharServerHandler():
+ mCharCreateDialog(0)
{
static const Uint16 _messages[] = {
APMSG_CHAR_CREATE_RESPONSE,
@@ -99,6 +101,13 @@ CharServerHandler::handleMessage(MessageIn &msg)
mCharInfo->unlock();
mCharInfo->select(slot);
mCharInfo->setEntry(tempPlayer);
+
+ // Close the character create dialog
+ if (mCharCreateDialog)
+ {
+ mCharCreateDialog->scheduleDelete();
+ mCharCreateDialog = 0;
+ }
break;
case APMSG_CHAR_SELECT_RESPONSE:
@@ -154,6 +163,9 @@ CharServerHandler::handleCharCreateResponse(MessageIn &msg)
}
new OkDialog("Error", message);
}
+
+ if (mCharCreateDialog)
+ mCharCreateDialog->unlock();
}
void
@@ -177,15 +189,20 @@ CharServerHandler::handleCharSelectResponse(MessageIn &msg)
// Keep the selected character and delete the others
player_node = mCharInfo->getEntry();
+ int slot = mCharInfo->getPos();
mCharInfo->unlock();
mCharInfo->select(0);
do {
LocalPlayer *tmp = mCharInfo->getEntry();
if (tmp != player_node)
+ {
delete tmp;
+ mCharInfo->setEntry(0);
+ }
mCharInfo->next();
} while (mCharInfo->getPos());
+ mCharInfo->select(slot);
mCharInfo->clear(); //player_node will be deleted by ~Game
@@ -204,8 +221,11 @@ CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
tempPlayer->setHairColor(msg.readByte());
tempPlayer->setLevel(msg.readByte());
tempPlayer->setMoney(msg.readLong());
- for (int i = 0; i < 7; i++) {
+
+ for (int i = 0; i < 7; i++)
+ {
tempPlayer->setAttributeBase(i, msg.readByte());
}
+
return tempPlayer;
}
diff --git a/src/net/charserverhandler.h b/src/net/charserverhandler.h
index 342641d7..4a4fe0c3 100644
--- a/src/net/charserverhandler.h
+++ b/src/net/charserverhandler.h
@@ -28,9 +28,13 @@
#include "../lockedarray.h"
+class CharCreateDialog;
class LocalPlayer;
class LoginData;
+/**
+ * Deals with incoming messages related to character selection.
+ */
class CharServerHandler : public MessageHandler
{
public:
@@ -45,6 +49,14 @@ class CharServerHandler : public MessageHandler
mCharInfo = charInfo;
}
+ /**
+ * 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)
+ { mCharCreateDialog = window; }
+
protected:
void
handleCharCreateResponse(MessageIn &msg);
@@ -53,6 +65,7 @@ class CharServerHandler : public MessageHandler
handleCharSelectResponse(MessageIn &msg);
LockedArray<LocalPlayer*> *mCharInfo;
+ CharCreateDialog *mCharCreateDialog;
LocalPlayer*
readPlayerData(MessageIn &msg, int &slot);
diff --git a/src/net/equipmenthandler.cpp b/src/net/equipmenthandler.cpp
index 1c0fd4ca..c0072a45 100644
--- a/src/net/equipmenthandler.cpp
+++ b/src/net/equipmenthandler.cpp
@@ -43,6 +43,7 @@ EquipmentHandler::EquipmentHandler()
0x01d7,
SMSG_PLAYER_UNEQUIP,
SMSG_PLAYER_ARROW_EQUIP,
+ SMSG_PLAYER_ATTACK_RANGE,
0
};
handledMessages = _messages;
@@ -191,6 +192,10 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
index, equipPoint, type, position);
break;
+ case SMSG_PLAYER_ATTACK_RANGE:
+ player_node->setAttackRange(msg.readShort());
+ break;
+
case SMSG_PLAYER_ARROW_EQUIP:
itemId = msg.readShort();
diff --git a/src/net/loginhandler.cpp b/src/net/loginhandler.cpp
index c68a620a..90f2dbd5 100644
--- a/src/net/loginhandler.cpp
+++ b/src/net/loginhandler.cpp
@@ -88,7 +88,7 @@ void LoginHandler::handleMessage(MessageIn &msg)
{
switch (errMsg) {
case REGISTER_INVALID_VERSION:
- errorMessage = "Client has an insufficient version number to login.";
+ errorMessage = "Client has an insufficient version number to login.";
break;
case ERRMSG_INVALID_ARGUMENT:
errorMessage = "Wrong username, password or email address";
diff --git a/src/net/protocol.h b/src/net/protocol.h
index a9ee0e5b..b5dc2996 100644
--- a/src/net/protocol.h
+++ b/src/net/protocol.h
@@ -44,6 +44,7 @@
#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
diff --git a/src/npc.cpp b/src/npc.cpp
index ccd085b6..2d291104 100644
--- a/src/npc.cpp
+++ b/src/npc.cpp
@@ -28,8 +28,6 @@
#include "gui/gui.h"
-class Spriteset;
-
NPC *current_npc = 0;
NPC::NPC(Uint16 id, Uint16 job, Map *map):
diff --git a/src/resources/animation.h b/src/resources/animation.h
index 54142bcb..d0d11c69 100644
--- a/src/resources/animation.h
+++ b/src/resources/animation.h
@@ -29,7 +29,6 @@
#include <libxml/tree.h>
class Image;
-class Spriteset;
/**
* A single frame in an animation, with a delay and an offset.
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index 58325213..a27783d4 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -80,7 +80,7 @@ Image* Image::load(void *buffer, unsigned int bufferSize,
tmpImage = IMG_Load_RW(rw, 1);
}
- if (tmpImage == NULL) {
+ if (!tmpImage) {
logger->log("Error, image load failed: %s", IMG_GetError());
return NULL;
}
@@ -99,87 +99,28 @@ Image* Image::load(void *buffer, unsigned int bufferSize,
amask = 0xff000000;
#endif
- // Convert the image to a 32 bit software surface for processing
- SDL_Surface *formatImage = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, 32,
- rmask, gmask, bmask, amask);
-
- if (formatImage == NULL) {
- logger->log("Error, image load failed: not enough memory");
- SDL_FreeSurface(tmpImage);
- return NULL;
- }
-
- SDL_Surface *image = SDL_ConvertSurface(
- tmpImage, formatImage->format, SDL_SWSURFACE);
-
- SDL_FreeSurface(formatImage);
-
- if (image == NULL) {
- logger->log("Error, image load failed: not enough memory");
- return NULL;
- }
-
- bool hasPink = false;
- bool hasAlpha = false;
- int i;
- Uint32 pink = SDL_MapRGB(image->format, 255, 0, 255);
-
- // Figure out whether the image has pink pixels
- for (i = 0; i < image->w * image->h; ++i)
- {
- if (((Uint32*)image->pixels)[i] == pink)
- {
- hasPink = true;
- break;
- }
- }
-
- // Figure out whether the image uses its alpha layer
- for (i = 0; i < image->w * image->h; ++i)
- {
- Uint8 r, g, b, a;
- SDL_GetRGBA(
- ((Uint32*)image->pixels)[i],
- image->format,
- &r, &g, &b, &a);
-
- if (a != 255)
- {
- hasAlpha = true;
- break;
- }
- }
-
- SDL_FreeSurface(image);
-
- if (hasPink && !hasAlpha) {
- SDL_SetColorKey(tmpImage, SDL_SRCCOLORKEY,
- SDL_MapRGB(tmpImage->format, 255, 0, 255));
- } else if (hasAlpha) {
- SDL_SetAlpha(tmpImage, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
- }
-
#ifdef USE_OPENGL
if (mUseOpenGL)
{
int width = tmpImage->w;
int height = tmpImage->h;
- int realWidth = 1, realHeight = 1;
+ int realWidth = powerOfTwo(width);
+ int realHeight = powerOfTwo(height);
- while (realWidth < width && realWidth < 1024) {
- realWidth *= 2;
- }
-
- while (realHeight < height && realHeight < 1024) {
- realHeight *= 2;
+ 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);
+
SDL_Surface *oldImage = tmpImage;
- tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight, 32,
- rmask, gmask, bmask, amask);
+ tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight,
+ 32, rmask, gmask, bmask, amask);
- if (tmpImage == NULL) {
+ if (!tmpImage) {
logger->log("Error, image convert failed: out of memory");
return NULL;
}
@@ -189,8 +130,6 @@ Image* Image::load(void *buffer, unsigned int bufferSize,
GLuint texture;
glGenTextures(1, &texture);
- logger->log("Binding texture %d (%dx%d)",
- texture, tmpImage->w, tmpImage->h);
glBindTexture(GL_TEXTURE_2D, texture);
if (SDL_MUSTLOCK(tmpImage)) {
@@ -246,8 +185,27 @@ Image* Image::load(void *buffer, unsigned int bufferSize,
}
#endif
- // Set color key and alpha blending optins, and convert the surface to the
- // current display format
+ bool hasAlpha = false;
+
+ // 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;
+ break;
+ }
+ }
+
+ SDL_Surface *image;
+
+ // Convert the surface to the current display format
if (hasAlpha) {
image = SDL_DisplayFormatAlpha(tmpImage);
}
@@ -256,7 +214,7 @@ Image* Image::load(void *buffer, unsigned int bufferSize,
}
SDL_FreeSurface(tmpImage);
- if (image == NULL) {
+ if (!image) {
logger->log("Error: Image convert failed.");
return NULL;
}
@@ -315,10 +273,22 @@ float Image::getAlpha()
}
#ifdef USE_OPENGL
-void Image::setLoadAsOpenGL(bool useOpenGL)
+void
+Image::setLoadAsOpenGL(bool useOpenGL)
{
Image::mUseOpenGL = useOpenGL;
}
+
+int
+Image::powerOfTwo(int input)
+{
+ int value = 1;
+ while (value < input && value < 1024)
+ {
+ value <<= 1;
+ }
+ return value;
+}
#endif
//============================================================================
diff --git a/src/resources/image.h b/src/resources/image.h
index 03bf0cbc..cad21dcd 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -126,6 +126,12 @@ class Image : public Resource
#ifdef USE_OPENGL
Image(const std::string &idPath, 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);
#endif
Image(const std::string &idPath, SDL_Surface *image);
diff --git a/src/resources/spriteset.cpp b/src/resources/imageset.cpp
index 96bcef0c..677c024b 100644
--- a/src/resources/spriteset.cpp
+++ b/src/resources/imageset.cpp
@@ -21,7 +21,7 @@
* $Id$
*/
-#include "spriteset.h"
+#include "imageset.h"
#include "../log.h"
@@ -29,7 +29,7 @@
#include "../utils/dtor.h"
-Spriteset::Spriteset(const std::string& idPath,
+ImageSet::ImageSet(const std::string& idPath,
Image *img,
int width, int height):
Resource(idPath)
@@ -38,28 +38,28 @@ Spriteset::Spriteset(const std::string& idPath,
{
for (int x = 0; x + width <= img->getWidth(); x += width)
{
- mSpriteset.push_back(img->getSubImage(x, y, width, height));
+ mImages.push_back(img->getSubImage(x, y, width, height));
}
}
mWidth = width;
mHeight = height;
}
-Spriteset::~Spriteset()
+ImageSet::~ImageSet()
{
- for_each(mSpriteset.begin(), mSpriteset.end(), make_dtor(mSpriteset));
+ for_each(mImages.begin(), mImages.end(), make_dtor(mImages));
}
Image*
-Spriteset::get(size_type i)
+ImageSet::get(size_type i)
{
- if (i >= mSpriteset.size())
+ if (i >= mImages.size())
{
- logger->log("Warning: Sprite #%i does not exist in this spriteset", i);
+ logger->log("Warning: Sprite #%i does not exist in this image set", i);
return NULL;
}
else
{
- return mSpriteset[i];
+ return mImages[i];
}
}
diff --git a/src/resources/spriteset.h b/src/resources/imageset.h
index 7f6b42df..3469a3bb 100644
--- a/src/resources/spriteset.h
+++ b/src/resources/imageset.h
@@ -21,8 +21,8 @@
* $Id$
*/
-#ifndef _TMW_SPRITESET_H
-#define _TMW_SPRITESET_H
+#ifndef _TMW_IMAGESET_H
+#define _TMW_IMAGESET_H
#include <vector>
@@ -33,21 +33,19 @@ class Image;
/**
* Stores a set of subimages originating from a single image.
- *
- * TODO: Should probably be renamed to ImageSet or TileSet.
*/
-class Spriteset : public Resource
+class ImageSet : public Resource
{
public:
/*
* Cuts the passed image in a grid of sub images.
*/
- Spriteset(const std::string &idPath, Image *img, int w, int h);
+ ImageSet(const std::string &idPath, Image *img, int w, int h);
/**
* Destructor.
*/
- ~Spriteset();
+ ~ImageSet();
int getWidth() { return mWidth; };
@@ -56,14 +54,13 @@ class Spriteset : public Resource
typedef std::vector<Image*>::size_type size_type;
Image* get(size_type i);
- size_type size() { return mSpriteset.size(); }
+ size_type size() { return mImages.size(); }
private:
- // Vector storing the whole spriteset.
- std::vector<Image*> mSpriteset;
- // Height and width of the images in the spriteset
- int mHeight;
- int mWidth;
+ 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/monsterdb.h b/src/resources/monsterdb.h
index 048638c2..46a33b06 100644
--- a/src/resources/monsterdb.h
+++ b/src/resources/monsterdb.h
@@ -39,7 +39,7 @@ namespace MonsterDB
void
unload();
- const MonsterInfo& get (int id);
+ const MonsterInfo& get(int id);
typedef std::map<int, MonsterInfo*> MonsterInfos;
typedef MonsterInfos::iterator MonsterInfoIterator;
diff --git a/src/resources/monsterinfo.h b/src/resources/monsterinfo.h
index 413dafa0..05d4c014 100644
--- a/src/resources/monsterinfo.h
+++ b/src/resources/monsterinfo.h
@@ -1,74 +1,83 @@
-/*
- * The Mana World
- * Copyright 2004 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * The Mana World is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * The Mana World is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with The Mana World; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id: monsterinfo.h 2650 2006-09-03 15:00:47Z b_lindeijer $
- */
-
-#ifndef _TMW_MONSTERINFO_H_
-#define _TMW_MONSTERINFO_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-
-enum SoundEvent
-{
- EVENT_HIT,
- EVENT_MISS,
- EVENT_HURT,
- EVENT_DIE
-};
-
-
-class MonsterInfo
-{
- public:
- MonsterInfo();
-
- ~MonsterInfo();
-
- void
- setName(std::string name) { mName = name; } ;
-
- void
- setSprite(std::string filename) { mSprite = filename; }
-
- void
- addSound (SoundEvent event, std::string filename);
-
- const std::string&
- getName () const { return mName; };
-
- const std::string&
- getSprite () const { return mSprite; };
-
- std::string
- getSound (SoundEvent event) const;
-
- private:
-
- std::string mName;
- std::string mSprite;
-
- std::map<SoundEvent, std::vector<std::string>* > mSounds;
-};
-
-#endif
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id: monsterinfo.h 2650 2006-09-03 15:00:47Z b_lindeijer $
+ */
+
+#ifndef _TMW_MONSTERINFO_H_
+#define _TMW_MONSTERINFO_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+enum SoundEvent
+{
+ EVENT_HIT,
+ EVENT_MISS,
+ EVENT_HURT,
+ EVENT_DIE
+};
+
+/**
+ * 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
+ */
+class MonsterInfo
+{
+ public:
+ /**
+ * Constructor.
+ */
+ MonsterInfo();
+
+ /**
+ * Destructor.
+ */
+ ~MonsterInfo();
+
+ void
+ setName(std::string name) { mName = name; } ;
+
+ void
+ setSprite(std::string filename) { mSprite = filename; }
+
+ void
+ addSound (SoundEvent event, std::string filename);
+
+ const std::string&
+ getName () const { return mName; };
+
+ const std::string&
+ getSprite () const { return mSprite; };
+
+ std::string
+ getSound (SoundEvent event) const;
+
+ private:
+ std::string mName;
+ std::string mSprite;
+
+ std::map<SoundEvent, std::vector<std::string>* > mSounds;
+};
+
+#endif
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index 2059a5c3..448e7f80 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -31,7 +31,7 @@
#include "image.h"
#include "music.h"
#include "soundeffect.h"
-#include "spriteset.h"
+#include "imageset.h"
#include "spritedef.h"
#include "../log.h"
@@ -46,7 +46,7 @@ ResourceManager::ResourceManager()
ResourceManager::~ResourceManager()
{
- // Release any remaining spritedefs first because they depend on spritesets
+ // Release any remaining spritedefs first because they depend on image sets
ResourceIterator iter = mResources.begin();
while (iter != mResources.end())
{
@@ -63,11 +63,11 @@ ResourceManager::~ResourceManager()
}
}
- // Release any remaining spritesets first because they depend on images
+ // Release any remaining image sets first because they depend on images
iter = mResources.begin();
while (iter != mResources.end())
{
- if (dynamic_cast<Spriteset*>(iter->second) != 0)
+ if (dynamic_cast<ImageSet*>(iter->second) != 0)
{
cleanUp(iter->second);
ResourceIterator toErase = iter;
@@ -232,8 +232,8 @@ ResourceManager::getSoundEffect(const std::string &idPath)
return dynamic_cast<SoundEffect*>(get(SOUND_EFFECT, idPath));
}
-Spriteset*
-ResourceManager::getSpriteset(const std::string &imagePath, int w, int h)
+ImageSet*
+ResourceManager::getImageSet(const std::string &imagePath, int w, int h)
{
std::stringstream ss;
ss << imagePath << "[" << w << "x" << h << "]";
@@ -243,7 +243,7 @@ ResourceManager::getSpriteset(const std::string &imagePath, int w, int h)
if (resIter != mResources.end()) {
resIter->second->incRef();
- return dynamic_cast<Spriteset*>(resIter->second);
+ return dynamic_cast<ImageSet*>(resIter->second);
}
Image *img = getImage(imagePath);
@@ -252,13 +252,13 @@ ResourceManager::getSpriteset(const std::string &imagePath, int w, int h)
return NULL;
}
- Spriteset *spriteset = new Spriteset(idPath, img, w, h);
- spriteset->incRef();
- mResources[idPath] = spriteset;
+ ImageSet *imageSet = new ImageSet(idPath, img, w, h);
+ imageSet->incRef();
+ mResources[idPath] = imageSet;
img->decRef();
- return spriteset;
+ return imageSet;
}
SpriteDef*
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
index e176e337..db29e6d3 100644
--- a/src/resources/resourcemanager.h
+++ b/src/resources/resourcemanager.h
@@ -33,7 +33,7 @@ class Resource;
class Image;
class Music;
class SoundEffect;
-class Spriteset;
+class ImageSet;
class SpriteDef;
/**
@@ -143,11 +143,11 @@ class ResourceManager
getSoundEffect(const std::string &idPath);
/**
- * Creates a spriteset based on the image referenced by the given
+ * Creates a image set based on the image referenced by the given
* path and the supplied sprite sizes
*/
- Spriteset*
- getSpriteset(const std::string &imagePath, int w, int h);
+ ImageSet*
+ getImageSet(const std::string &imagePath, int w, int h);
/**
* Creates a sprite definition based on a given path and the supplied
diff --git a/src/resources/spritedef.cpp b/src/resources/spritedef.cpp
index feb6f8f8..d29bd847 100644
--- a/src/resources/spritedef.cpp
+++ b/src/resources/spritedef.cpp
@@ -28,7 +28,7 @@
#include "animation.h"
#include "action.h"
#include "resourcemanager.h"
-#include "spriteset.h"
+#include "imageset.h"
#include "image.h"
#include "../utils/xml.h"
@@ -135,30 +135,30 @@ SpriteDef::loadImageSet(xmlNodePtr node)
std::string imageSrc = XML::getProperty(node, "src", "");
ResourceManager *resman = ResourceManager::getInstance();
- Spriteset *spriteset = resman->getSpriteset(imageSrc, width, height);
+ ImageSet *imageSet = resman->getImageSet(imageSrc, width, height);
- if (!spriteset)
+ if (!imageSet)
{
logger->error("Couldn't load imageset!");
}
- mSpritesets[name] = spriteset;
+ 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", "");
+ const std::string imageSetName = XML::getProperty(node, "imageset", "");
- SpritesetIterator si = mSpritesets.find(imagesetName);
- if (si == mSpritesets.end())
+ ImageSetIterator si = mImageSets.find(imageSetName);
+ if (si == mImageSets.end())
{
logger->log("Warning: imageset \"%s\" not defined in %s",
- imagesetName.c_str(), getIdPath().c_str());
+ imageSetName.c_str(), getIdPath().c_str());
return;
}
- Spriteset *imageset = si->second;
+ ImageSet *imageSet = si->second;
SpriteAction actionType = makeSpriteAction(actionName);
if (actionType == ACTION_INVALID)
@@ -183,14 +183,14 @@ SpriteDef::loadAction(xmlNodePtr node, int variant_offset)
{
if (xmlStrEqual(animationNode->name, BAD_CAST "animation"))
{
- loadAnimation(animationNode, action, imageset, variant_offset);
+ loadAnimation(animationNode, action, imageSet, variant_offset);
}
}
}
void
SpriteDef::loadAnimation(xmlNodePtr animationNode,
- Action *action, Spriteset *imageset,
+ Action *action, ImageSet *imageSet,
int variant_offset)
{
std::string directionName =
@@ -215,8 +215,8 @@ SpriteDef::loadAnimation(xmlNodePtr animationNode,
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;
+ offsetY -= imageSet->getHeight() - 32;
+ offsetX -= imageSet->getWidth() / 2 - 16;
if (xmlStrEqual(frameNode->name, BAD_CAST "frame"))
{
@@ -228,7 +228,7 @@ SpriteDef::loadAnimation(xmlNodePtr animationNode,
continue;
}
- Image *img = imageset->get(index + variant_offset);
+ Image *img = imageSet->get(index + variant_offset);
if (!img)
{
@@ -251,7 +251,7 @@ SpriteDef::loadAnimation(xmlNodePtr animationNode,
while (end >= start)
{
- Image *img = imageset->get(start + variant_offset);
+ Image *img = imageSet->get(start + variant_offset);
if (!img)
{
@@ -296,8 +296,8 @@ SpriteDef::substituteAction(SpriteAction complete, SpriteAction with)
SpriteDef::~SpriteDef()
{
- for (SpritesetIterator i = mSpritesets.begin();
- i != mSpritesets.end(); ++i)
+ for (ImageSetIterator i = mImageSets.begin();
+ i != mImageSets.end(); ++i)
{
i->second->decRef();
}
diff --git a/src/resources/spritedef.h b/src/resources/spritedef.h
index 057129ad..6d335b02 100644
--- a/src/resources/spritedef.h
+++ b/src/resources/spritedef.h
@@ -32,7 +32,7 @@
#include <libxml/tree.h>
class Action;
-class Spriteset;
+class ImageSet;
enum SpriteAction
{
@@ -111,7 +111,7 @@ class SpriteDef : public Resource
*/
void
loadAnimation(xmlNodePtr animationNode,
- Action *action, Spriteset *imageset,
+ Action *action, ImageSet *imageSet,
int variant_offset);
/**
@@ -140,12 +140,12 @@ class SpriteDef : public Resource
makeSpriteDirection(const std::string &direction);
- typedef std::map<std::string, Spriteset*> Spritesets;
- typedef Spritesets::iterator SpritesetIterator;
+ typedef std::map<std::string, ImageSet*> ImageSets;
+ typedef ImageSets::iterator ImageSetIterator;
typedef std::map<SpriteAction, Action*> Actions;
- Spritesets mSpritesets;
+ ImageSets mImageSets;
Actions mActions;
Action *mAction;
SpriteDirection mDirection;
diff --git a/src/simpleanimation.cpp b/src/simpleanimation.cpp
new file mode 100644
index 00000000..5fc35bcd
--- /dev/null
+++ b/src/simpleanimation.cpp
@@ -0,0 +1,50 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#include "simpleanimation.h"
+
+
+void SimpleAnimation::update(unsigned int timePassed)
+{
+ mAnimationTime += timePassed;
+ while (mAnimationTime > mCurrentFrame->delay)
+ {
+ mAnimationTime -= mCurrentFrame->delay;
+ mAnimationPhase++;
+ if (mAnimationPhase >= mAnimation->getLength())
+ {
+ mAnimationPhase = 0;
+ }
+ mCurrentFrame = mAnimation->getFrame(mAnimationPhase);
+ }
+}
+
+Image *SimpleAnimation::getCurrentImage() const
+{
+ return mCurrentFrame->image;
+}
+
+SimpleAnimation::~SimpleAnimation()
+{
+ delete mAnimation;
+}
diff --git a/src/simpleanimation.h b/src/simpleanimation.h
new file mode 100644
index 00000000..a56c31da
--- /dev/null
+++ b/src/simpleanimation.h
@@ -0,0 +1,65 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#ifndef _TMW_SIMPLEANIMAION_H
+#define _TMW_SIMPLEANIMAION_H
+
+#include "resources/animation.h"
+
+class Frame;
+
+/**
+ * This class is a leightweight alternative to the AnimatedSprite class.
+ * It hosts a looping animation without actions and directions.
+ */
+class SimpleAnimation
+{
+ public:
+ SimpleAnimation(Animation *animation):
+ mAnimation(animation),
+ mAnimationTime(0),
+ mAnimationPhase(0),
+ mCurrentFrame(mAnimation->getFrame(0))
+ {};
+
+ ~SimpleAnimation();
+
+ void update(unsigned int timePassed);
+
+ Image *getCurrentImage() const;
+
+ private:
+ /** The hosted animation. */
+ Animation *mAnimation;
+
+ /** Time in game ticks the current frame is shown. */
+ unsigned int mAnimationTime;
+
+ /** Index of current animation frame. */
+ unsigned int mAnimationPhase;
+
+ /** Current animation frame. */
+ Frame *mCurrentFrame;
+};
+
+#endif
diff --git a/src/tileset.h b/src/tileset.h
index 27bc28c3..7521a3e5 100644
--- a/src/tileset.h
+++ b/src/tileset.h
@@ -24,19 +24,19 @@
#ifndef _TMW_TILESET_H_
#define _TMW_TILESET_H_
-#include "resources/spriteset.h"
+#include "resources/imageset.h"
/**
- * A tileset, which is basically just a spriteset but it stores a firstgid.
+ * A tileset, which is basically just an image set but it stores a firstgid.
*/
-class Tileset : public Spriteset
+class Tileset : public ImageSet
{
public:
/**
* Constructor.
*/
Tileset(Image *img, int w, int h, int firstGid):
- Spriteset("", img, w, h),
+ ImageSet("", img, w, h),
mFirstGid(firstGid)
{
}
diff --git a/src/tmw.rc b/src/tmw.rc
index ee5f99cd..673b2387 100644
--- a/src/tmw.rc
+++ b/src/tmw.rc
@@ -2,7 +2,7 @@
#include "winver.h"
-A ICON MOVEABLE PURE LOADONCALL DISCARDABLE "data/icons/tmw-icon.ico"
+A ICON MOVEABLE PURE LOADONCALL DISCARDABLE "data/icons/tmw.ico"
1 VERSIONINFO
FILEVERSION VER_MAJOR,VER_MINOR,VER_RELEASE,VER_BUILD
diff --git a/tmw.cbp b/tmw.cbp
index 96ef5a36..c66a5719 100644
--- a/tmw.cbp
+++ b/tmw.cbp
@@ -1262,6 +1262,16 @@
<Option link="0"/>
<Option target="default"/>
</Unit>
+ <Unit filename="src\resources\imageset.cpp">
+ <Option compilerVar="CPP"/>
+ <Option target="default"/>
+ </Unit>
+ <Unit filename="src\resources\imageset.h">
+ <Option compilerVar=""/>
+ <Option compile="0"/>
+ <Option link="0"/>
+ <Option target="default"/>
+ </Unit>
<Unit filename="src\resources\imagewriter.cpp">
<Option compilerVar="CPP"/>
<Option target="default"/>
@@ -1392,17 +1402,17 @@
<Option link="0"/>
<Option target="default"/>
</Unit>
- <Unit filename="src\resources\spriteset.cpp">
- <Option compilerVar="CPP"/>
+ <Unit filename="src\serverinfo.h">
+ <Option compilerVar=""/>
+ <Option compile="0"/>
+ <Option link="0"/>
<Option target="default"/>
</Unit>
- <Unit filename="src\resources\spriteset.h">
+ <Unit filename="src\simpleanimation.cpp">
<Option compilerVar="CPP"/>
- <Option compile="0"/>
- <Option link="0"/>
<Option target="default"/>
</Unit>
- <Unit filename="src\serverinfo.h">
+ <Unit filename="src\simpleanimation.h">
<Option compilerVar=""/>
<Option compile="0"/>
<Option link="0"/>