summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt104
-rw-r--r--src/Makefile.am234
-rw-r--r--[-rwxr-xr-x]src/SDLMain.h0
-rw-r--r--[-rwxr-xr-x]src/SDLMain.m0
-rw-r--r--src/animatedsprite.cpp9
-rw-r--r--src/animatedsprite.h8
-rw-r--r--src/animationparticle.cpp5
-rw-r--r--src/animationparticle.h5
-rw-r--r--src/being.cpp577
-rw-r--r--src/being.h242
-rw-r--r--src/beingmanager.cpp87
-rw-r--r--src/beingmanager.h37
-rw-r--r--src/channel.cpp45
-rw-r--r--src/channel.h87
-rw-r--r--src/channelmanager.cpp85
-rw-r--r--src/channelmanager.h48
-rw-r--r--src/commandhandler.cpp593
-rw-r--r--src/commandhandler.h154
-rw-r--r--src/configlistener.h5
-rw-r--r--src/configuration.cpp14
-rw-r--r--src/configuration.h19
-rw-r--r--src/effectmanager.cpp6
-rw-r--r--src/effectmanager.h3
-rw-r--r--src/emoteshortcut.cpp3
-rw-r--r--src/emoteshortcut.h3
-rw-r--r--src/engine.cpp31
-rw-r--r--src/engine.h13
-rw-r--r--src/equipment.cpp49
-rw-r--r--src/equipment.h41
-rw-r--r--src/floor_item.cpp11
-rw-r--r--src/floor_item.h11
-rw-r--r--src/flooritemmanager.cpp8
-rw-r--r--src/flooritemmanager.h3
-rw-r--r--src/game.cpp498
-rw-r--r--src/game.h31
-rw-r--r--src/graphics.cpp7
-rw-r--r--src/graphics.h7
-rw-r--r--src/gui/browserbox.cpp6
-rw-r--r--src/gui/browserbox.h6
-rw-r--r--src/gui/buddywindow.cpp68
-rw-r--r--src/gui/buddywindow.h60
-rw-r--r--src/gui/button.cpp7
-rw-r--r--src/gui/button.h5
-rw-r--r--src/gui/buy.cpp76
-rw-r--r--src/gui/buy.h30
-rw-r--r--src/gui/buysell.cpp21
-rw-r--r--src/gui/buysell.h8
-rw-r--r--src/gui/changeemaildialog.cpp167
-rw-r--r--src/gui/changeemaildialog.h72
-rw-r--r--src/gui/changepassworddialog.cpp193
-rw-r--r--src/gui/changepassworddialog.h72
-rw-r--r--src/gui/char_select.cpp384
-rw-r--r--src/gui/char_select.h67
-rw-r--r--src/gui/char_server.cpp11
-rw-r--r--src/gui/char_server.h5
-rw-r--r--src/gui/chat.cpp848
-rw-r--r--src/gui/chat.h229
-rw-r--r--src/gui/chatinput.cpp5
-rw-r--r--src/gui/chatinput.h7
-rw-r--r--src/gui/checkbox.cpp7
-rw-r--r--src/gui/checkbox.h7
-rw-r--r--src/gui/confirm_dialog.cpp13
-rw-r--r--src/gui/confirm_dialog.h6
-rw-r--r--src/gui/connection.cpp30
-rw-r--r--src/gui/connection.h18
-rw-r--r--src/gui/debugwindow.cpp5
-rw-r--r--src/gui/debugwindow.h5
-rw-r--r--src/gui/emotecontainer.cpp3
-rw-r--r--src/gui/emotecontainer.h3
-rw-r--r--src/gui/emoteshortcutcontainer.cpp3
-rw-r--r--src/gui/emoteshortcutcontainer.h3
-rw-r--r--src/gui/emotewindow.cpp6
-rw-r--r--src/gui/emotewindow.h2
-rw-r--r--src/gui/equipmentwindow.cpp66
-rw-r--r--src/gui/equipmentwindow.h46
-rw-r--r--src/gui/focushandler.cpp5
-rw-r--r--src/gui/focushandler.h5
-rw-r--r--src/gui/gccontainer.cpp5
-rw-r--r--src/gui/gccontainer.h5
-rw-r--r--src/gui/gui.cpp15
-rw-r--r--src/gui/gui.h5
-rw-r--r--src/gui/guildlistbox.cpp130
-rw-r--r--src/gui/guildlistbox.h65
-rw-r--r--src/gui/guildwindow.cpp273
-rw-r--r--src/gui/guildwindow.h135
-rw-r--r--src/gui/help.cpp11
-rw-r--r--src/gui/help.h7
-rw-r--r--src/gui/icon.cpp58
-rw-r--r--src/gui/icon.h66
-rw-r--r--src/gui/inttextfield.cpp32
-rw-r--r--src/gui/inttextfield.h11
-rw-r--r--src/gui/inventorywindow.cpp145
-rw-r--r--src/gui/inventorywindow.h52
-rw-r--r--src/gui/item_amount.cpp24
-rw-r--r--src/gui/item_amount.h10
-rw-r--r--src/gui/itemcontainer.cpp465
-rw-r--r--src/gui/itemcontainer.h94
-rw-r--r--src/gui/itemlinkhandler.cpp13
-rw-r--r--src/gui/itemlinkhandler.h17
-rw-r--r--src/gui/itempopup.cpp31
-rw-r--r--src/gui/itempopup.h7
-rw-r--r--src/gui/itemshortcutcontainer.cpp46
-rw-r--r--src/gui/itemshortcutcontainer.h5
-rw-r--r--src/gui/itemshortcutwindow.cpp71
-rw-r--r--src/gui/itemshortcutwindow.h61
-rw-r--r--src/gui/label.cpp10
-rw-r--r--src/gui/label.h9
-rw-r--r--src/gui/linkhandler.h9
-rw-r--r--src/gui/listbox.cpp5
-rw-r--r--src/gui/listbox.h5
-rw-r--r--src/gui/login.cpp60
-rw-r--r--src/gui/login.h19
-rw-r--r--src/gui/magic.cpp92
-rw-r--r--src/gui/magic.h75
-rw-r--r--src/gui/menuwindow.cpp61
-rw-r--r--src/gui/menuwindow.h5
-rw-r--r--src/gui/minimap.cpp18
-rw-r--r--src/gui/minimap.h5
-rw-r--r--src/gui/ministatus.cpp77
-rw-r--r--src/gui/ministatus.h22
-rw-r--r--src/gui/npc_text.cpp79
-rw-r--r--src/gui/npc_text.h24
-rw-r--r--src/gui/npcintegerdialog.cpp62
-rw-r--r--src/gui/npcintegerdialog.h27
-rw-r--r--src/gui/npclistdialog.cpp63
-rw-r--r--src/gui/npclistdialog.h27
-rw-r--r--src/gui/npcpostdialog.cpp101
-rw-r--r--src/gui/npcpostdialog.h57
-rw-r--r--src/gui/npcstringdialog.cpp60
-rw-r--r--src/gui/npcstringdialog.h22
-rw-r--r--src/gui/ok_dialog.cpp11
-rw-r--r--src/gui/ok_dialog.h14
-rw-r--r--src/gui/palette.cpp6
-rw-r--r--src/gui/palette.h38
-rw-r--r--src/gui/partywindow.cpp145
-rw-r--r--src/gui/partywindow.h96
-rw-r--r--src/gui/passwordfield.cpp7
-rw-r--r--src/gui/passwordfield.h9
-rw-r--r--src/gui/playerbox.cpp18
-rw-r--r--src/gui/playerbox.h5
-rw-r--r--src/gui/popup.cpp8
-rw-r--r--src/gui/popup.h50
-rw-r--r--src/gui/popupmenu.cpp155
-rw-r--r--src/gui/popupmenu.h7
-rw-r--r--src/gui/progressbar.cpp46
-rw-r--r--src/gui/progressbar.h26
-rw-r--r--src/gui/quitdialog.cpp135
-rw-r--r--src/gui/quitdialog.h70
-rw-r--r--src/gui/radiobutton.cpp7
-rw-r--r--src/gui/radiobutton.h7
-rw-r--r--src/gui/recorder.cpp22
-rw-r--r--src/gui/recorder.h16
-rw-r--r--src/gui/register.cpp68
-rw-r--r--src/gui/register.h28
-rw-r--r--src/gui/scrollarea.cpp21
-rw-r--r--src/gui/scrollarea.h14
-rw-r--r--src/gui/sell.cpp86
-rw-r--r--src/gui/sell.h22
-rw-r--r--src/gui/serverdialog.cpp214
-rw-r--r--src/gui/serverdialog.h123
-rw-r--r--src/gui/setup.cpp19
-rw-r--r--src/gui/setup.h7
-rw-r--r--src/gui/setup_audio.cpp6
-rw-r--r--src/gui/setup_audio.h5
-rw-r--r--src/gui/setup_colors.cpp10
-rw-r--r--src/gui/setup_colors.h2
-rw-r--r--src/gui/setup_joystick.cpp5
-rw-r--r--src/gui/setup_joystick.h5
-rw-r--r--src/gui/setup_keyboard.cpp10
-rw-r--r--src/gui/setup_keyboard.h7
-rw-r--r--src/gui/setup_players.cpp39
-rw-r--r--src/gui/setup_players.h5
-rw-r--r--src/gui/setup_video.cpp34
-rw-r--r--src/gui/setup_video.h17
-rw-r--r--src/gui/setuptab.h5
-rw-r--r--src/gui/shop.cpp29
-rw-r--r--src/gui/shop.h48
-rw-r--r--src/gui/shoplistbox.cpp20
-rw-r--r--src/gui/shoplistbox.h7
-rw-r--r--src/gui/shortcutcontainer.cpp7
-rw-r--r--src/gui/shortcutcontainer.h11
-rw-r--r--src/gui/shortcutwindow.cpp7
-rw-r--r--src/gui/shortcutwindow.h7
-rw-r--r--src/gui/skill.cpp27
-rw-r--r--src/gui/skill.h7
-rw-r--r--src/gui/skilldialog.cpp318
-rw-r--r--src/gui/skilldialog.h79
-rw-r--r--src/gui/skin.cpp10
-rw-r--r--src/gui/slider.cpp5
-rw-r--r--src/gui/slider.h5
-rw-r--r--src/gui/speechbubble.cpp15
-rw-r--r--src/gui/speechbubble.h8
-rw-r--r--src/gui/status.cpp136
-rw-r--r--src/gui/status.h11
-rw-r--r--src/gui/statuswindow.cpp376
-rw-r--r--src/gui/statuswindow.h107
-rw-r--r--src/gui/storagewindow.cpp8
-rw-r--r--src/gui/storagewindow.h3
-rw-r--r--src/gui/table.cpp51
-rw-r--r--src/gui/table.h42
-rw-r--r--src/gui/table_model.cpp21
-rw-r--r--src/gui/table_model.h40
-rw-r--r--src/gui/textbox.cpp5
-rw-r--r--src/gui/textbox.h5
-rw-r--r--src/gui/textdialog.cpp91
-rw-r--r--src/gui/textdialog.h66
-rw-r--r--src/gui/textfield.cpp7
-rw-r--r--src/gui/textfield.h10
-rw-r--r--src/gui/textrenderer.h17
-rw-r--r--src/gui/trade.cpp181
-rw-r--r--src/gui/trade.h60
-rw-r--r--src/gui/truetypefont.cpp26
-rw-r--r--src/gui/truetypefont.h17
-rw-r--r--src/gui/unregisterdialog.cpp141
-rw-r--r--src/gui/unregisterdialog.h70
-rw-r--r--src/gui/updatewindow.cpp15
-rw-r--r--src/gui/updatewindow.h7
-rw-r--r--src/gui/viewport.cpp170
-rw-r--r--src/gui/viewport.h31
-rw-r--r--src/gui/widgets/avatar.cpp55
-rw-r--r--src/gui/widgets/avatar.h61
-rw-r--r--src/gui/widgets/channeltab.cpp70
-rw-r--r--src/gui/widgets/channeltab.h57
-rw-r--r--src/gui/widgets/chattab.cpp324
-rw-r--r--src/gui/widgets/chattab.h118
-rw-r--r--src/gui/widgets/dropdown.cpp29
-rw-r--r--src/gui/widgets/dropdown.h33
-rw-r--r--src/gui/widgets/layout.cpp9
-rw-r--r--src/gui/widgets/layout.h9
-rw-r--r--src/gui/widgets/layouthelper.cpp7
-rw-r--r--src/gui/widgets/layouthelper.h7
-rw-r--r--src/gui/widgets/resizegrip.cpp17
-rw-r--r--src/gui/widgets/resizegrip.h5
-rw-r--r--src/gui/widgets/tab.cpp24
-rw-r--r--src/gui/widgets/tab.h5
-rw-r--r--src/gui/widgets/tabbedarea.cpp11
-rw-r--r--src/gui/widgets/tabbedarea.h9
-rw-r--r--src/gui/widgets/textpreview.cpp24
-rw-r--r--src/gui/widgets/textpreview.h22
-rw-r--r--src/gui/widgets/whispertab.cpp78
-rw-r--r--src/gui/widgets/whispertab.h55
-rw-r--r--src/gui/window.cpp23
-rw-r--r--src/gui/window.h45
-rw-r--r--src/gui/windowcontainer.cpp5
-rw-r--r--src/gui/windowcontainer.h5
-rw-r--r--src/guichanfwd.h5
-rw-r--r--src/guild.cpp69
-rw-r--r--src/guild.h108
-rw-r--r--src/imageparticle.cpp5
-rw-r--r--src/imageparticle.h5
-rw-r--r--src/inventory.cpp17
-rw-r--r--src/inventory.h16
-rw-r--r--src/item.cpp23
-rw-r--r--src/item.h16
-rw-r--r--src/itemshortcut.cpp11
-rw-r--r--src/itemshortcut.h5
-rw-r--r--src/joystick.cpp9
-rw-r--r--src/joystick.h5
-rw-r--r--src/keyboardconfig.cpp7
-rw-r--r--src/keyboardconfig.h7
-rw-r--r--src/localplayer.cpp641
-rw-r--r--src/localplayer.h334
-rw-r--r--src/lockedarray.h32
-rw-r--r--src/log.cpp7
-rw-r--r--src/log.h5
-rw-r--r--src/logindata.h37
-rw-r--r--src/main.cpp1041
-rw-r--r--src/main.h93
-rw-r--r--src/map.cpp174
-rw-r--r--src/map.h48
-rw-r--r--src/monster.cpp47
-rw-r--r--src/monster.h27
-rw-r--r--src/net/ea/beinghandler.cpp (renamed from src/net/beinghandler.cpp)285
-rw-r--r--src/net/ea/beinghandler.h (renamed from src/net/beinghandler.h)15
-rw-r--r--src/net/ea/buysellhandler.cpp (renamed from src/net/buysellhandler.cpp)85
-rw-r--r--src/net/ea/buysellhandler.h35
-rw-r--r--src/net/ea/charserverhandler.cpp (renamed from src/net/charserverhandler.cpp)75
-rw-r--r--src/net/ea/charserverhandler.h (renamed from src/net/charserverhandler.h)19
-rw-r--r--src/net/ea/chathandler.cpp (renamed from src/net/chathandler.cpp)89
-rw-r--r--src/net/ea/chathandler.h (renamed from src/net/chathandler.h)15
-rw-r--r--src/net/ea/equipmenthandler.cpp (renamed from src/net/equipmenthandler.cpp)73
-rw-r--r--src/net/ea/equipmenthandler.h (renamed from src/net/equipmenthandler.h)15
-rw-r--r--src/net/ea/inventoryhandler.cpp (renamed from src/net/inventoryhandler.cpp)157
-rw-r--r--src/net/ea/inventoryhandler.h35
-rw-r--r--src/net/ea/itemhandler.cpp (renamed from src/net/itemhandler.cpp)35
-rw-r--r--src/net/ea/itemhandler.h35
-rw-r--r--src/net/ea/loginhandler.cpp (renamed from src/net/loginhandler.cpp)71
-rw-r--r--src/net/ea/loginhandler.h (renamed from src/net/loginhandler.h)19
-rw-r--r--src/net/ea/maploginhandler.cpp (renamed from src/net/maploginhandler.cpp)37
-rw-r--r--src/net/ea/maploginhandler.h (renamed from src/net/maploginhandler.h)15
-rw-r--r--src/net/ea/network.cpp (renamed from src/net/network.cpp)22
-rw-r--r--src/net/ea/network.h (renamed from src/net/network.h)13
-rw-r--r--src/net/ea/npchandler.cpp (renamed from src/net/npchandler.cpp)69
-rw-r--r--src/net/ea/npchandler.h35
-rw-r--r--src/net/ea/partyhandler.cpp (renamed from src/net/partyhandler.cpp)47
-rw-r--r--src/net/ea/partyhandler.h (renamed from src/net/partyhandler.h)17
-rw-r--r--src/net/ea/playerhandler.cpp (renamed from src/net/playerhandler.cpp)313
-rw-r--r--src/net/ea/playerhandler.h (renamed from src/net/playerhandler.h)15
-rw-r--r--src/net/ea/protocol.cpp (renamed from src/net/protocol.cpp)7
-rw-r--r--src/net/ea/protocol.h (renamed from src/net/protocol.h)9
-rw-r--r--src/net/ea/skillhandler.cpp208
-rw-r--r--src/net/ea/skillhandler.h (renamed from src/net/skillhandler.h)15
-rw-r--r--src/net/ea/tradehandler.cpp (renamed from src/net/tradehandler.cpp)81
-rw-r--r--src/net/ea/tradehandler.h (renamed from src/net/tradehandler.h)17
-rw-r--r--src/net/messagehandler.cpp28
-rw-r--r--src/net/messagehandler.h14
-rw-r--r--src/net/messagein.cpp94
-rw-r--r--src/net/messagein.h42
-rw-r--r--src/net/messageout.cpp112
-rw-r--r--src/net/messageout.h48
-rw-r--r--src/net/skillhandler.cpp94
-rw-r--r--src/net/tmwserv/accountserver/account.cpp108
-rw-r--r--src/net/tmwserv/accountserver/account.h54
-rw-r--r--src/net/tmwserv/accountserver/accountserver.cpp82
-rw-r--r--src/net/tmwserv/accountserver/accountserver.h47
-rw-r--r--src/net/tmwserv/accountserver/internal.cpp32
-rw-r--r--src/net/tmwserv/accountserver/internal.h35
-rw-r--r--src/net/tmwserv/beinghandler.cpp357
-rw-r--r--src/net/tmwserv/beinghandler.h45
-rw-r--r--src/net/tmwserv/buysellhandler.cpp91
-rw-r--r--src/net/tmwserv/buysellhandler.h (renamed from src/net/buysellhandler.h)13
-rw-r--r--src/net/tmwserv/charserverhandler.cpp228
-rw-r--r--src/net/tmwserv/charserverhandler.h68
-rw-r--r--src/net/tmwserv/chathandler.cpp285
-rw-r--r--src/net/tmwserv/chathandler.h84
-rw-r--r--src/net/tmwserv/chatserver/chatserver.cpp147
-rw-r--r--src/net/tmwserv/chatserver/chatserver.h60
-rw-r--r--src/net/tmwserv/chatserver/guild.cpp95
-rw-r--r--src/net/tmwserv/chatserver/guild.h67
-rw-r--r--src/net/tmwserv/chatserver/internal.cpp32
-rw-r--r--src/net/tmwserv/chatserver/internal.h35
-rw-r--r--src/net/tmwserv/chatserver/party.cpp69
-rw-r--r--src/net/tmwserv/chatserver/party.h56
-rw-r--r--src/net/tmwserv/connection.cpp104
-rw-r--r--src/net/tmwserv/connection.h80
-rw-r--r--src/net/tmwserv/effecthandler.cpp59
-rw-r--r--src/net/tmwserv/effecthandler.h38
-rw-r--r--src/net/tmwserv/gameserver/gameserver.cpp50
-rw-r--r--src/net/tmwserv/gameserver/gameserver.h39
-rw-r--r--src/net/tmwserv/gameserver/internal.cpp32
-rw-r--r--src/net/tmwserv/gameserver/internal.h35
-rw-r--r--src/net/tmwserv/gameserver/player.cpp203
-rw-r--r--src/net/tmwserv/gameserver/player.h71
-rw-r--r--src/net/tmwserv/guildhandler.cpp243
-rw-r--r--src/net/tmwserv/guildhandler.h40
-rw-r--r--src/net/tmwserv/internal.cpp27
-rw-r--r--src/net/tmwserv/internal.h30
-rw-r--r--src/net/tmwserv/inventoryhandler.cpp79
-rw-r--r--src/net/tmwserv/inventoryhandler.h (renamed from src/net/inventoryhandler.h)13
-rw-r--r--src/net/tmwserv/itemhandler.cpp66
-rw-r--r--src/net/tmwserv/itemhandler.h (renamed from src/net/itemhandler.h)13
-rw-r--r--src/net/tmwserv/loginhandler.cpp226
-rw-r--r--src/net/tmwserv/loginhandler.h47
-rw-r--r--src/net/tmwserv/logouthandler.cpp218
-rw-r--r--src/net/tmwserv/logouthandler.h62
-rw-r--r--src/net/tmwserv/network.cpp170
-rw-r--r--src/net/tmwserv/network.h79
-rw-r--r--src/net/tmwserv/npchandler.cpp83
-rw-r--r--src/net/tmwserv/npchandler.h (renamed from src/net/npchandler.h)13
-rw-r--r--src/net/tmwserv/partyhandler.cpp105
-rw-r--r--src/net/tmwserv/partyhandler.h38
-rw-r--r--src/net/tmwserv/playerhandler.cpp329
-rw-r--r--src/net/tmwserv/playerhandler.h38
-rw-r--r--src/net/tmwserv/protocol.h295
-rw-r--r--src/net/tmwserv/tradehandler.cpp137
-rw-r--r--src/net/tmwserv/tradehandler.h53
-rw-r--r--src/npc.cpp46
-rw-r--r--src/npc.h28
-rw-r--r--src/openglgraphics.cpp9
-rw-r--r--src/openglgraphics.h5
-rw-r--r--src/particle.cpp7
-rw-r--r--src/particle.h9
-rw-r--r--src/particlecontainer.cpp38
-rw-r--r--src/particlecontainer.h11
-rw-r--r--src/particleemitter.cpp5
-rw-r--r--src/particleemitter.h5
-rw-r--r--src/particleemitterprop.h5
-rw-r--r--src/party.cpp83
-rw-r--r--src/party.h13
-rw-r--r--src/player.cpp69
-rw-r--r--src/player.h74
-rw-r--r--src/player_relations.cpp7
-rw-r--r--src/player_relations.h6
-rw-r--r--src/position.cpp5
-rw-r--r--src/position.h5
-rw-r--r--src/properties.h10
-rw-r--r--src/resources/action.cpp12
-rw-r--r--src/resources/action.h13
-rw-r--r--src/resources/ambientoverlay.cpp12
-rw-r--r--src/resources/ambientoverlay.h16
-rw-r--r--src/resources/animation.cpp12
-rw-r--r--src/resources/animation.h13
-rw-r--r--src/resources/colordb.cpp20
-rw-r--r--src/resources/colordb.h16
-rw-r--r--src/resources/dye.cpp17
-rw-r--r--src/resources/dye.h5
-rw-r--r--src/resources/emotedb.cpp20
-rw-r--r--src/resources/emotedb.h10
-rw-r--r--src/resources/image.cpp35
-rw-r--r--src/resources/image.h19
-rw-r--r--src/resources/imageloader.cpp16
-rw-r--r--src/resources/imageloader.h13
-rw-r--r--src/resources/imageset.cpp14
-rw-r--r--src/resources/imageset.h15
-rw-r--r--src/resources/imagewriter.cpp13
-rw-r--r--src/resources/imagewriter.h7
-rw-r--r--src/resources/itemdb.cpp173
-rw-r--r--src/resources/itemdb.h14
-rw-r--r--src/resources/iteminfo.cpp35
-rw-r--r--src/resources/iteminfo.h120
-rw-r--r--src/resources/mapreader.cpp52
-rw-r--r--src/resources/mapreader.h5
-rw-r--r--src/resources/monsterdb.cpp36
-rw-r--r--src/resources/monsterdb.h7
-rw-r--r--src/resources/monsterinfo.cpp53
-rw-r--r--src/resources/monsterinfo.h47
-rw-r--r--src/resources/music.cpp9
-rw-r--r--src/resources/music.h8
-rw-r--r--src/resources/npcdb.cpp13
-rw-r--r--src/resources/npcdb.h5
-rw-r--r--src/resources/resource.cpp12
-rw-r--r--src/resources/resource.h9
-rw-r--r--src/resources/resourcemanager.cpp40
-rw-r--r--src/resources/resourcemanager.h13
-rw-r--r--src/resources/soundeffect.cpp9
-rw-r--r--src/resources/soundeffect.h11
-rw-r--r--src/resources/spritedef.cpp73
-rw-r--r--src/resources/spritedef.h48
-rw-r--r--src/serverinfo.h5
-rw-r--r--src/shopitem.cpp21
-rw-r--r--src/shopitem.h8
-rw-r--r--src/simpleanimation.cpp9
-rw-r--r--src/simpleanimation.h5
-rw-r--r--src/sound.cpp5
-rw-r--r--src/sound.h7
-rw-r--r--src/sprite.h5
-rw-r--r--src/statuseffect.cpp174
-rw-r--r--src/statuseffect.h110
-rw-r--r--src/text.cpp74
-rw-r--r--src/text.h15
-rw-r--r--src/textmanager.cpp5
-rw-r--r--src/textmanager.h2
-rw-r--r--src/textparticle.cpp5
-rw-r--r--src/textparticle.h9
-rw-r--r--src/tileset.h5
-rw-r--r--src/tmw.rc (renamed from src/aethyra.rc)43
-rw-r--r--src/units.cpp234
-rw-r--r--src/units.h46
-rw-r--r--src/utils/base64.cpp4
-rw-r--r--src/utils/dtor.h8
-rw-r--r--src/utils/gettext.h7
-rw-r--r--src/utils/mutex.h9
-rw-r--r--src/utils/sha256.cpp276
-rw-r--r--src/utils/sha256.h35
-rw-r--r--src/utils/stringutils.cpp7
-rw-r--r--src/utils/stringutils.h5
-rw-r--r--src/utils/strprintf.cpp10
-rw-r--r--src/utils/strprintf.h5
-rw-r--r--src/utils/xml.cpp19
-rw-r--r--src/utils/xml.h14
-rw-r--r--src/vector.cpp5
-rw-r--r--src/vector.h5
-rw-r--r--src/winver.h10
463 files changed, 21798 insertions, 4944 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0176e617..4fa61ca7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -2,13 +2,15 @@ FIND_PACKAGE(SDL REQUIRED)
FIND_PACKAGE(SDL_image REQUIRED)
FIND_PACKAGE(SDL_mixer REQUIRED)
FIND_PACKAGE(SDL_net REQUIRED)
+FIND_PACKAGE(SDL_ttf REQUIRED)
+FIND_PACKAGE(ENet REQUIRED)
FIND_PACKAGE(CURL REQUIRED)
FIND_PACKAGE(LibXml2 REQUIRED)
FIND_PACKAGE(PhysFS REQUIRED)
FIND_PACKAGE(PNG REQUIRED)
SET(FLAGS "-DPACKAGE_VERSION=\\\"${VERSION}\\\"")
-SET(FLAGS "${FLAGS} -DAETHYRA_DATADIR=\\\"${PKG_DATADIR}/\\\"")
+SET(FLAGS "${FLAGS} -DTMW_DATADIR=\\\"${PKG_DATADIR}/\\\"")
SET(GUICHAN_COMPONENTS "SDL")
IF (WITH_OPENGL)
@@ -28,6 +30,8 @@ INCLUDE_DIRECTORIES(
${SDLIMAGE_INCLUDE_DIR}
${SDLMIXER_INCLUDE_DIR}
${SDLNET_INCLUDE_DIR}
+ ${SDLTTF_INCLUDE_DIR}
+ ${ENET_INCLUDE_DIR}
${PNG_INCLUDE_DIR}
${PHYSFS_INCLUDE_DIR}
${CURL_INCLUDE_DIR}
@@ -49,6 +53,8 @@ MARK_AS_ADVANCED(SDL_INCLUDE_DIR)
MARK_AS_ADVANCED(SDL_LIBRARY)
SET(SRCS
+ gui/widgets/avatar.cpp
+ gui/widgets/avatar.h
gui/widgets/dropdown.cpp
gui/widgets/dropdown.h
gui/widgets/resizegrip.cpp
@@ -71,6 +77,10 @@ SET(SRCS
gui/buy.h
gui/buysell.cpp
gui/buysell.h
+ gui/changeemaildialog.cpp
+ gui/changeemaildialog.h
+ gui/changepassworddialog.cpp
+ gui/changepassworddialog.h
gui/char_server.cpp
gui/char_server.h
gui/char_select.cpp
@@ -101,8 +111,14 @@ SET(SRCS
gui/gccontainer.h
gui/gui.cpp
gui/gui.h
+ gui/guildlistbox.cpp
+ gui/guildlistbox.h
+ gui/guildwindow.cpp
+ gui/guildwindow.h
gui/help.cpp
gui/help.h
+ gui/icon.cpp
+ gui/icon.h
gui/inttextfield.cpp
gui/inttextfield.h
gui/inventorywindow.cpp
@@ -124,6 +140,8 @@ SET(SRCS
gui/listbox.h
gui/login.cpp
gui/login.h
+ gui/magic.cpp
+ gui/magic.h
gui/menuwindow.cpp
gui/menuwindow.h
gui/minimap.cpp
@@ -136,12 +154,16 @@ SET(SRCS
gui/npclistdialog.h
gui/npcstringdialog.cpp
gui/npcstringdialog.h
+ gui/npcpostdialog.cpp
+ gui/npcpostdialog.h
gui/npc_text.cpp
gui/npc_text.h
gui/ok_dialog.cpp
gui/ok_dialog.h
gui/palette.cpp
gui/palette.h
+ gui/partywindow.h
+ gui/partywindow.cpp
gui/passwordfield.cpp
gui/passwordfield.h
gui/playerbox.cpp
@@ -152,6 +174,8 @@ SET(SRCS
gui/popupmenu.h
gui/progressbar.cpp
gui/progressbar.h
+ gui/quitdialog.cpp
+ gui/quitdialog.h
gui/radiobutton.cpp
gui/radiobutton.h
gui/recorder.cpp
@@ -164,6 +188,8 @@ SET(SRCS
gui/sdlinput.h
gui/sell.cpp
gui/sell.h
+ gui/serverdialog.cpp
+ gui/serverdialog.h
gui/setup.cpp
gui/setup.h
gui/setup_audio.cpp
@@ -205,6 +231,8 @@ SET(SRCS
gui/table_model.h
gui/textbox.cpp
gui/textbox.h
+ gui/textdialog.cpp
+ gui/textdialog.h
gui/textfield.cpp
gui/textfield.h
gui/textrenderer.h
@@ -212,30 +240,40 @@ SET(SRCS
gui/trade.h
gui/truetypefont.cpp
gui/truetypefont.h
- gui/updatewindow.h
+ gui/unregisterdialog.cpp
+ gui/unregisterdialog.h
gui/updatewindow.cpp
+ gui/updatewindow.h
gui/viewport.cpp
gui/viewport.h
gui/window.cpp
gui/window.h
gui/windowcontainer.cpp
gui/windowcontainer.h
- net/beinghandler.h
net/beinghandler.cpp
- net/buysellhandler.h
+ net/beinghandler.h
net/buysellhandler.cpp
- net/charserverhandler.h
+ net/buysellhandler.h
net/charserverhandler.cpp
- net/chathandler.h
+ net/charserverhandler.h
net/chathandler.cpp
- net/equipmenthandler.h
+ net/chathandler.h
+ net/connection.cpp
+ net/connection.h
net/equipmenthandler.cpp
- net/inventoryhandler.h
+ net/equipmenthandler.h
+ net/guildhandler.cpp
+ net/guildhandler.h
+ net/internal.cpp
+ net/internal.h
net/inventoryhandler.cpp
- net/itemhandler.h
+ net/inventoryhandler.h
net/itemhandler.cpp
- net/loginhandler.h
+ net/itemhandler.h
net/loginhandler.cpp
+ net/loginhandler.h
+ net/logouthandler.cpp
+ net/logouthandler.h
net/maploginhandler.cpp
net/maploginhandler.h
net/messagehandler.cpp
@@ -258,6 +296,28 @@ SET(SRCS
net/skillhandler.h
net/tradehandler.cpp
net/tradehandler.h
+ net/effecthandler.cpp
+ net/effecthandler.h
+ net/accountserver/account.cpp
+ net/accountserver/account.h
+ net/accountserver/accountserver.cpp
+ net/accountserver/accountserver.h
+ net/accountserver/internal.cpp
+ net/accountserver/internal.h
+ net/chatserver/chatserver.cpp
+ net/chatserver/chatserver.h
+ net/chatserver/guild.cpp
+ net/chatserver/guild.h
+ net/chatserver/internal.cpp
+ net/chatserver/internal.h
+ net/chatserver/party.cpp
+ net/chatserver/party.h
+ net/gameserver/gameserver.cpp
+ net/gameserver/gameserver.h
+ net/gameserver/internal.cpp
+ net/gameserver/internal.h
+ net/gameserver/player.cpp
+ net/gameserver/player.h
resources/action.cpp
resources/action.h
resources/ambientoverlay.cpp
@@ -305,6 +365,8 @@ SET(SRCS
utils/dtor.h
utils/fastsqrt.h
utils/gettext.h
+ utils/sha256.h
+ utils/sha256.cpp
utils/stringutils.cpp
utils/stringutils.h
utils/strprintf.cpp
@@ -319,6 +381,12 @@ SET(SRCS
being.h
beingmanager.cpp
beingmanager.h
+ channel.cpp
+ channel.h
+ channelmanager.cpp
+ channelmanager.h
+ commandhandler.cpp
+ commandhandler.h
configlistener.h
configuration.cpp
configuration.h
@@ -339,6 +407,8 @@ SET(SRCS
graphics.cpp
graphics.h
guichanfwd.h
+ guild.cpp
+ guild.h
imageparticle.cpp
imageparticle.h
inventory.cpp
@@ -398,17 +468,23 @@ SET(SRCS
textparticle.cpp
textparticle.h
tileset.h
+ units.cpp
+ units.h
vector.cpp
vector.h
+ effectmanager.cpp
+ effectmanager.h
)
-ADD_EXECUTABLE(aethyra ${SRCS})
+ADD_EXECUTABLE(tmw ${SRCS})
-TARGET_LINK_LIBRARIES(aethyra
+TARGET_LINK_LIBRARIES(tmw
${SDL_LIBRARY}
${SDLIMAGE_LIBRARY}
${SDLMIXER_LIBRARY}
${SDLNET_LIBRARY}
+ ${SDLTTF_LIBRARY}
+ ${ENET_LIBRARIES}
${PNG_LIBRARIES}
${PHYSFS_LIBRARY}
${CURL_LIBRARIES}
@@ -417,6 +493,6 @@ TARGET_LINK_LIBRARIES(aethyra
${OPENGL_LIBRARIES}
)
-INSTALL(TARGETS aethyra RUNTIME DESTINATION ${PKG_BINDIR})
+INSTALL(TARGETS tmw RUNTIME DESTINATION ${PKG_BINDIR})
-SET_TARGET_PROPERTIES(aethyra PROPERTIES COMPILE_FLAGS "${FLAGS}")
+SET_TARGET_PROPERTIES(tmw PROPERTIES COMPILE_FLAGS "${FLAGS}")
diff --git a/src/Makefile.am b/src/Makefile.am
index 5029697a..4c5893ac 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,8 +1,18 @@
AUTOMAKE_OPTIONS = subdir-objects
-bin_PROGRAMS = aethyra
-aethyra_SOURCES = gui/widgets/dropdown.cpp \
- gui/widgets/dropdown.h \
+bin_PROGRAMS = tmw
+
+tmw_CXXFLAGS = -DPKG_DATADIR=\""$(pkgdatadir)/"\" \
+ -DLOCALEDIR=\""$(localedir)"\"
+
+tmw_SOURCES = gui/widgets/avatar.cpp \
+ gui/widgets/avatar.h \
+ gui/widgets/channeltab.cpp \
+ gui/widgets/channeltab.h \
+ gui/widgets/chattab.cpp \
+ gui/widgets/chattab.h \
+ gui/widgets/dropdown.cpp \
+ gui/widgets/dropdown.h \
gui/widgets/layout.cpp \
gui/widgets/layout.h \
gui/widgets/layouthelper.cpp \
@@ -15,6 +25,8 @@ aethyra_SOURCES = gui/widgets/dropdown.cpp \
gui/widgets/tabbedarea.h \
gui/widgets/textpreview.cpp \
gui/widgets/textpreview.h \
+ gui/widgets/whispertab.cpp \
+ gui/widgets/whispertab.h \
gui/browserbox.cpp \
gui/browserbox.h \
gui/button.cpp \
@@ -25,8 +37,6 @@ aethyra_SOURCES = gui/widgets/dropdown.cpp \
gui/buysell.h \
gui/char_select.cpp \
gui/char_select.h \
- gui/char_server.cpp \
- gui/char_server.h \
gui/chat.cpp \
gui/chat.h \
gui/chatinput.cpp \
@@ -35,8 +45,6 @@ aethyra_SOURCES = gui/widgets/dropdown.cpp \
gui/checkbox.h \
gui/confirm_dialog.cpp \
gui/confirm_dialog.h \
- gui/connection.cpp \
- gui/connection.h \
gui/debugwindow.cpp \
gui/debugwindow.h \
gui/emotecontainer.cpp \
@@ -55,8 +63,10 @@ aethyra_SOURCES = gui/widgets/dropdown.cpp \
gui/gui.h \
gui/help.cpp \
gui/help.h \
- gui/inttextfield.h \
+ gui/icon.cpp \
+ gui/icon.h \
gui/inttextfield.cpp \
+ gui/inttextfield.h \
gui/inventorywindow.cpp \
gui/inventorywindow.h \
gui/itemcontainer.cpp \
@@ -106,8 +116,8 @@ aethyra_SOURCES = gui/widgets/dropdown.cpp \
gui/progressbar.h \
gui/radiobutton.cpp \
gui/radiobutton.h \
- gui/recorder.cpp \
- gui/recorder.h \
+ gui/recorder.cpp \
+ gui/recorder.h \
gui/register.cpp \
gui/register.h \
gui/scrollarea.cpp \
@@ -139,24 +149,20 @@ aethyra_SOURCES = gui/widgets/dropdown.cpp \
gui/shortcutwindow.h \
gui/shortcutcontainer.cpp \
gui/shortcutcontainer.h \
- gui/skill.cpp \
- gui/skill.h \
gui/skin.cpp \
gui/skin.h \
gui/slider.cpp \
gui/slider.h \
gui/speechbubble.cpp \
gui/speechbubble.h \
- gui/status.cpp \
- gui/status.h \
- gui/storagewindow.cpp \
- gui/storagewindow.h \
gui/table.cpp \
gui/table.h \
gui/table_model.cpp \
gui/table_model.h \
gui/textbox.cpp \
gui/textbox.h \
+ gui/textdialog.cpp \
+ gui/textdialog.h \
gui/textfield.cpp \
gui/textfield.h \
gui/textrenderer.h \
@@ -164,52 +170,20 @@ aethyra_SOURCES = gui/widgets/dropdown.cpp \
gui/trade.h \
gui/truetypefont.cpp \
gui/truetypefont.h \
- gui/updatewindow.h \
gui/updatewindow.cpp \
+ gui/updatewindow.h \
gui/viewport.cpp \
gui/viewport.h \
gui/window.cpp \
gui/window.h \
gui/windowcontainer.cpp \
gui/windowcontainer.h \
- net/beinghandler.h \
- net/beinghandler.cpp \
- net/buysellhandler.h \
- net/buysellhandler.cpp \
- net/charserverhandler.h \
- net/charserverhandler.cpp \
- net/chathandler.h \
- net/chathandler.cpp \
- net/equipmenthandler.h \
- net/equipmenthandler.cpp \
- net/inventoryhandler.h \
- net/inventoryhandler.cpp \
- net/itemhandler.h \
- net/itemhandler.cpp \
- net/loginhandler.h \
- net/loginhandler.cpp \
- net/maploginhandler.cpp \
- net/maploginhandler.h \
net/messagehandler.cpp \
net/messagehandler.h \
net/messagein.cpp \
net/messagein.h \
net/messageout.cpp \
net/messageout.h \
- net/network.cpp \
- net/network.h \
- net/npchandler.cpp \
- net/npchandler.h \
- net/partyhandler.cpp \
- net/partyhandler.h \
- net/playerhandler.cpp \
- net/playerhandler.h \
- net/protocol.cpp \
- net/protocol.h \
- net/skillhandler.cpp \
- net/skillhandler.h \
- net/tradehandler.cpp \
- net/tradehandler.h \
resources/action.cpp \
resources/action.h \
resources/ambientoverlay.cpp \
@@ -257,6 +231,8 @@ aethyra_SOURCES = gui/widgets/dropdown.cpp \
utils/dtor.h \
utils/fastsqrt.h \
utils/gettext.h \
+ utils/sha256.cpp \
+ utils/sha256.h \
utils/stringutils.cpp \
utils/stringutils.h \
utils/strprintf.cpp \
@@ -272,6 +248,12 @@ aethyra_SOURCES = gui/widgets/dropdown.cpp \
being.h \
beingmanager.cpp \
beingmanager.h \
+ channel.cpp \
+ channel.h \
+ channelmanager.cpp \
+ channelmanager.h \
+ commandhandler.cpp \
+ commandhandler.h \
configlistener.h \
configuration.cpp \
configuration.h \
@@ -327,8 +309,6 @@ aethyra_SOURCES = gui/widgets/dropdown.cpp \
particleemitter.cpp \
particleemitter.h \
particleemitterprop.h \
- party.cpp \
- party.h \
player.cpp \
player.h \
player_relations.cpp \
@@ -344,6 +324,8 @@ aethyra_SOURCES = gui/widgets/dropdown.cpp \
sound.cpp \
sound.h \
sprite.h \
+ statuseffect.cpp \
+ statuseffect.h \
text.cpp \
text.h \
textmanager.cpp \
@@ -351,17 +333,147 @@ aethyra_SOURCES = gui/widgets/dropdown.cpp \
textparticle.cpp \
textparticle.h \
tileset.h \
+ units.cpp \
+ units.h \
vector.cpp \
vector.h
-# set the include path found by configure
-INCLUDES = \
- $(all_includes) \
- -DPKG_DATADIR=\""$(pkgdatadir)/"\" \
- -DLOCALEDIR=\""$(localedir)/"\"
+if SERVER_TMWSERV
+tmw_CXXFLAGS += -DTMWSERV_SUPPORT
+tmw_SOURCES += \
+ gui/buddywindow.cpp \
+ gui/buddywindow.h \
+ gui/changeemaildialog.cpp \
+ gui/changeemaildialog.h \
+ gui/changepassworddialog.cpp \
+ gui/changepassworddialog.h \
+ gui/connection.cpp \
+ gui/connection.h \
+ gui/guildlistbox.cpp \
+ gui/guildlistbox.h \
+ gui/guildwindow.cpp \
+ gui/guildwindow.h \
+ gui/magic.cpp \
+ gui/magic.h \
+ gui/npcpostdialog.cpp \
+ gui/npcpostdialog.h \
+ gui/partywindow.cpp \
+ gui/partywindow.h \
+ gui/quitdialog.cpp \
+ gui/quitdialog.h \
+ gui/serverdialog.cpp \
+ gui/serverdialog.h \
+ gui/skilldialog.cpp \
+ gui/skilldialog.h \
+ gui/statuswindow.cpp \
+ gui/statuswindow.h \
+ gui/unregisterdialog.cpp \
+ gui/unregisterdialog.h \
+ net/tmwserv/accountserver/account.cpp \
+ net/tmwserv/accountserver/account.h \
+ net/tmwserv/accountserver/accountserver.cpp \
+ net/tmwserv/accountserver/accountserver.h \
+ net/tmwserv/accountserver/internal.cpp \
+ net/tmwserv/accountserver/internal.h \
+ net/tmwserv/chatserver/chatserver.cpp \
+ net/tmwserv/chatserver/chatserver.h \
+ net/tmwserv/chatserver/guild.cpp \
+ net/tmwserv/chatserver/guild.h \
+ net/tmwserv/chatserver/internal.cpp \
+ net/tmwserv/chatserver/internal.h \
+ net/tmwserv/chatserver/party.cpp \
+ net/tmwserv/chatserver/party.h \
+ net/tmwserv/gameserver/gameserver.cpp \
+ net/tmwserv/gameserver/gameserver.h \
+ net/tmwserv/gameserver/internal.cpp \
+ net/tmwserv/gameserver/internal.h \
+ net/tmwserv/gameserver/player.cpp \
+ net/tmwserv/gameserver/player.h \
+ net/tmwserv/beinghandler.cpp \
+ net/tmwserv/beinghandler.h \
+ net/tmwserv/buysellhandler.cpp \
+ net/tmwserv/buysellhandler.h \
+ net/tmwserv/charserverhandler.cpp \
+ net/tmwserv/charserverhandler.h \
+ net/tmwserv/chathandler.cpp \
+ net/tmwserv/chathandler.h \
+ net/tmwserv/connection.cpp \
+ net/tmwserv/connection.h \
+ net/tmwserv/effecthandler.cpp \
+ net/tmwserv/effecthandler.h \
+ net/tmwserv/guildhandler.cpp \
+ net/tmwserv/guildhandler.h \
+ net/tmwserv/internal.cpp \
+ net/tmwserv/internal.h \
+ net/tmwserv/inventoryhandler.cpp \
+ net/tmwserv/inventoryhandler.h \
+ net/tmwserv/itemhandler.h \
+ net/tmwserv/itemhandler.cpp \
+ net/tmwserv/loginhandler.cpp \
+ net/tmwserv/loginhandler.h \
+ net/tmwserv/logouthandler.cpp \
+ net/tmwserv/logouthandler.h \
+ net/tmwserv/network.cpp \
+ net/tmwserv/network.h \
+ net/tmwserv/npchandler.cpp \
+ net/tmwserv/npchandler.h \
+ net/tmwserv/partyhandler.cpp \
+ net/tmwserv/partyhandler.h \
+ net/tmwserv/playerhandler.cpp \
+ net/tmwserv/playerhandler.h \
+ net/tmwserv/protocol.h \
+ net/tmwserv/tradehandler.cpp \
+ net/tmwserv/tradehandler.h \
+ guild.cpp \
+ guild.h
+endif
-# the library search path.
-aethyra_LDFLAGS = $(all_libraries) $(LIBSDL_RPATH) `pkg-config --libs libxml-2.0`
-aethyra_CXXFLAGS = -Wall $(LIBSDL_CFLAGS) `pkg-config --cflags libxml-2.0` $(CURL_CFLAGS)
-aethyra_LDADD = $(LIBSDL_LIBS) -lguichan_sdl $(CURL_LIBS)
-aethyra_TARGET = aethyra
+if SERVER_EATHENA
+tmw_CXXFLAGS += -DEATHENA_SUPPORT
+tmw_SOURCES += \
+ gui/char_server.cpp \
+ gui/char_server.h \
+ gui/skill.cpp \
+ gui/skill.h \
+ gui/status.cpp \
+ gui/status.h \
+ gui/storagewindow.cpp \
+ gui/storagewindow.h \
+ net/ea/beinghandler.cpp \
+ net/ea/beinghandler.h \
+ net/ea/buysellhandler.cpp \
+ net/ea/buysellhandler.h \
+ net/ea/charserverhandler.cpp \
+ net/ea/charserverhandler.h \
+ net/ea/chathandler.cpp \
+ net/ea/chathandler.h \
+ net/ea/equipmenthandler.cpp \
+ net/ea/equipmenthandler.h \
+ net/ea/inventoryhandler.cpp \
+ net/ea/inventoryhandler.h \
+ net/ea/itemhandler.cpp \
+ net/ea/itemhandler.h \
+ net/ea/loginhandler.cpp \
+ net/ea/loginhandler.h \
+ net/ea/maploginhandler.cpp \
+ net/ea/maploginhandler.h \
+ net/ea/network.cpp \
+ net/ea/network.h \
+ net/ea/npchandler.cpp \
+ net/ea/npchandler.h \
+ net/ea/partyhandler.cpp \
+ net/ea/partyhandler.h \
+ net/ea/playerhandler.cpp \
+ net/ea/playerhandler.h \
+ net/ea/protocol.cpp \
+ net/ea/protocol.h \
+ net/ea/skillhandler.cpp \
+ net/ea/skillhandler.h \
+ net/ea/tradehandler.cpp \
+ net/ea/tradehandler.h \
+ party.cpp \
+ party.h
+endif
+
+# set the include path found by configure
+INCLUDES = $(all_includes)
diff --git a/src/SDLMain.h b/src/SDLMain.h
index 4683df57..4683df57 100755..100644
--- a/src/SDLMain.h
+++ b/src/SDLMain.h
diff --git a/src/SDLMain.m b/src/SDLMain.m
index 3d02719c..3d02719c 100755..100644
--- a/src/SDLMain.m
+++ b/src/SDLMain.m
diff --git a/src/animatedsprite.cpp b/src/animatedsprite.cpp
index 108f5166..5a57b08c 100644
--- a/src/animatedsprite.cpp
+++ b/src/animatedsprite.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -52,7 +51,7 @@ AnimatedSprite::AnimatedSprite(SpriteDef *sprite):
play(ACTION_STAND);
}
-AnimatedSprite *AnimatedSprite::load(const std::string& filename, int variant)
+AnimatedSprite *AnimatedSprite::load(const std::string &filename, int variant)
{
ResourceManager *resman = ResourceManager::getInstance();
SpriteDef *s = resman->getSprite(filename, variant);
@@ -141,7 +140,7 @@ bool AnimatedSprite::updateCurrentAnimation(unsigned int time)
return true;
}
-bool AnimatedSprite::draw(Graphics* graphics, int posX, int posY) const
+bool AnimatedSprite::draw(Graphics *graphics, int posX, int posY) const
{
if (!mFrame || !mFrame->image)
return false;
diff --git a/src/animatedsprite.h b/src/animatedsprite.h
index 756d9aed..43248731 100644
--- a/src/animatedsprite.h
+++ b/src/animatedsprite.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -51,7 +50,8 @@ class AnimatedSprite
* @param filename the file of the sprite to animate
* @param variant the sprite variant
*/
- static AnimatedSprite *load(std::string const &filename, int variant = 0);
+ static AnimatedSprite *load(const std::string &filename,
+ int variant = 0);
/**
* Destructor.
diff --git a/src/animationparticle.cpp b/src/animationparticle.cpp
index 4e1c348b..9c1f7ccb 100644
--- a/src/animationparticle.cpp
+++ b/src/animationparticle.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2006 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/animationparticle.h b/src/animationparticle.h
index 444703f3..03065eb7 100644
--- a/src/animationparticle.h
+++ b/src/animationparticle.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2006 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/being.cpp b/src/being.cpp
index 8f00fd3c..e143d506 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,11 +19,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <cassert>
-#include <cmath>
+#include "being.h"
#include "animatedsprite.h"
-#include "being.h"
#include "configuration.h"
#include "effectmanager.h"
#include "game.h"
@@ -36,6 +33,7 @@
#include "simpleanimation.h"
#include "sound.h"
#include "text.h"
+#include "statuseffect.h"
#include "gui/speechbubble.h"
@@ -53,8 +51,22 @@
#include "utils/dtor.h"
#include "utils/gettext.h"
#include "utils/stringutils.h"
+#include "utils/xml.h"
+
+#include <cassert>
+#include <cmath>
+
+namespace {
+const bool debug_movement = true;
+}
+
+#define BEING_EFFECTS_FILE "effects.xml"
+#define HAIR_FILE "hair.xml"
+
+int Being::mNumberOfHairColors = 1;
int Being::mNumberOfHairstyles = 1;
+std::vector<std::string> Being::hairColors;
static const int X_SPEECH_OFFSET = 18;
static const int Y_SPEECH_OFFSET = 60;
@@ -63,35 +75,50 @@ static const int DEFAULT_WIDTH = 32;
static const int DEFAULT_HEIGHT = 32;
Being::Being(int id, int job, Map *map):
- mJob(job),
+#ifdef EATHENA_SUPPORT
mX(0), mY(0),
- mAction(STAND),
mWalkTime(0),
+#endif
mEmotion(0), mEmotionTime(0),
mSpeechTime(0),
mAttackSpeed(350),
+ mAction(STAND),
+ mJob(job),
mId(id),
- mWalkSpeed(150),
mDirection(DOWN),
+#ifdef TMWSERV_SUPPORT
+ mSpriteDirection(DIRECTION_DOWN),
+#endif
mMap(NULL),
- mName(""),
mIsGM(false),
mParticleEffects(config.getValue("particleeffects", 1)),
mEquippedWeapon(NULL),
- mHairStyle(1), mHairColor(0),
+#ifdef TMWSERV_SUPPORT
+ mHairStyle(0),
+#else
+ mHairStyle(1),
+#endif
+ mHairColor(0),
mGender(GENDER_UNSPECIFIED),
mPx(0), mPy(0),
+ mStunMode(0),
mSprites(VECTOREND_SPRITE, NULL),
mSpriteIDs(VECTOREND_SPRITE, 0),
mSpriteColors(VECTOREND_SPRITE, ""),
- mChildParticleEffects(),
+ mStatusParticleEffects(&mStunParticleEffects, false),
+ mChildParticleEffects(&mStatusParticleEffects, false),
+ mMustResetParticles(false),
+#ifdef TMWSERV_SUPPORT
+ mWalkSpeed(100),
+#else
+ mWalkSpeed(150),
+#endif
mUsedTargetCursor(NULL)
{
setMap(map);
- mSpeechBubble = new SpeechBubble();
+ mSpeechBubble = new SpeechBubble;
- mSpeech = "";
mNameColor = &guiPalette->getColor(Palette::CHAT);
mText = 0;
}
@@ -111,12 +138,188 @@ Being::~Being()
delete mText;
}
+void Being::setPosition(const Vector &pos)
+{
+ mPos = pos;
+ mDest = pos;
+ mPath.clear();
+}
+
+#ifdef EATHENA_SUPPORT
void Being::setDestination(Uint16 destX, Uint16 destY)
{
if (mMap)
- setPath(mMap->findPath(mX, mY, destX, destY));
+ setPath(mMap->findPath(mX, mY, destX, destY, getWalkMask()));
+}
+#endif
+
+#ifdef TMWSERV_SUPPORT
+void Being::adjustCourse(int srcX, int srcY, int dstX, int dstY)
+{
+ if (debug_movement)
+ printf("%p adjustCourse(%d, %d, %d, %d)\n",
+ (void*) this, srcX, srcY, dstX, dstY);
+
+ mDest.x = dstX;
+ mDest.y = dstY;
+
+ // Find a path to the destination when it is at least a tile away
+ if (mMap && fabsf((mDest - mPos).length()) > 32) {
+ setPath(mMap->findPath((int) mPos.x / 32, (int) mPos.y / 32,
+ dstX / 32, dstY / 32, getWalkMask()));
+ } else {
+ setPath(Path());
+ }
+
+ // TODO: Evaluate the implementation of this method
+ /*
+ if (mX / 32 == dstX / 32 && mY / 32 == dstY / 32)
+ {
+ // The being is already on the last tile of the path.
+ Path p;
+ p.push_back(Position(dstX, dstY));
+ setPath(p);
+ return;
+ }
+
+ Path p1;
+ int p1_size, p1_length;
+ Uint16 *p1_dist;
+ int onPath = -1;
+ if (srcX / 32 == dstX / 32 && srcY / 32 == dstY / 32)
+ {
+ p1_dist = new Uint16[1];
+ p1_size = 1;
+ p1_dist[0] = 0;
+ p1_length = 0;
+ }
+ else
+ {
+ p1 = mMap->findPath(srcX / 32, srcY / 32, dstX / 32, dstY / 32, getWalkMask());
+ if (p1.empty())
+ {
+ // No path, but don't teleport since it could be user input.
+ setPath(p1);
+ return;
+ }
+ p1_size = p1.size();
+ p1_dist = new Uint16[p1_size];
+ int j = 0;
+ // Remove last tile so that it can be replaced by the exact destination.
+ p1.pop_back();
+ for (Path::iterator i = p1.begin(), i_end = p1.end(); i != i_end; ++i)
+ {
+ // Get distance from source to tile i.
+ p1_dist[j] = mMap->getMetaTile(i->x, i->y)->Gcost;
+ // Check if the being is already walking on the path.
+ if (i->x == mX / 32 && i->y == mY / 32)
+ {
+ onPath = j;
+ }
+ // Do not set any offset for intermediate steps.
+ i->x = i->x * 32;
+ i->y = i->y * 32;
+ ++j;
+ }
+ p1_length = mMap->getMetaTile(dstX / 32, dstY / 32)->Gcost;
+ p1_dist[p1_size - 1] = p1_length;
+ }
+ p1.push_back(Position(dstX, dstY));
+
+ if (mX / 32 == srcX / 32 && mY / 32 == srcY / 32)
+ {
+ // The being is at the start of the path.
+ setPath(p1);
+ delete[] p1_dist;
+ return;
+ }
+
+ if (onPath >= 0)
+ {
+ // The being is already on the path, but it needs to be slowed down.
+ for (int j = onPath; j >= 0; --j)
+ {
+ p1.pop_front();
+ }
+ int r = p1_length - p1_dist[onPath]; // remaining length
+ assert(r > 0);
+ setPath(p1, p1_length * 1024 / r);
+ delete[] p1_dist;
+ return;
+ }
+
+ Path bestPath;
+ int bestRating = -1, bestStart = 0, bestLength = 0;
+ int j = 0;
+
+ for (Path::iterator i = p1.begin(), i_end = p1.end(); i != i_end; ++i)
+ {
+ // Look if it is worth passing by tile i.
+ Path p2 = mMap->findPath(mX / 32, mY / 32, i->x / 32, i->y / 32, getWalkMask());
+ if (!p2.empty())
+ {
+ int l1 = mMap->getMetaTile(i->x / 32, i->y / 32)->Gcost;
+ int l2 = p1_length - p1_dist[j];
+ int r = l1 + l2 / 2; // TODO: tune rating formula
+ assert(r > 0);
+ if (bestRating < 0 || r < bestRating)
+ {
+ bestPath.swap(p2);
+ bestRating = r;
+ bestStart = j;
+ bestLength = l1 + l2;
+ }
+ }
+ ++j;
+ }
+
+ if (bestRating < 0)
+ {
+ // Unable to reach the path? Still, don't teleport since it could be
+ // user input instead of server command.
+ setPath(p1);
+ delete[] p1_dist;
+ return;
+ }
+
+ bestPath.pop_back();
+ for (Path::iterator i = bestPath.begin(), i_end = bestPath.end(); i != i_end; ++i)
+ {
+ i->x = i->x * 32;
+ i->y = i->y * 32;
+ }
+
+ // Concatenate paths.
+ for (int j = bestStart; j > 0; --j)
+ {
+ p1.pop_front();
+ }
+ p1.splice(p1.begin(), bestPath);
+
+ assert(bestLength > 0);
+ setPath(p1, p1_length * 1024 / bestLength);
+ delete[] p1_dist;
+ */
}
+void Being::adjustCourse(int srcX, int srcY)
+{
+ if (debug_movement)
+ printf("%p adjustCourse(%d, %d)\n", (void*) this, srcX, srcY);
+
+ if (!mPath.empty())
+ adjustCourse(srcX, srcY, mPath.back().x * 32, mPath.back().y * 32);
+}
+
+void Being::setDestination(int destX, int destY)
+{
+ if (debug_movement)
+ printf("%p setDestination(%d, %d)\n", (void*) this, destX, destY);
+
+ adjustCourse((int) mPos.x, (int) mPos.y, destX, destY);
+}
+#endif // TMWSERV_SUPPORT
+
void Being::clearPath()
{
mPath.clear();
@@ -125,12 +328,15 @@ void Being::clearPath()
void Being::setPath(const Path &path)
{
mPath = path;
-
+#ifdef TMWSERV_SUPPORT
+ std::cout << this << " New path: " << path << std::endl;
+#else
if (mAction != WALK && mAction != DEAD)
{
nextStep();
mWalkTime = tick_time;
}
+#endif
}
void Being::setHairStyle(int style, int color)
@@ -139,7 +345,7 @@ void Being::setHairStyle(int style, int color)
mHairColor = color < 0 ? mHairColor : color % ColorDB::size();
}
-void Being::setSprite(int slot, int id, std::string color)
+void Being::setSprite(int slot, int id, const std::string &color)
{
assert(slot >= BASE_SPRITE && slot < VECTOREND_SPRITE);
mSpriteIDs[slot] = id;
@@ -224,22 +430,40 @@ void Being::takeDamage(Being *attacker, int amount, AttackType type)
color = &guiPalette->getColor(Palette::HIT_MONSTER_PLAYER);
}
- if (amount > 0 && type == CRITICAL)
+ // Show damage number
+ particleEngine->addTextSplashEffect(damage,
+#ifdef TMWSERV_SUPPORT
+ (int) mPos.x + 16,
+ (int) mPos.y + 16,
+#else
+ mPx + 16, mPy + 16,
+#endif
+ color, font, true);
+
+ if (amount > 0)
{
- particleEngine->addTextSplashEffect("crit!", mPx + 16, mPy + 16,
- color, font, true);
+ if (type != CRITICAL)
+ {
+ effectManager->trigger(26, this);
+ }
+ else
+ {
+ effectManager->trigger(28, this);
+ }
}
-
- // Show damage number
- particleEngine->addTextSplashEffect(damage, mPx + 16, mPy + 16,
- color, font, true);
}
+#ifdef TMWSERV_SUPPORT
+void Being::handleAttack()
+#else
void Being::handleAttack(Being *victim, int damage, AttackType type)
+#endif
{
setAction(Being::ATTACK);
+#ifdef EATHENA_SUPPORT
mFrame = 0;
mWalkTime = tick_time;
+#endif
}
void Being::setMap(Map *map)
@@ -256,6 +480,7 @@ void Being::setMap(Map *map)
// Clear particle effect list because child particles became invalid
mChildParticleEffects.clear();
+ mMustResetParticles = true; // Reset status particles on next redraw
}
void Being::controlParticle(Particle *particle)
@@ -263,7 +488,7 @@ void Being::controlParticle(Particle *particle)
mChildParticleEffects.addLocally(particle);
}
-void Being::setAction(Action action)
+void Being::setAction(Action action, int attackType)
{
SpriteAction currentAction = ACTION_INVALID;
@@ -316,8 +541,27 @@ void Being::setDirection(Uint8 direction)
if (mDirection == direction)
return;
+#ifdef TMWSERV_SUPPORT
+ // if the direction does not change much, keep the common component
+ int mFaceDirection = mDirection & direction;
+ if (!mFaceDirection)
+ mFaceDirection = direction;
+ mDirection = direction;
+
+ SpriteDirection dir;
+ if (mFaceDirection & UP)
+ dir = DIRECTION_UP;
+ else if (mFaceDirection & DOWN)
+ dir = DIRECTION_DOWN;
+ else if (mFaceDirection & RIGHT)
+ dir = DIRECTION_RIGHT;
+ else
+ dir = DIRECTION_LEFT;
+ mSpriteDirection = dir;
+#else
mDirection = direction;
SpriteDirection dir = getSpriteDirection();
+#endif
for (int i = 0; i < VECTOREND_SPRITE; i++)
{
@@ -326,6 +570,7 @@ void Being::setDirection(Uint8 direction)
}
}
+#ifdef EATHENA_SUPPORT
SpriteDirection Being::getSpriteDirection() const
{
SpriteDirection dir;
@@ -365,7 +610,7 @@ void Being::nextStep()
setDirection(dir);
- if (mMap->tileCollides(pos.x, pos.y))
+ if (!mMap->getWalk(pos.x, pos.y, getWalkMask()))
{
setAction(STAND);
return;
@@ -376,12 +621,13 @@ void Being::nextStep()
setAction(WALK);
mWalkTime += mWalkSpeed / 10;
}
+#endif
void Being::logic()
{
// Reduce the time that speech is still displayed
if (mSpeechTime > 0)
- mSpeechTime--;
+ mSpeechTime--;
// Remove text and speechbubbles if speech boxes aren't being used
if (mSpeechTime == 0 && mText)
@@ -390,6 +636,42 @@ void Being::logic()
mText = 0;
}
+#ifdef TMWSERV_SUPPORT
+ const Vector dest = (mPath.empty()) ?
+ mDest : Vector(mPath.front().x * 32 + 16,
+ mPath.front().y * 32 + 16);
+
+ Vector dir = dest - mPos;
+ const float length = dir.length();
+
+ // When we're over 2 pixels from our destination, move to it
+ // TODO: Should be possible to make it even pixel exact, but this solves
+ // the jigger caused by moving too far.
+ if (length > 2.0f) {
+ const float speed = mWalkSpeed / 100.0f;
+ mPos += dir / (length / speed);
+
+ if (mAction != WALK)
+ setAction(WALK);
+
+ // Update the player sprite direction
+ int direction = 0;
+ const float dx = std::abs(dir.x);
+ const float dy = std::abs(dir.y);
+ if (dx > dy)
+ direction |= (dir.x > 0) ? RIGHT : LEFT;
+ else
+ direction |= (dir.y > 0) ? DOWN : UP;
+ setDirection(direction);
+ }
+ else if (!mPath.empty()) {
+ // TODO: Pop as soon as there is a direct unblocked line to the next
+ // point on the path.
+ mPath.pop_front();
+ } else if (mAction == WALK) {
+ setAction(STAND);
+ }
+#else
int oldPx = mPx;
int oldPy = mPy;
@@ -401,6 +683,7 @@ void Being::logic()
{
updateCoords();
}
+#endif
if (mEmotion != 0)
{
@@ -410,7 +693,7 @@ void Being::logic()
}
// Update sprite animations
- if (mUsedTargetCursor != NULL)
+ if (mUsedTargetCursor)
mUsedTargetCursor->update(tick_time * 10);
for (int i = 0; i < VECTOREND_SPRITE; i++)
@@ -419,22 +702,51 @@ void Being::logic()
mSprites[i]->update(tick_time * 10);
}
+ // Restart status/particle effects, if needed
+ if (mMustResetParticles) {
+ mMustResetParticles = false;
+ for (std::set<int>::iterator it = mStatusEffects.begin();
+ it != mStatusEffects.end(); it++) {
+ const StatusEffect *effect = StatusEffect::getStatusEffect(*it, true);
+ if (effect && effect->particleEffectIsPersistent())
+ updateStatusEffect(*it, true);
+ }
+ }
+
// Update particle effects
- mChildParticleEffects.moveTo((float) mPx + 16.0f, (float) mPy + 32.0f);
+#ifdef TMWSERV_SUPPORT
+ mChildParticleEffects.moveTo((float) mPx + 16.0f,
+ (float) mPy + 32.0f);
+#else
+ mChildParticleEffects.moveTo(mPos.x, mPos.y);
+#endif
}
void Being::draw(Graphics *graphics, int offsetX, int offsetY) const
{
+#ifdef TMWSERV_SUPPORT
+ int px = (int) mPos.x + offsetX;
+ int py = (int) mPos.y + offsetY;
+#else
int px = mPx + offsetX;
int py = mPy + offsetY;
+#endif
- if (mUsedTargetCursor != NULL)
+ if (mUsedTargetCursor)
mUsedTargetCursor->draw(graphics, px, py);
for (int i = 0; i < VECTOREND_SPRITE; i++)
{
if (mSprites[i])
+ {
+#ifdef TMWSERV_SUPPORT
+ // TODO: Eventually, we probably should fix all sprite offsets so
+ // that this translation isn't necessary anymore.
+ mSprites[i]->draw(graphics, px - 16, py - 32);
+#else
mSprites[i]->draw(graphics, px, py);
+#endif
+ }
}
}
@@ -443,8 +755,13 @@ void Being::drawEmotion(Graphics *graphics, int offsetX, int offsetY)
if (!mEmotion)
return;
+#ifdef TMWSERV_SUPPORT
+ const int px = (int) mPos.x + offsetX;
+ const int py = (int) mPos.y + offsetY - 64;
+#else
const int px = mPx - offsetX;
const int py = mPy - offsetY - 64;
+#endif
const int emotionIndex = mEmotion - 1;
if (emotionIndex >= 0 && emotionIndex <= EmoteDB::getLast())
@@ -453,8 +770,13 @@ void Being::drawEmotion(Graphics *graphics, int offsetX, int offsetY)
void Being::drawSpeech(int offsetX, int offsetY)
{
+#ifdef TMWSERV_SUPPORT
+ int px = (int) mPos.x - offsetX;
+ int py = (int) mPos.y - offsetY;
+#else
const int px = mPx - offsetX;
const int py = mPy - offsetY;
+#endif
const int speech = (int) config.getValue("speech", NAME_IN_BUBBLE);
// Draw speech above this being
@@ -512,6 +834,63 @@ Being::Type Being::getType() const
return UNKNOWN;
}
+void Being::setStatusEffectBlock(int offset, Uint16 newEffects)
+{
+ for (int i = 0; i < STATUS_EFFECTS; i++) {
+ int index = StatusEffect::blockEffectIndexToEffectIndex(offset + i);
+
+ if (index != -1)
+ setStatusEffect(index, (newEffects & (1 << i)) > 0);
+ }
+}
+
+void Being::handleStatusEffect(StatusEffect *effect, int effectId)
+{
+ if (!effect)
+ return;
+
+ // TODO: Find out how this is meant to be used
+ // (SpriteAction != Being::Action)
+ //SpriteAction action = effect->getAction();
+ //if (action != ACTION_INVALID)
+ // setAction(action);
+
+ Particle *particle = effect->getParticle();
+
+ if (effectId >= 0)
+ mStatusParticleEffects.setLocally(effectId, particle);
+ else {
+ mStunParticleEffects.clearLocally();
+ if (particle)
+ mStunParticleEffects.addLocally(particle);
+ }
+}
+
+void Being::updateStunMode(int oldMode, int newMode)
+{
+ handleStatusEffect(StatusEffect::getStatusEffect(oldMode, false), -1);
+ handleStatusEffect(StatusEffect::getStatusEffect(newMode, true), -1);
+}
+
+void Being::updateStatusEffect(int index, bool newStatus)
+{
+ handleStatusEffect(StatusEffect::getStatusEffect(index, newStatus), index);
+}
+
+void Being::setStatusEffect(int index, bool active)
+{
+ const bool wasActive = mStatusEffects.find(index) != mStatusEffects.end();
+
+ if (active != wasActive) {
+ updateStatusEffect(index, active);
+ if (active)
+ mStatusEffects.insert(index);
+ else
+ mStatusEffects.erase(index);
+ }
+}
+
+#ifdef EATHENA_SUPPORT
int Being::getOffset(char pos, char neg) const
{
// Check whether we're walking in the requested direction
@@ -531,6 +910,7 @@ int Being::getOffset(char pos, char neg) const
return offset;
}
+#endif
int Being::getWidth() const
{
@@ -554,6 +934,114 @@ void Being::setTargetAnimation(SimpleAnimation* animation)
mUsedTargetCursor->reset();
}
+struct EffectDescription {
+ std::string mGFXEffect;
+ std::string mSFXEffect;
+};
+
+static EffectDescription *default_effect = NULL;
+static std::map<int, EffectDescription *> effects;
+static bool effects_initialized = false;
+
+static EffectDescription *getEffectDescription(xmlNodePtr node, int *id)
+{
+ EffectDescription *ed = new EffectDescription;
+
+ *id = atoi(XML::getProperty(node, "id", "-1").c_str());
+ ed->mSFXEffect = XML::getProperty(node, "audio", "");
+ ed->mGFXEffect = XML::getProperty(node, "particle", "");
+
+ return ed;
+}
+
+static EffectDescription *getEffectDescription(int effectId)
+{
+ if (!effects_initialized)
+ {
+ XML::Document doc(BEING_EFFECTS_FILE);
+ xmlNodePtr root = doc.rootNode();
+
+ if (!root || !xmlStrEqual(root->name, BAD_CAST "being-effects"))
+ {
+ logger->log("Error loading being effects file: "
+ BEING_EFFECTS_FILE);
+ return NULL;
+ }
+
+ for_each_xml_child_node(node, root)
+ {
+ int id;
+
+ if (xmlStrEqual(node->name, BAD_CAST "effect"))
+ {
+ EffectDescription *EffectDescription =
+ getEffectDescription(node, &id);
+ effects[id] = EffectDescription;
+ } else if (xmlStrEqual(node->name, BAD_CAST "default"))
+ {
+ EffectDescription *EffectDescription =
+ getEffectDescription(node, &id);
+
+ if (default_effect)
+ delete default_effect;
+
+ default_effect = EffectDescription;
+ }
+ }
+
+ effects_initialized = true;
+ } // done initializing
+
+ EffectDescription *ed = effects[effectId];
+
+ if (!ed)
+ return default_effect;
+ else
+ return ed;
+}
+
+void Being::internalTriggerEffect(int effectId, bool sfx, bool gfx)
+{
+ logger->log("Special effect #%d on %s", effectId,
+ getId() == player_node->getId() ? "self" : "other");
+
+ EffectDescription *ed = getEffectDescription(effectId);
+
+ if (!ed) {
+ logger->log("Unknown special effect and no default recorded");
+ return;
+ }
+
+ if (gfx && !ed->mGFXEffect.empty()) {
+ Particle *selfFX;
+
+ selfFX = particleEngine->addEffect(ed->mGFXEffect, 0, 0);
+ controlParticle(selfFX);
+ }
+
+ if (sfx && !ed->mSFXEffect.empty()) {
+ sound.playSfx(ed->mSFXEffect);
+ }
+}
+
+int Being::getHairStyleCount()
+{
+ return mNumberOfHairstyles;
+}
+
+int Being::getHairColorCount()
+{
+ return mNumberOfHairColors;
+}
+
+std::string Being::getHairColor(int index)
+{
+ if (index < 0 || index >= mNumberOfHairColors)
+ return "#000000";
+
+ return hairColors[index];
+}
+
void Being::load()
{
// Hairstyles are encoded as negative numbers. Count how far negative
@@ -564,5 +1052,32 @@ void Being::load()
hairstyles++;
mNumberOfHairstyles = hairstyles;
-}
+ XML::Document doc(HAIR_FILE);
+ xmlNodePtr root = doc.rootNode();
+
+ // Add an initial hair color
+ hairColors.resize(1, "#000000");
+
+ if (!root || !xmlStrEqual(root->name, BAD_CAST "colors"))
+ {
+ logger->log("Error loading being hair configuration file");
+ } else {
+ for_each_xml_child_node(node, root)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "color"))
+ {
+ int index = atoi(XML::getProperty(node, "id", "-1").c_str());
+ std::string value = XML::getProperty(node, "value", "");
+
+ if (index >= 0 && !value.empty()) {
+ if (index >= mNumberOfHairColors) {
+ mNumberOfHairColors = index + 1;
+ hairColors.resize(mNumberOfHairColors, "#000000");
+ }
+ hairColors[index] = value;
+ }
+ }
+ }
+ }
+}
diff --git a/src/being.h b/src/being.h
index 689eda02..158f2f72 100644
--- a/src/being.h
+++ b/src/being.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,13 +26,15 @@
#include <SDL_types.h>
+#include <set>
#include <string>
#include <vector>
-#include <bitset>
+#include "map.h"
#include "particlecontainer.h"
#include "position.h"
#include "sprite.h"
+#include "vector.h"
#include "resources/spritedef.h"
@@ -55,6 +56,8 @@ class SimpleAnimation;
class SpeechBubble;
class Text;
+class StatusEffect;
+
typedef std::list<Sprite*> Sprites;
typedef Sprites::iterator SpriteIterator;
@@ -77,7 +80,9 @@ class Being : public Sprite
};
/**
- * Action the being is currently performing.
+ * Action the being is currently performing
+ * WARNING: Has to be in sync with the same enum in the Being class
+ * of the server!
*/
enum Action
{
@@ -95,14 +100,20 @@ class Being : public Sprite
SHOE_SPRITE,
BOTTOMCLOTHES_SPRITE,
TOPCLOTHES_SPRITE,
+#ifdef EATHENA_SUPPORT
MISC1_SPRITE,
MISC2_SPRITE,
+#endif
HAIR_SPRITE,
HAT_SPRITE,
+#ifdef EATHENA_SUPPORT
CAPE_SPRITE,
GLOVES_SPRITE,
+#endif
WEAPON_SPRITE,
+#ifdef EATHENA_SUPPORT
SHIELD_SPRITE,
+#endif
VECTOREND_SPRITE
};
@@ -137,16 +148,18 @@ class Being : public Sprite
*/
enum { DOWN = 1, LEFT = 2, UP = 4, RIGHT = 8 };
- Uint16 mJob; /**< Job (player job, npc, monster, ) */
+#ifdef EATHENA_SUPPORT
Uint16 mX, mY; /**< Tile coordinates */
- Action mAction; /**< Action the being is performing */
int mFrame;
int mWalkTime;
+#endif
int mEmotion; /**< Currently showing emotion */
int mEmotionTime; /**< Time until emotion disappears */
int mSpeechTime;
int mAttackSpeed; /**< Attack speed */
+ Action mAction; /**< Action the being is performing */
+ Uint16 mJob; /**< Job (player job, npc, monster, creature ) */
/**
* Constructor.
@@ -166,7 +179,26 @@ class Being : public Sprite
/**
* Sets a new destination for this being to walk to.
*/
+#ifdef EATHENA_SUPPORT
virtual void setDestination(Uint16 destX, Uint16 destY);
+#else
+ void setDestination(int x, int y);
+
+ /**
+ * Returns the destination for this being.
+ */
+ const Vector &getDestination() const { return mDest; }
+
+ /**
+ * Adjusts course to expected start point.
+ */
+ void adjustCourse(int srcX, int srcY);
+
+ /**
+ * Adjusts course to expected start and end points.
+ */
+ void adjustCourse(int srcX, int srcY, int destX, int destY);
+#endif
/**
* Puts a "speech balloon" above this being for the specified amount
@@ -193,19 +225,25 @@ class Being : public Sprite
* @param damage the amount of damage dealt (0 means miss)
* @param type the attack type
*/
+#ifdef TMWSERV_SUPPORT
+ virtual void handleAttack();
+#else
virtual void handleAttack(Being *victim, int damage, AttackType type);
+#endif
/**
* Returns the name of the being.
*/
- const std::string& getName() const { return mName; }
+ const std::string &getName() const
+ { return mName; }
/**
* Sets the name for the being.
*
* @param name The name that should appear.
*/
- virtual void setName(const std::string &name) { mName = name; }
+ virtual void setName(const std::string &name)
+ { mName = name; }
/**
* Gets the hair color for this being.
@@ -230,7 +268,8 @@ class Being : public Sprite
/**
* Sets visible equipments for this being.
*/
- virtual void setSprite(int slot, int id, std::string color = "");
+ virtual void setSprite(int slot, int id,
+ const std::string &color = "");
/**
* Sets the gender of this being.
@@ -242,10 +281,12 @@ class Being : public Sprite
*/
Gender getGender() const { return mGender; }
+#ifdef EATHENA_SUPPORT
/**
* Makes this being take the next step of his path.
*/
virtual void nextStep();
+#endif
/**
* Triggers whether or not to show the name as a GM name.
@@ -277,16 +318,17 @@ class Being : public Sprite
/**
* Gets the walk speed.
+ * @see setWalkSpeed(int)
*/
- Uint16 getWalkSpeed() const { return mWalkSpeed; }
+ int getWalkSpeed() const { return mWalkSpeed; }
/**
- * Sets the walk speed.
+ * Sets the walk speed (in pixels per second).
*/
- void setWalkSpeed(Uint16 speed) { mWalkSpeed = speed; }
+ void setWalkSpeed(int speed) { mWalkSpeed = speed; }
/**
- * Gets the sprite id.
+ * Gets the being id.
*/
int getId() const { return mId; }
@@ -303,7 +345,12 @@ class Being : public Sprite
/**
* Sets the current action.
*/
- virtual void setAction(Action action);
+ virtual void setAction(Action action, int attackType = 0);
+
+ /**
+ * Gets the current action.
+ */
+ bool isAlive() { return mAction != DEAD; }
/**
* Returns the current direction.
@@ -315,15 +362,22 @@ class Being : public Sprite
*/
void setDirection(Uint8 direction);
+#ifdef EATHENA_SUPPORT
/**
* Gets the current action.
*/
int getWalkTime() { return mWalkTime; }
+#endif
/**
* Returns the direction the being is facing.
*/
+#ifdef TMWSERV_SUPPORT
+ SpriteDirection getSpriteDirection() const
+ { return SpriteDirection(mSpriteDirection); }
+#else
SpriteDirection getSpriteDirection() const;
+#endif
/**
* Draws this being to the given graphics context.
@@ -335,32 +389,66 @@ class Being : public Sprite
/**
* Returns the pixel X coordinate.
*/
+#ifdef TMWSERV_SUPPORT
+ int getPixelX() const { return (int) mPos.x; }
+#else
int getPixelX() const { return mPx; }
+#endif
/**
* Returns the pixel Y coordinate.
*
* @see Sprite::getPixelY()
*/
+#ifdef TMWSERV_SUPPORT
+ int getPixelY() const { return (int) mPos.y; }
+#else
int getPixelY() const { return mPy; }
+#endif
+#ifdef EATHENA_SUPPORT
/**
* Get the current X pixel offset.
*/
- int getXOffset() const { return getOffset(LEFT, RIGHT); }
+ int getXOffset() const
+ { return getOffset(LEFT, RIGHT); }
/**
* Get the current Y pixel offset.
*/
- int getYOffset() const { return getOffset(UP, DOWN); }
+ int getYOffset() const
+ { return getOffset(UP, DOWN); }
+#endif
+
+ /**
+ * Sets the position of this being. When the being was walking, it also
+ * clears the destination and the path.
+ */
+ void setPosition(const Vector &pos);
+
+ /**
+ * Overloaded method provided for convenience.
+ *
+ * @see setPosition(const Vector &pos)
+ */
+ void setPosition(float x, float y, float z = 0.0f)
+ {
+ setPosition(Vector(x, y, z));
+ }
/**
- * Returns the horizontal size of the current base sprite of the being
+ * Returns the position of this being.
+ */
+ const Vector &getPosition() const { return mPos; }
+
+
+ /**
+ * Returns the horizontal size of the current base sprite of the being.
*/
virtual int getWidth() const;
/**
- * Returns the vertical size of the current base sprite of the being
+ * Returns the vertical size of the current base sprite of the being.
*/
virtual int getHeight() const;
@@ -376,6 +464,18 @@ class Being : public Sprite
void controlParticle(Particle *particle);
/**
+ * Gets the way the object is blocked by other objects.
+ */
+ virtual unsigned char getWalkMask() const
+ { return 0x00; } //can walk through everything
+
+ /**
+ * Returns the path this being is following. An empty path is returned
+ * when this being isn't following any path currently.
+ */
+ const Path &getPath() const { return mPath; }
+
+ /**
* Sets the target animation for this being.
*/
void setTargetAnimation(SimpleAnimation* animation);
@@ -391,6 +491,48 @@ class Being : public Sprite
mEmotionTime = emote_time;
}
+ /**
+ * Sets the being's stun mode. If zero, the being is `normal',
+ * otherwise it is `stunned' in some fashion.
+ */
+ void setStunMode(int stunMode)
+ {
+ if (mStunMode != stunMode)
+ updateStunMode(mStunMode, stunMode);
+ mStunMode = stunMode;
+ };
+
+ void setStatusEffect(int index, bool active);
+
+ /**
+ * A status effect block is a 16 bit mask of status effects.
+ * We assign each such flag a block ID of offset + bitnr.
+ *
+ * These are NOT the same as the status effect indices.
+ */
+ void setStatusEffectBlock(int offset, Uint16 flags);
+
+ /**
+ * Triggers a visual effect, such as `level up'
+ *
+ * Only draws the visual effect, does not play sound effects
+ *
+ * \param effectId ID of the effect to trigger
+ */
+ virtual void triggerEffect(int effectId)
+ {
+ internalTriggerEffect(effectId, false, true);
+ }
+
+ // Target cursor being used by the being
+ Image *mTargetCursor;
+
+ static int getHairColorCount();
+
+ static int getHairStyleCount();
+
+ static std::string getHairColor(int index);
+
virtual AnimatedSprite* getSprite(int index) const
{ return mSprites[index]; }
@@ -407,9 +549,46 @@ class Being : public Sprite
*/
virtual void updateCoords() {}
+ /**
+ * Gets the way the object blocks pathfinding for other objects
+ */
+ virtual Map::BlockType getBlockType() const
+ { return Map::BLOCKTYPE_NONE; }
+
+ /**
+ * Trigger visual effect, with components
+ *
+ * \param effectId ID of the effect to trigger
+ * \param sfx Whether to trigger sound effects
+ * \param gfx Whether to trigger graphical effects
+ */
+ void internalTriggerEffect(int effectId, bool sfx, bool gfx);
+
+ /**
+ * Notify self that the stun mode has been updated. Invoked by
+ * setStunMode if something changed.
+ */
+ virtual void updateStunMode(int oldMode, int newMode);
+
+ /**
+ * Notify self that a status effect has flipped.
+ * The new flag is passed.
+ */
+ virtual void updateStatusEffect(int index, bool newStatus);
+
+ /**
+ * Handle an update to a status or stun effect
+ *
+ * \param The StatusEffect to effect
+ * \param effectId -1 for stun, otherwise the effect index
+ */
+ virtual void handleStatusEffect(StatusEffect *effect, int effectId);
+
int mId; /**< Unique sprite id */
- Uint16 mWalkSpeed; /**< Walking speed */
Uint8 mDirection; /**< Facing direction */
+#ifdef TMWSERV_SUPPORT
+ Uint8 mSpriteDirection; /**< Facing direction */
+#endif
Map *mMap; /**< Map on which this being resides */
std::string mName; /**< Name of character */
SpriteIterator mSpriteIterator;
@@ -417,34 +596,51 @@ class Being : public Sprite
bool mParticleEffects; /**< Whether to display particles or not */
/** Engine-related infos about weapon. */
- const ItemInfo* mEquippedWeapon;
+ const ItemInfo *mEquippedWeapon;
- static int mNumberOfHairstyles; /** Number of hair styles in use */
+ static std::vector<std::string> hairColors;
+ static int mNumberOfHairColors; /** Number of hair colors in use */
+ static int mNumberOfHairstyles; /** Number of hair styles in use */
Path mPath;
std::string mSpeech;
Text *mText;
- Uint16 mHairStyle, mHairColor;
+ int mHairStyle;
+ int mHairColor;
Gender mGender;
int mPx, mPy; /**< Pixel coordinates */
+ Uint16 mStunMode; /**< Stun mode; zero if not stunned */
+ std::set<int> mStatusEffects; /**< set of active status effects */
const gcn::Color* mNameColor;
std::vector<AnimatedSprite*> mSprites;
std::vector<int> mSpriteIDs;
std::vector<std::string> mSpriteColors;
+ ParticleList mStunParticleEffects;
+ ParticleVector mStatusParticleEffects;
ParticleList mChildParticleEffects;
private:
+#ifdef EATHENA_SUPPORT
/**
* Calculates the offset in the given directions.
* If walking in direction 'neg' the value is negated.
*/
int getOffset(char pos, char neg) const;
+#endif
+
+ /** Reset particle status effects on next redraw? */
+ bool mMustResetParticles;
// Speech Bubble components
SpeechBubble *mSpeechBubble;
+ int mWalkSpeed; /**< Walking speed (pixels/sec) */
+
+ Vector mPos;
+ Vector mDest;
+
// Target cursor being used
SimpleAnimation* mUsedTargetCursor;
};
diff --git a/src/beingmanager.cpp b/src/beingmanager.cpp
index a3fb14ff..af968bdb 100644
--- a/src/beingmanager.cpp
+++ b/src/beingmanager.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,24 +20,37 @@
*/
#include "beingmanager.h"
+
#include "localplayer.h"
#include "monster.h"
#include "npc.h"
#include "player.h"
+#ifdef EATHENA_SUPPORT
#include "net/messageout.h"
-#include "net/protocol.h"
+#include "net/ea/protocol.h"
+#else
+#include "net/tmwserv/protocol.h"
+#endif
#include "utils/dtor.h"
+#include <cassert>
+
class FindBeingFunctor
{
public:
bool operator() (Being *being)
{
Uint16 other_y = y + ((being->getType() == Being::NPC) ? 1 : 0);
+#ifdef TMWSERV_SUPPORT
+ const Vector &pos = being->getPosition();
+ return ((int) pos.x / 32 == x &&
+ ((int) pos.y / 32 == y || (int) pos.y / 32 == other_y) &&
+#else
return (being->mX == x &&
(being->mY == y || being->mY == other_y) &&
+#endif
being->mAction != Being::DEAD &&
(type == Being::UNKNOWN || being->getType() == type));
}
@@ -47,10 +59,12 @@ class FindBeingFunctor
Being::Type type;
} beingFinder;
+#ifdef EATHENA_SUPPORT
BeingManager::BeingManager(Network *network):
mNetwork(network)
{
}
+#endif
BeingManager::~BeingManager()
{
@@ -70,10 +84,30 @@ void BeingManager::setPlayer(LocalPlayer *player)
mBeings.push_back(player);
}
+#ifdef TMWSERV_SUPPORT
+Being *BeingManager::createBeing(int id, int type, int subtype)
+#else
Being *BeingManager::createBeing(int id, Uint16 job)
+#endif
{
Being *being;
+#ifdef TMWSERV_SUPPORT
+ switch (type)
+ {
+ case OBJECT_PLAYER:
+ being = new Player(id, subtype, mMap);
+ break;
+ case OBJECT_NPC:
+ being = new NPC(id, subtype, mMap);
+ break;
+ case OBJECT_MONSTER:
+ being = new Monster(id, subtype, mMap);
+ break;
+ default:
+ assert(false);
+ }
+#else
if (job <= 25 || (job >= 4001 && job <= 4049))
being = new Player(id, job, mMap);
else if (job >= 46 && job <= 1000)
@@ -90,15 +124,19 @@ Being *BeingManager::createBeing(int id, Uint16 job)
outMsg.writeInt16(0x0094);
outMsg.writeInt32(id);//readLong(2));
}
+#endif
mBeings.push_back(being);
-
return being;
}
void BeingManager::destroyBeing(Being *being)
{
mBeings.remove(being);
+#ifdef TMWSERV_SUPPORT
+ if(being == player_node->getTarget())
+ player_node->setTarget(NULL);
+#endif
delete being;
}
@@ -133,15 +171,15 @@ Being *BeingManager::findBeingByPixel(int x, int y)
{
Being *being = (*itr);
- int xtol = being->getWidth();
- int uptol = being->getHeight() / 2;
+ int xtol = being->getWidth() / 2;
+ int uptol = being->getHeight();
if ((being->mAction != Being::DEAD) &&
(being != player_node) &&
- (being->getPixelX() <= x) &&
+ (being->getPixelX() - xtol <= x) &&
(being->getPixelX() + xtol >= x) &&
(being->getPixelY() - uptol <= y) &&
- (being->getPixelY() + uptol >= y))
+ (being->getPixelY() >= y))
{
return being;
}
@@ -176,12 +214,14 @@ void BeingManager::logic()
being->logic();
+#ifdef EATHENA_SUPPORT
if (being->mAction == Being::DEAD && being->mFrame >= 20)
{
delete being;
i = mBeings.erase(i);
}
else
+#endif
{
i++;
}
@@ -206,13 +246,30 @@ Being *BeingManager::findNearestLivingBeing(int x, int y, int maxdist,
Being *closestBeing = NULL;
int dist = 0;
+#ifdef TMWSERV_SUPPORT
+ //Why do we do this:
+ //For some reason x,y passed to this function is always
+ //in map coords, while down below its in pixels
+ //
+ //I believe there is a deeper problem under this, but
+ //for a temp solution we'll convert to coords to pixels
+ x = x * 32;
+ y = y * 32;
+ maxdist = maxdist * 32;
+#endif
+
BeingIterator itr = mBeings.begin();
BeingIterator itr_end = mBeings.end();
for (; itr != itr_end; ++itr)
{
Being *being = (*itr);
+#ifdef TMWSERV_SUPPORT
+ const Vector &pos = being->getPosition();
+ int d = abs(((int) pos.x) - x) + abs(((int) pos.y) - y);
+#else
int d = abs(being->mX - x) + abs(being->mY - y);
+#endif
if ((being->getType() == type || type == Being::UNKNOWN)
&& (d < dist || closestBeing == NULL) // it is closer
@@ -231,13 +288,25 @@ Being *BeingManager::findNearestLivingBeing(Being *aroundBeing, int maxdist,
{
Being *closestBeing = NULL;
int dist = 0;
+#ifdef TMWSERV_SUPPORT
+ const Vector &apos = aroundBeing->getPosition();
+ int x = apos.x;
+ int y = apos.y;
+ maxdist = maxdist * 32;
+#else
int x = aroundBeing->mX;
int y = aroundBeing->mY;
+#endif
for (BeingIterator i = mBeings.begin(); i != mBeings.end(); i++)
{
Being *being = (*i);
+#ifdef TMWSERV_SUPPORT
+ const Vector &pos = being->getPosition();
+ int d = abs(((int) pos.x) - x) + abs(((int) pos.y) - y);
+#else
int d = abs(being->mX - x) + abs(being->mY - y);
+#endif
if ((being->getType() == type || type == Being::UNKNOWN)
&& (d < dist || closestBeing == NULL) // it is closer
diff --git a/src/beingmanager.h b/src/beingmanager.h
index 3284ce16..05821bcf 100644
--- a/src/beingmanager.h
+++ b/src/beingmanager.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,7 +26,9 @@
class LocalPlayer;
class Map;
+#ifdef EATHENA_SUPPORT
class Network;
+#endif
typedef std::list<Being*> Beings;
typedef Beings::iterator BeingIterator;
@@ -35,7 +36,9 @@ typedef Beings::iterator BeingIterator;
class BeingManager
{
public:
+#ifdef EATHENA_SUPPORT
BeingManager(Network *network);
+#endif
~BeingManager();
@@ -52,7 +55,11 @@ class BeingManager
/**
* Create a being and add it to the list of beings.
*/
+#ifdef TMWSERV_SUPPORT
+ Being *createBeing(int id, int type, int subtype);
+#else
Being *createBeing(int id, Uint16 job);
+#endif
/**
* Remove a Being.
@@ -60,25 +67,25 @@ class BeingManager
void destroyBeing(Being *being);
/**
- * Return a specific id Being.
+ * Returns a specific id Being.
*/
Being *findBeing(int id);
- Being *findBeingByPixel(int x, int y);
/**
* Returns a being at specific coordinates.
*/
Being *findBeing(int x, int y, Being::Type type = Being::UNKNOWN);
+ Being *findBeingByPixel(int x, int y);
- /**
- * Returns a being nearest to specific coordinates.
- *
- * @param x X coordinate.
- * @param y Y coordinate.
- * @param maxdist Maximal distance. If minimal distance is larger,
- * no being is returned.
- * @param type The type of being to look for.
- */
+ /**
+ * Returns a being nearest to specific coordinates.
+ *
+ * @param x X coordinate.
+ * @param y Y coordinate.
+ * @param maxdist Maximal distance. If minimal distance is larger,
+ * no being is returned.
+ * @param type The type of being to look for.
+ */
Being *findNearestLivingBeing(int x, int y, int maxdist,
Being::Type type = Being::UNKNOWN);
@@ -122,7 +129,9 @@ class BeingManager
protected:
Beings mBeings;
Map *mMap;
+#ifdef EATHENA_SUPPORT
Network *mNetwork;
+#endif
};
extern BeingManager *beingManager;
diff --git a/src/channel.cpp b/src/channel.cpp
new file mode 100644
index 00000000..3e4646fb
--- /dev/null
+++ b/src/channel.cpp
@@ -0,0 +1,45 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "channel.h"
+
+#ifdef TMWSERV_SUPPORT
+#include "net/tmwserv/chatserver/chatserver.h"
+#include "net/tmwserv/gameserver/player.h"
+#else
+#include "net/messageout.h"
+#include "net/ea/protocol.h"
+#endif
+
+Channel::Channel(short id,
+ const std::string &name,
+ const std::string &announcement) :
+ mId(id),
+ mName(name),
+ mAnnouncement(announcement),
+ mTab(new ChannelTab(this))
+{
+}
+
+Channel::~Channel()
+{
+ delete mTab;
+}
diff --git a/src/channel.h b/src/channel.h
new file mode 100644
index 00000000..b2080d4a
--- /dev/null
+++ b/src/channel.h
@@ -0,0 +1,87 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef CHANNEL_H
+#define CHANNEL_H
+
+#include <string>
+
+#include "gui/widgets/channeltab.h"
+
+class Channel
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @param id the id associated with the channel.
+ * @param name the name of the channel.
+ * @param announcement a welcome message.
+ */
+ Channel(short id,
+ const std::string &name,
+ const std::string &announcement = std::string());
+
+ ~Channel();
+
+ /**
+ * Get the id associated witht his channel
+ */
+ int getId() const { return mId; }
+
+ /**
+ * Get this channel's name
+ */
+ const std::string &getName() const
+ { return mName; }
+
+ /**
+ * Get the announcement message for this channel
+ */
+ const std::string &getAnnouncement() const
+ { return mAnnouncement; }
+
+ /**
+ * Sets the name of the channel.
+ */
+ void setName(const std::string &channelName)
+ { mName = channelName; }
+
+ /**
+ * Sets the announcement string of the channel.
+ */
+ void setAnnouncement(const std::string &channelAnnouncement)
+ { mAnnouncement = channelAnnouncement; }
+
+ ChannelTab *getTab() { return mTab; }
+
+ protected:
+ friend class ChannelTab;
+ void setTab(ChannelTab *tab) { mTab = tab; }
+
+ private:
+ unsigned short mId;
+ std::string mName;
+ std::string mAnnouncement;
+ ChannelTab *mTab;
+};
+
+#endif // CHANNEL_H
diff --git a/src/channelmanager.cpp b/src/channelmanager.cpp
new file mode 100644
index 00000000..6868c283
--- /dev/null
+++ b/src/channelmanager.cpp
@@ -0,0 +1,85 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "channelmanager.h"
+#include "channel.h"
+
+#include "utils/dtor.h"
+
+ChannelManager::ChannelManager()
+{
+}
+
+ChannelManager::~ChannelManager()
+{
+ delete_all(mChannels);
+ mChannels.clear();
+}
+
+Channel *ChannelManager::findById(int id) const
+{
+ Channel *channel = 0;
+ for (std::list<Channel*>::const_iterator itr = mChannels.begin(),
+ end = mChannels.end();
+ itr != end;
+ itr++)
+ {
+ Channel *c = (*itr);
+ if (c->getId() == id)
+ {
+ channel = c;
+ break;
+ }
+ }
+ return channel;
+}
+
+Channel *ChannelManager::findByName(const std::string &name) const
+{
+ Channel *channel = 0;
+ if (!name.empty())
+ {
+ for (std::list<Channel*>::const_iterator itr = mChannels.begin(),
+ end = mChannels.end();
+ itr != end;
+ itr++)
+ {
+ Channel *c = (*itr);
+ if (c->getName() == name)
+ {
+ channel = c;
+ break;
+ }
+ }
+ }
+ return channel;
+}
+
+void ChannelManager::addChannel(Channel *channel)
+{
+ mChannels.push_back(channel);
+}
+
+void ChannelManager::removeChannel(Channel *channel)
+{
+ mChannels.remove(channel);
+ delete channel;
+}
diff --git a/src/channelmanager.h b/src/channelmanager.h
new file mode 100644
index 00000000..9b425159
--- /dev/null
+++ b/src/channelmanager.h
@@ -0,0 +1,48 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef CHANNELMANAGER_H
+#define CHANNELMANAGER_H
+
+#include <list>
+#include <string>
+
+class Channel;
+
+class ChannelManager
+{
+public:
+ ChannelManager();
+ ~ChannelManager();
+
+ Channel *findById(int id) const;
+ Channel *findByName(const std::string &name) const;
+
+ void addChannel(Channel *channel);
+ void removeChannel(Channel *channel);
+
+private:
+ std::list<Channel*> mChannels;
+};
+
+extern ChannelManager *channelManager;
+
+#endif
diff --git a/src/commandhandler.cpp b/src/commandhandler.cpp
new file mode 100644
index 00000000..f875fd85
--- /dev/null
+++ b/src/commandhandler.cpp
@@ -0,0 +1,593 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "commandhandler.h"
+#include "channelmanager.h"
+#include "channel.h"
+#include "game.h"
+#include "localplayer.h"
+
+#include "gui/widgets/channeltab.h"
+#include "gui/widgets/chattab.h"
+#include "gui/chat.h"
+
+#ifdef TMWSERV_SUPPORT
+#include "net/tmwserv/chatserver/chatserver.h"
+#include "net/tmwserv/gameserver/player.h"
+#else
+#include "party.h"
+#include "net/messageout.h"
+#include "net/ea/protocol.h"
+#endif
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+#include "utils/strprintf.h"
+
+#ifdef TMWSERV_SUPPORT
+CommandHandler::CommandHandler()
+#else
+CommandHandler::CommandHandler(Network *network):
+ mNetwork(network)
+#endif
+{}
+
+void CommandHandler::handleCommand(const std::string &command)
+{
+ std::string::size_type pos = command.find(' ');
+ std::string type(command, 0, pos);
+ std::string args(command, pos == std::string::npos ? command.size() : pos + 1);
+
+ if (type == "announce")
+ {
+ handleAnnounce(args);
+ }
+ else if (type == "help")
+ {
+ handleHelp(args);
+ }
+ else if (type == "where")
+ {
+ handleWhere();
+ }
+ else if (type == "who")
+ {
+ handleWho();
+ }
+ else if (type == "msg" || type == "whisper" || type == "w")
+ {
+ handleMsg(args);
+ }
+#ifdef TMWSERV_SUPPORT
+ else if (type == "join")
+ {
+ handleJoin(args);
+ }
+ else if (type == "list")
+ {
+ handleListChannels();
+ }
+ else if (type == "users")
+ {
+ handleListUsers();
+ }
+ else if (type == "quit")
+ {
+ handleQuit();
+ }
+ else if (type == "topic")
+ {
+ handleTopic(args);
+ }
+ else if (type == "clear")
+ {
+ handleClear();
+ }
+ else if (type == "op")
+ {
+ handleOp(args);
+ }
+ else if (type == "kick")
+ {
+ handleKick(args);
+ }
+#endif
+ else if (type == "party")
+ {
+ handleParty(args);
+ }
+ else if (type == "me")
+ {
+ handleMe(args);
+ }
+ else if (type == "record")
+ {
+ handleRecord(args);
+ }
+ else if (type == "toggle")
+ {
+ handleToggle(args);
+ }
+ else if (type == "present")
+ {
+ handlePresent(args);
+ }
+ else
+ {
+ localChatTab->chatLog("Unknown command");
+ }
+}
+
+void CommandHandler::handleAnnounce(const std::string &args)
+{
+#ifdef TMWSERV_SUPPORT
+ Net::ChatServer::announce(args);
+#else
+ MessageOut outMsg(mNetwork);
+ outMsg.writeInt16(0x0099);
+ outMsg.writeInt16(args.length() + 4);
+ outMsg.writeString(args, args.length());
+#endif
+}
+
+void CommandHandler::handleHelp(const std::string &args)
+{
+ if (args == "")
+ {
+ localChatTab->chatLog(_("-- Help --"));
+ localChatTab->chatLog(_("/help > Display this help."));
+
+ localChatTab->chatLog(_("/where > Display map name"));
+ localChatTab->chatLog(_("/who > Display number of online users"));
+ localChatTab->chatLog(_("/me > Tell something about yourself"));
+
+ localChatTab->chatLog(_("/msg > Send a private message to a user"));
+ localChatTab->chatLog(_("/whisper > Alias of msg"));
+ localChatTab->chatLog(_("/w > Alias of msg"));
+
+#ifdef TMWSERV_SUPPORT
+ localChatTab->chatLog(_("/list > Display all public channels"));
+ localChatTab->chatLog(_("/users > Lists the users in the current channel"));
+ localChatTab->chatLog(_("/join > Join or create a channel"));
+ localChatTab->chatLog(_("/topic > Set the topic of the current channel"));
+ localChatTab->chatLog(_("/quit > Leave a channel"));
+ localChatTab->chatLog(_("/clear > Clears this window"));
+ localChatTab->chatLog(_("/op > Make a user a channel operator"));
+ localChatTab->chatLog(_("/kick > Kick a user from the channel"));
+
+ localChatTab->chatLog(_("/party > Invite a user to party"));
+#else
+ localChatTab->chatLog(_("/party > Party-related commands"));
+#endif
+
+ localChatTab->chatLog(_("/record > Start recording the chat to an external file"));
+ localChatTab->chatLog(_("/toggle > Determine whether <return> toggles the chat log"));
+ localChatTab->chatLog(_("/present > Get list of players present (sent to chat log, if logging)"));
+
+ localChatTab->chatLog(_("/announce > Global announcement (GM only)"));
+
+ localChatTab->chatLog(_("For more information, type /help <command>"));
+ }
+ else if (args == "announce")
+ {
+ localChatTab->chatLog(_("Command: /announce <msg>"));
+ localChatTab->chatLog(_("*** only available to a GM ***"));
+ localChatTab->chatLog(_("This command sends the message <msg> to "
+ "all players currently online."));
+ }
+ else if (args == "clear")
+ {
+ localChatTab->chatLog(_("Command: /clear"));
+ localChatTab->chatLog(_("This command clears the chat log of previous chat."));
+ }
+ else if (args == "help")
+ {
+ localChatTab->chatLog(_("Command: /help"));
+ localChatTab->chatLog(_("This command displays a list of all commands available."));
+ localChatTab->chatLog(_("Command: /help <command>"));
+ localChatTab->chatLog(_("This command displays help on <command>."));
+ }
+ else if (args == "join")
+ {
+ localChatTab->chatLog(_("Command: /join <channel>"));
+ localChatTab->chatLog(_("This command makes you enter <channel>."));
+ localChatTab->chatLog(_("If <channel> doesn't exist, it's created."));
+ }
+ else if (args == "kick")
+ {
+ localChatTab->chatLog(_("Command: /kick <nick>"));
+ localChatTab->chatLog(_("This command makes <nick> leave the channel."));
+ localChatTab->chatLog(_("If the <nick> has spaces in it, enclose it in "
+ "double quotes (\")."));
+ }
+ else if (args == "list")
+ {
+ localChatTab->chatLog(_("Command: /list"));
+ localChatTab->chatLog(_("This command shows a list of all channels."));
+ }
+ else if (args == "me")
+ {
+ localChatTab->chatLog(_("Command: /me <message>"));
+ localChatTab->chatLog(_("This command tell others you are (doing) <msg>."));
+ }
+ else if (args == "msg" || args == "whisper" || args == "w")
+ {
+ localChatTab->chatLog(_("Command: /msg <nick> <message>"));
+ localChatTab->chatLog(_("Command: /whisper <nick> <message>"));
+ localChatTab->chatLog(_("Command: /w <nick> <message>"));
+ localChatTab->chatLog(_("This command sends the text <message> to <nick>."));
+ localChatTab->chatLog(_("If the <nick> has spaces in it, enclose it in "
+ "double quotes (\")."));
+ }
+ else if (args == "op")
+ {
+ localChatTab->chatLog(_("Command: /op <nick>"));
+ localChatTab->chatLog(_("This command makes <nick> a channel operator."));
+ localChatTab->chatLog(_("If the <nick> has spaces in it, enclose it in "
+ "double quotes (\")."));
+ localChatTab->chatLog(_("Channel operators can kick and op other users "
+ "from the channel."));
+ }
+#ifdef TMWSERV_SUPPORT
+ else if (args == "party")
+ {
+ localChatTab->chatLog(_("Command: /party <nick>"));
+ localChatTab->chatLog(_("This command invites <nick> to party with you."));
+ localChatTab->chatLog(_("If the <nick> has spaces in it, enclose it in "
+ "double quotes (\")."));
+#else
+ else if (args.substr(0, 5) == "party")
+ {
+ playerParty->help(args);
+#endif
+ }
+ else if (args == "present")
+ {
+ localChatTab->chatLog(_("Command: /present"));
+ localChatTab->chatLog(_("This command gets a list of players within hearing and "
+ "sends it to either the record log if recording, or the chat "
+ "log otherwise."));
+ }
+ else if (args == "quit")
+ {
+ localChatTab->chatLog(_("Command: /quit"));
+ localChatTab->chatLog(_("This command leaves the current channel."));
+ localChatTab->chatLog(_("If you're the last person in the channel, it will be deleted."));
+ }
+ else if (args == "record")
+ {
+ localChatTab->chatLog(_("Command: /record <filename>"));
+ localChatTab->chatLog(_("This command starts recording the chat log to the file "
+ "<filename>."));
+ localChatTab->chatLog(_("Command: /record"));
+ localChatTab->chatLog(_("This command finishes a recording session."));
+ }
+ else if (args == "toggle")
+ {
+ localChatTab->chatLog(_("Command: /toggle <state>"));
+ localChatTab->chatLog(_("This command sets whether the return key should toggle the "
+ "chat log, or whether the chat log turns off automatically."));
+ localChatTab->chatLog(_("<state> can be one of \"1\", \"yes\", \"true\" to "
+ "turn the toggle on, or \"0\", \"no\", \"false\" to turn the "
+ "toggle off."));
+ localChatTab->chatLog(_("Command: /toggle"));
+ localChatTab->chatLog(_("This command displays the return toggle status."));
+ }
+ else if (args == "topic")
+ {
+ localChatTab->chatLog(_("Command: /topic <message>"));
+ localChatTab->chatLog(_("This command sets the topic to <message>."));
+ }
+ else if (args == "users")
+ {
+ localChatTab->chatLog(_("Command: /users <channel>"));
+ localChatTab->chatLog(_("This command shows the users in <channel>."));
+ }
+ else if (args == "where")
+ {
+ localChatTab->chatLog(_("Command: /where"));
+ localChatTab->chatLog(_("This command displays the name of the current map."));
+ }
+ else if (args == "who")
+ {
+ localChatTab->chatLog(_("Command: /who"));
+ localChatTab->chatLog(_("This command displays the number of players currently "
+ "online."));
+ }
+ else
+ {
+ localChatTab->chatLog(_("Unknown command."));
+ localChatTab->chatLog(_("Type /help for a list of commands."));
+ }
+}
+
+void CommandHandler::handleWhere()
+{
+ // TODO: add position
+ localChatTab->chatLog(map_path, BY_SERVER);
+}
+
+void CommandHandler::handleWho()
+{
+#ifdef TMWSERV_SUPPORT
+ //TODO
+#else
+ MessageOut outMsg(mNetwork);
+ outMsg.writeInt16(0x00c1);
+#endif
+}
+
+void CommandHandler::handleMsg(const std::string &args)
+{
+#ifdef TMWSERV_SUPPORT
+ std::string::size_type pos = args.find(' ');
+ std::string recipient(args, 0, pos);
+ std::string text(args, pos+1);
+ Net::ChatServer::privMsg(recipient, text);
+#else
+ std::string recvnick = "";
+ std::string msg = "";
+
+ if (args.substr(0, 1) == "\"")
+ {
+ const std::string::size_type pos = args.find('"', 1);
+ if (pos != std::string::npos)
+ {
+ recvnick = args.substr(1, pos - 1);
+ msg = args.substr(pos + 2, args.length());
+ }
+ }
+ else
+ {
+ const std::string::size_type pos = args.find(" ");
+ if (pos != std::string::npos)
+ {
+ recvnick = args.substr(0, pos);
+ msg = args.substr(pos + 1, args.length());
+ }
+ else
+ {
+ recvnick = std::string(args);
+ msg = "";
+ }
+ }
+
+ trim(msg);
+
+ if (msg.length() > 0)
+ {
+ std::string playerName = player_node->getName();
+ std::string tempNick = recvnick;
+
+ toLower(playerName);
+ toLower(tempNick);
+
+ if (tempNick.compare(playerName) == 0 || args.empty())
+ return;
+
+ chatWindow->whisper(recvnick, msg, true);
+ }
+ else
+ localChatTab->chatLog("Cannont send empty whispers!");
+#endif
+}
+
+void CommandHandler::handleClear()
+{
+ chatWindow->clearTab();
+}
+
+#ifdef TMWSERV_SUPPORT
+
+void CommandHandler::handleJoin(const std::string &args)
+{
+ std::string::size_type pos = args.find(' ');
+ std::string name(args, 0, pos);
+ std::string password(args, pos+1);
+ localChatTab->chatLog("Requesting to join channel " + name);
+ Net::ChatServer::enterChannel(name, password);
+}
+
+void CommandHandler::handleListChannels()
+{
+ Net::ChatServer::getChannelList();
+}
+
+void CommandHandler::handleListUsers()
+{
+ Net::ChatServer::getUserList(chatWindow->getFocused()->getCaption());
+}
+
+void CommandHandler::handleTopic(const std::string &args)
+{
+ ChannelTab *tab = dynamic_cast<ChannelTab*>(chatWindow->getFocused());
+ Channel *channel = tab ? tab->getChannel() : NULL;
+ if (channel)
+ {
+ Net::ChatServer::setChannelTopic(channel->getId(), args);
+ }
+ else
+ {
+ localChatTab->chatLog("Unable to set this channel's topic", BY_CHANNEL);
+ }
+}
+
+void CommandHandler::handleQuit()
+{
+ ChannelTab *tab = dynamic_cast<ChannelTab*>(chatWindow->getFocused());
+ Channel *channel = tab ? tab->getChannel() : NULL;
+ if (channel)
+ {
+ Net::ChatServer::quitChannel(channel->getId());
+ }
+ else
+ {
+ localChatTab->chatLog("Unable to quit this channel", BY_CHANNEL);
+ }
+}
+
+void CommandHandler::handleOp(const std::string &args)
+{
+ ChannelTab *tab = dynamic_cast<ChannelTab*>(chatWindow->getFocused());
+ Channel *channel = tab ? tab->getChannel() : NULL;
+ if (channel)
+ {
+ // set the user mode 'o' to op a user
+ if (args != "")
+ {
+ Net::ChatServer::setUserMode(channel->getId(), args, 'o');
+ }
+ }
+ else
+ {
+ localChatTab->chatLog("Unable to set this user's mode", BY_CHANNEL);
+ }
+}
+
+void CommandHandler::handleKick(const std::string &args)
+{
+ ChannelTab *tab = dynamic_cast<ChannelTab*>(chatWindow->getFocused());
+ Channel *channel = tab ? tab->getChannel() : NULL;
+ if (channel)
+ {
+ if (args != "")
+ {
+ Net::ChatServer::kickUser(channel->getId(), args);
+ }
+ }
+ else
+ {
+ localChatTab->chatLog("Unable to kick user", BY_CHANNEL);
+ }
+}
+
+#endif
+
+void CommandHandler::handleParty(const std::string &args)
+{
+#ifdef TMWSERV_SUPPORT
+ if (args != "")
+ {
+ player_node->inviteToParty(args);
+ }
+#else
+ if (args.empty())
+ {
+ localChatTab->chatLog(_("Unknown party command... Type \"/help\" party for more "
+ "information."), BY_SERVER);
+ return;
+ }
+
+ const std::string::size_type space = args.find(" ");
+ std::string command;
+ std::string rest;
+
+ if (space == std::string::npos)
+ {
+ command = args;
+ }
+ else
+ {
+ command = args.substr(0, space);
+ rest = args.substr(space + 1, args.length());
+ }
+
+ if (command == "prefix")
+ {
+ if (rest.empty())
+ {
+ char temp[2] = ".";
+ *temp = chatWindow->getPartyPrefix();
+ localChatTab->chatLog(_("The current party prefix is ") + std::string(temp));
+ }
+ else if (rest.length() != 1)
+ {
+ localChatTab->chatLog(_("Party prefix must be one character long."));
+ }
+ else
+ {
+ if (rest == "/")
+ {
+ localChatTab->chatLog(_("Cannot use a '/' as the prefix."));
+ }
+ else
+ {
+ chatWindow->setPartyPrefix(rest.at(0));
+ localChatTab->chatLog(_("Changing prefix to ") + rest);
+ }
+ }
+ }
+ else
+ playerParty->respond(command, rest);
+#endif
+}
+
+void CommandHandler::handleMe(const std::string &args)
+{
+ std::string action = strprintf("*%s*", args.c_str());
+ chatWindow->chatSend(action);
+ //std::stringstream actionStr;
+ //actionStr << "*" << args << "*";
+ //chatWindow->chatSend(actionStr.str());
+}
+
+void CommandHandler::handleRecord(const std::string &args)
+{
+ chatWindow->setRecordingFile(args);
+}
+
+void CommandHandler::handleToggle(const std::string &args)
+{
+ if (args.empty())
+ {
+ localChatTab->chatLog(chatWindow->getReturnTogglesChat() ?
+ _("Return toggles chat.") : _("Message closes chat."));
+ return;
+ }
+
+ std::string opt = args.substr(0, 1);
+
+ if (opt == "1" ||
+ opt == "y" || opt == "Y" ||
+ opt == "t" || opt == "T")
+ {
+ localChatTab->chatLog(_("Return now toggles chat."));
+ chatWindow->setReturnTogglesChat(true);
+ return;
+ }
+ else if (opt == "0" ||
+ opt == "n" || opt == "N" ||
+ opt == "f" || opt == "F")
+ {
+ localChatTab->chatLog(_("Message now closes chat."));
+ chatWindow->setReturnTogglesChat(false);
+ return;
+ }
+ else
+ localChatTab->chatLog(_("Options to /toggle are \"yes\", \"no\", \"true\", "
+ "\"false\", \"1\", \"0\"."));
+}
+
+void CommandHandler::handlePresent(const std::string &args)
+{
+ chatWindow->doPresent();
+}
diff --git a/src/commandhandler.h b/src/commandhandler.h
new file mode 100644
index 00000000..2adf4e1b
--- /dev/null
+++ b/src/commandhandler.h
@@ -0,0 +1,154 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef COMMANDHANDLER_H
+#define COMMANDHANDLER_H
+
+#include <string>
+
+#ifdef EATHENA_SUPPORT
+class Network;
+#endif
+
+/**
+ * A class to parse and handle user commands
+ */
+class CommandHandler
+{
+ public:
+ /**
+ * Constructor
+ */
+#ifdef TMWSERV_SUPPORT
+ CommandHandler();
+#else
+ CommandHandler(Network *network);
+#endif
+
+ /**
+ * Destructor
+ */
+ ~CommandHandler() {}
+
+ /**
+ * Parse and handle the given command.
+ */
+ void handleCommand(const std::string &command);
+
+ private:
+ /**
+ * Handle an announce command.
+ */
+ void handleAnnounce(const std::string &args);
+
+ /**
+ * Handle a help command.
+ */
+ void handleHelp(const std::string &args);
+
+ /**
+ * Handle a where command.
+ */
+ void handleWhere();
+
+ /**
+ * Handle a who command.
+ */
+ void handleWho();
+
+ /**
+ * Handle a msg command.
+ */
+ void handleMsg(const std::string &args);
+
+ /**
+ * Handle a join command.
+ */
+ void handleJoin(const std::string &args);
+
+ /**
+ * Handle a listchannels command.
+ */
+ void handleListChannels();
+
+ /**
+ * Handle a listusers command.
+ */
+ void handleListUsers();
+
+ /**
+ * Handle a topic command.
+ */
+ void handleTopic(const std::string &args);
+
+ /**
+ * Handle a quit command.
+ */
+ void handleQuit();
+
+ /**
+ * Handle a clear command.
+ */
+ void handleClear();
+
+ /**
+ * Handle a party command.
+ */
+ void handleParty(const std::string &args);
+
+ /**
+ * Handle a op command.
+ */
+ void handleOp(const std::string &args);
+
+ /**
+ * Handle a kick command.
+ */
+ void handleKick(const std::string &args);
+
+ /**
+ * Handle a me command.
+ */
+ void handleMe(const std::string &args);
+
+ /**
+ * Handle a record command.
+ */
+ void handleRecord(const std::string &args);
+
+ /**
+ * Handle a toggle command.
+ */
+ void handleToggle(const std::string &args);
+
+ /**
+ * Handle a present command.
+ */
+ void handlePresent(const std::string &args);
+
+#ifdef EATHENA_SUPPORT
+ Network *mNetwork;
+#endif
+};
+
+extern CommandHandler *commandHandler;
+
+#endif // COMMANDHANDLER_H
diff --git a/src/configlistener.h b/src/configlistener.h
index edd9e90a..ec7d6a2c 100644
--- a/src/configlistener.h
+++ b/src/configlistener.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/configuration.cpp b/src/configuration.cpp
index 0df666ab..3c3ae1d5 100644
--- a/src/configuration.cpp
+++ b/src/configuration.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -57,7 +56,8 @@ void Configuration::setValue(const std::string &key, std::string value)
}
}
-std::string ConfigurationObject::getValue(const std::string &key, std::string deflt)
+std::string ConfigurationObject::getValue(const std::string &key,
+ std::string deflt)
{
OptionIterator iter = mOptions.find(key);
return ((iter != mOptions.end()) ? iter->second : deflt);
@@ -78,7 +78,7 @@ void ConfigurationObject::deleteList(const std::string &name)
mContainerOptions[name].clear();
}
-void ConfigurationObject::clear(void)
+void ConfigurationObject::clear()
{
for (std::map<std::string, ConfigurationList>::const_iterator
it = mContainerOptions.begin(); it != mContainerOptions.end(); it++)
@@ -86,7 +86,7 @@ void ConfigurationObject::clear(void)
mOptions.clear();
}
-ConfigurationObject::~ConfigurationObject(void)
+ConfigurationObject::~ConfigurationObject()
{
clear();
}
@@ -106,7 +106,7 @@ void ConfigurationObject::initFromXML(xmlNodePtr parent_node)
{
if (xmlStrEqual(subnode->name, BAD_CAST name.c_str())
&& subnode->type == XML_ELEMENT_NODE) {
- ConfigurationObject *cobj = new ConfigurationObject();
+ ConfigurationObject *cobj = new ConfigurationObject;
cobj->initFromXML(subnode); // recurse
diff --git a/src/configuration.h b/src/configuration.h
index 3e201dcb..0134f29a 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -73,7 +72,7 @@ class ConfigurationObject
friend class Configuration;
public:
- virtual ~ConfigurationObject(void);
+ virtual ~ConfigurationObject();
/**
* Sets an option using a string value.
@@ -110,7 +109,7 @@ class ConfigurationObject
/**
* Re-sets all data in the configuration
*/
- virtual void clear(void);
+ virtual void clear();
/**
* Serialises a container into a list of configuration options
@@ -127,7 +126,7 @@ class ConfigurationObject
template <class IT, class T, class CONT>
void setList(const std::string &name, IT begin, IT end, ConfigurationListManager<T, CONT> *manager)
{
- ConfigurationObject *nextobj = new ConfigurationObject();
+ ConfigurationObject *nextobj = new ConfigurationObject;
deleteList(name);
ConfigurationList *list = &(mContainerOptions[name]);
@@ -135,7 +134,7 @@ class ConfigurationObject
ConfigurationObject *wrobj = manager->writeConfigItem(*it, nextobj);
if (wrobj) { // wrote something
assert (wrobj == nextobj);
- nextobj = new ConfigurationObject();
+ nextobj = new ConfigurationObject;
list->push_back(wrobj);
} else
nextobj->clear(); // you never know...
@@ -160,7 +159,7 @@ class ConfigurationObject
{
ConfigurationList *list = &(mContainerOptions[name]);
CONT container = empty;
-
+
for (ConfigurationList::const_iterator it = list->begin(); it != list->end(); it++)
container = manager->readConfigItem(*it, container);
@@ -189,7 +188,7 @@ class ConfigurationObject
class Configuration : public ConfigurationObject
{
public:
- virtual ~Configuration(void) {}
+ virtual ~Configuration() {}
/**
* Reads config file and parse all options into memory.
@@ -216,6 +215,7 @@ class Configuration : public ConfigurationObject
virtual void setValue(const std::string &key, std::string value);
virtual void setValue(const std::string &key, float value);
+
private:
typedef std::list<ConfigListener*> Listeners;
typedef Listeners::iterator ListenerIterator;
@@ -226,6 +226,7 @@ class Configuration : public ConfigurationObject
std::string mConfigPath; /**< Location of config file */
};
+extern Configuration branding;
extern Configuration config;
#endif
diff --git a/src/effectmanager.cpp b/src/effectmanager.cpp
index 567e692b..d9234f66 100644
--- a/src/effectmanager.cpp
+++ b/src/effectmanager.cpp
@@ -3,8 +3,7 @@
* Copyright (C) 2008 Fate <fate.tmw@googlemail.com>
* Copyright (C) 2008 Chuck Miller <shadowmil@gmail.com>
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -46,8 +45,6 @@ EffectManager::EffectManager()
for_each_xml_child_node(node, root)
{
- //int id;
-
if (xmlStrEqual(node->name, BAD_CAST "effect"))
{
EffectDescription ed;
@@ -61,7 +58,6 @@ EffectManager::EffectManager()
EffectManager::~EffectManager()
{
-
}
bool EffectManager::trigger(int id, Being* being)
diff --git a/src/effectmanager.h b/src/effectmanager.h
index c69ade09..01c5a6b8 100644
--- a/src/effectmanager.h
+++ b/src/effectmanager.h
@@ -3,8 +3,7 @@
* Copyright (C) 2008 Fate <fate.tmw@googlemail.com>
* Copyright (C) 2008 Chuck Miller <shadowmil@gmail.com>
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/emoteshortcut.cpp b/src/emoteshortcut.cpp
index b229ec70..46e13782 100644
--- a/src/emoteshortcut.cpp
+++ b/src/emoteshortcut.cpp
@@ -2,8 +2,7 @@
* Extended support for activating emotes
* Copyright (C) 2009 Aethyra Development Team
*
- * This file is part of Aethyra derived from original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/emoteshortcut.h b/src/emoteshortcut.h
index 3fe911dd..ceb51a9b 100644
--- a/src/emoteshortcut.h
+++ b/src/emoteshortcut.h
@@ -2,8 +2,7 @@
* Extended support for activating emotes
* Copyright (C) 2009 Aethyra Development Team
*
- * This file is part of Aethyra derived from original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/engine.cpp b/src/engine.cpp
index 8ef2b9c6..da4eb336 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,17 +33,25 @@
#include "gui/minimap.h"
#include "gui/viewport.h"
+#ifdef EATHENA_SUPPORT
#include "net/messageout.h"
-#include "net/protocol.h"
+#include "net/ea/protocol.h"
+#endif
#include "resources/mapreader.h"
+#include "resources/monsterdb.h"
#include "resources/resourcemanager.h"
#include "utils/stringutils.h"
+#ifdef TMWSERV_SUPPORT
+Engine::Engine():
+ mCurrentMap(NULL)
+#else
Engine::Engine(Network *network):
mCurrentMap(NULL),
mNetwork(network)
+#endif
{
}
@@ -58,6 +65,7 @@ void Engine::changeMap(const std::string &mapPath)
// Clean up floor items, beings and particles
floorItemManager->clear();
beingManager->clear();
+ particleEngine->clear();
// Unset the map of the player so that its particles are cleared before
// being deleted in the next step
@@ -69,7 +77,11 @@ void Engine::changeMap(const std::string &mapPath)
mMapName = mapPath;
// Store full map path in global var
+#ifdef TMWSERV_SUPPORT
+ map_path = "maps/" + mapPath + ".tmx";
+#else
map_path = "maps/" + mapPath.substr(0, mapPath.rfind(".")) + ".tmx";
+#endif
ResourceManager *resman = ResourceManager::getInstance();
if (!resman->exists(map_path))
map_path += ".gz";
@@ -107,6 +119,12 @@ void Engine::changeMap(const std::string &mapPath)
else
minimap->setProportion(0.5);
}
+ if (newMap->hasProperty("name"))
+ {
+ minimap->setCaption(newMap->getProperty("name"));
+ } else {
+ minimap->setCaption("Map");
+ }
minimap->setMapImage(mapImage);
beingManager->setMap(newMap);
particleEngine->setMap(newMap);
@@ -131,15 +149,18 @@ void Engine::changeMap(const std::string &mapPath)
mCurrentMap = newMap;
+#ifdef EATHENA_SUPPORT
// Send "map loaded"
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_MAP_LOADED);
+#endif
}
void Engine::logic()
{
beingManager->logic();
particleEngine->update();
- mCurrentMap->update();
+ if (mCurrentMap)
+ mCurrentMap->update();
gui->logic();
}
diff --git a/src/engine.h b/src/engine.h
index e2fec2f6..60b1f6c8 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -2,8 +2,7 @@
* The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,7 +25,9 @@
#include <string>
class Map;
+#ifdef EATHENA_SUPPORT
class Network;
+#endif
/**
* Game engine. Actually hardly does anything anymore except keeping track of
@@ -38,7 +39,11 @@ class Engine
/**
* Constructor.
*/
+#ifdef EATHENA_SUPPORT
Engine(Network *network);
+#else
+ Engine();
+#endif
/**
* Destructor.
@@ -58,13 +63,15 @@ class Engine
void changeMap(const std::string &mapName);
/**
- * Performs engine logic.
+ * Performs engine logic. This method is called 100 times per second.
*/
void logic();
private:
Map *mCurrentMap;
+#ifdef EATHENA_SUPPORT
Network *mNetwork;
+#endif
std::string mMapName;
};
diff --git a/src/equipment.cpp b/src/equipment.cpp
index 558df216..c8e58b8c 100644
--- a/src/equipment.cpp
+++ b/src/equipment.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,19 +21,57 @@
#include "equipment.h"
#include "item.h"
+#ifdef EATHENA_SUPPORT
#include "inventory.h"
#include "localplayer.h"
+#endif
-Equipment::Equipment():
- mArrows(0)
+#include <algorithm>
+
+Equipment::Equipment()
+#ifdef EATHENA_SUPPORT
+ : mArrows(0)
+#endif
{
+#ifdef TMWSERV_SUPPORT
+ std::fill_n(mEquipment, EQUIPMENT_SIZE, (Item*) 0);
+#else
std::fill_n(mEquipment, EQUIPMENT_SIZE, 0);
+#endif
+}
+
+#ifdef TMWSERV_SUPPORT
+
+Equipment::~Equipment()
+{
+ clear();
}
+void Equipment::clear()
+{
+ for (int i = 0; i < EQUIPMENT_SIZE; ++i)
+ delete mEquipment[i];
+
+ std::fill_n(mEquipment, EQUIPMENT_SIZE, (Item*) 0);
+}
+
+void Equipment::setEquipment(int index, int id)
+{
+ if (mEquipment[index] && mEquipment[index]->getId() == id)
+ return;
+
+ delete mEquipment[index];
+ mEquipment[index] = (id > 0) ? new Item(id) : 0;
+}
+
+#else
+
void Equipment::setEquipment(int index, int inventoryIndex)
{
mEquipment[index] = inventoryIndex;
- Item* item = player_node->getInventory()->getItem(inventoryIndex);
+ Item *item = player_node->getInventory()->getItem(inventoryIndex);
if (item)
item->setEquipped(true);
}
+
+#endif
diff --git a/src/equipment.h b/src/equipment.h
index d75069dc..7605175a 100644
--- a/src/equipment.h
+++ b/src/equipment.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,9 +22,13 @@
#ifndef EQUIPMENT_H
#define EQUIPMENT_H
-class Item;
-
+#ifdef TMWSERV_SUPPORT
+#define EQUIPMENT_SIZE 11
+#else
#define EQUIPMENT_SIZE 10
+#endif
+
+class Item;
class Equipment
{
@@ -35,17 +38,40 @@ class Equipment
*/
Equipment();
+#ifdef TMWSERV_SUPPORT
+ /**
+ * Destructor.
+ */
+ ~Equipment();
+#endif
+
/**
* Get equipment at the given slot.
*/
+#ifdef TMWSERV_SUPPORT
+ Item* getEquipment(int index)
+#else
int getEquipment(int index) const
+#endif
{ return mEquipment[index]; }
+#ifdef TMWSERV_SUPPORT
+ /**
+ * Clears equipment.
+ */
+ void clear();
+#endif
+
/**
* Set equipment at the given slot.
*/
+#ifdef TMWSERV_SUPPORT
+ void setEquipment(int index, int id);
+#else
void setEquipment(int index, int inventoryIndex);
+#endif
+#ifdef EATHENA_SUPPORT
/**
* Remove equipment from the given slot.
*/
@@ -60,10 +86,15 @@ class Equipment
* Set the item used in the arrow slot.
*/
void setArrows(int arrows) { mArrows = arrows; }
+#endif
private:
+#ifdef TMWSERV_SUPPORT
+ Item* mEquipment[EQUIPMENT_SIZE];
+#else
int mEquipment[EQUIPMENT_SIZE];
int mArrows;
+#endif
};
#endif
diff --git a/src/floor_item.cpp b/src/floor_item.cpp
index 82506f8f..000835ad 100644
--- a/src/floor_item.cpp
+++ b/src/floor_item.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,7 +26,11 @@
#include "resources/image.h"
-FloorItem::FloorItem(int id, int itemId, int x, int y, Map *map):
+FloorItem::FloorItem(int id,
+ int itemId,
+ int x,
+ int y,
+ Map *map):
mId(id),
mX(x),
mY(y),
diff --git a/src/floor_item.h b/src/floor_item.h
index 0972a983..7ca0f5a3 100644
--- a/src/floor_item.h
+++ b/src/floor_item.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -43,7 +42,11 @@ class FloorItem : public Sprite
/**
* Constructor.
*/
- FloorItem(int id, int itemId, int x, int y, Map *map);
+ FloorItem(int id,
+ int itemId,
+ int x,
+ int y,
+ Map *map);
/**
* Destructor.
diff --git a/src/flooritemmanager.cpp b/src/flooritemmanager.cpp
index 97b3ca5b..5d2799d4 100644
--- a/src/flooritemmanager.cpp
+++ b/src/flooritemmanager.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,7 +29,8 @@ FloorItemManager::~FloorItemManager()
clear();
}
-FloorItem* FloorItemManager::create(int id, int itemId, int x, int y, Map *map)
+FloorItem *FloorItemManager::create(int id, int itemId,
+ int x, int y, Map *map)
{
FloorItem *floorItem = new FloorItem(id, itemId, x, y, map);
mFloorItems.push_back(floorItem);
diff --git a/src/flooritemmanager.h b/src/flooritemmanager.h
index 1a6e8e0a..704b39fd 100644
--- a/src/flooritemmanager.h
+++ b/src/flooritemmanager.h
@@ -2,8 +2,7 @@
* The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/game.cpp b/src/game.cpp
index 7f0186d1..91d8fa3a 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,6 +27,8 @@
#include <guichan/exception.hpp>
#include "beingmanager.h"
+#include "channelmanager.h"
+#include "commandhandler.h"
#include "configuration.h"
#include "effectmanager.h"
#include "emoteshortcut.h"
@@ -42,8 +43,12 @@
#include "log.h"
#include "npc.h"
#include "particle.h"
+#ifdef EATHENA_SUPPORT
+#include "party.h"
+#endif
#include "player_relations.h"
+#include "gui/widgets/chattab.h"
#include "gui/buy.h"
#include "gui/buysell.h"
#include "gui/chat.h"
@@ -70,23 +75,47 @@
#include "gui/setup.h"
#include "gui/skill.h"
#include "gui/status.h"
-#include "gui/storagewindow.h"
#include "gui/trade.h"
#include "gui/viewport.h"
+#ifdef TMWSERV_SUPPORT
+#include "gui/buddywindow.h"
+#include "gui/guildwindow.h"
+#include "gui/magic.h"
+#include "gui/npcpostdialog.h"
+#include "gui/partywindow.h"
+#include "gui/quitdialog.h"
+#else
+#include "gui/storagewindow.h"
+#endif
-#include "net/beinghandler.h"
-#include "net/buysellhandler.h"
-#include "net/chathandler.h"
-#include "net/equipmenthandler.h"
-#include "net/inventoryhandler.h"
-#include "net/itemhandler.h"
+#ifdef TMWSERV_SUPPORT
+#include "net/tmwserv/chathandler.h"
+#include "net/tmwserv/itemhandler.h"
+#include "net/tmwserv/npchandler.h"
+#include "net/tmwserv/playerhandler.h"
+#include "net/tmwserv/tradehandler.h"
+#include "net/tmwserv/network.h"
+#include "net/tmwserv/beinghandler.h"
+#include "net/tmwserv/buysellhandler.h"
+#include "net/tmwserv/effecthandler.h"
+#include "net/tmwserv/guildhandler.h"
+#include "net/tmwserv/inventoryhandler.h"
+#include "net/tmwserv/partyhandler.h"
+#else
+#include "net/ea/network.h"
+#include "net/ea/chathandler.h"
+#include "net/ea/beinghandler.h"
+#include "net/ea/buysellhandler.h"
+#include "net/ea/equipmenthandler.h"
+#include "net/ea/inventoryhandler.h"
+#include "net/ea/itemhandler.h"
+#include "net/ea/npchandler.h"
+#include "net/ea/playerhandler.h"
+#include "net/ea/tradehandler.h"
+#include "net/ea/protocol.h"
+#include "net/ea/skillhandler.h"
#include "net/messageout.h"
-#include "net/network.h"
-#include "net/npchandler.h"
-#include "net/playerhandler.h"
-#include "net/protocol.h"
-#include "net/skillhandler.h"
-#include "net/tradehandler.h"
+#endif
#include "resources/imagewriter.h"
@@ -105,7 +134,11 @@ Joystick *joystick = NULL;
extern Window *weightNotice;
extern Window *deathNotice;
+#ifdef TMWSERV_SUPPORT
+QuitDialog *quitDialog = NULL;
+#else
ConfirmDialog *exitConfirm = NULL;
+#endif
OkDialog *disconnectedDialog = NULL;
ChatWindow *chatWindow;
@@ -114,7 +147,9 @@ StatusWindow *statusWindow;
MiniStatusWindow *miniStatusWindow;
BuyDialog *buyDialog;
SellDialog *sellDialog;
+#ifdef EATHENA_SUPPORT
BuySellDialog *buySellDialog;
+#endif
InventoryWindow *inventoryWindow;
EmoteWindow *emoteWindow;
NpcIntegerDialog *npcIntegerDialog;
@@ -122,6 +157,15 @@ NpcListDialog *npcListDialog;
NpcTextDialog *npcTextDialog;
NpcStringDialog *npcStringDialog;
SkillDialog *skillDialog;
+#ifdef TMWSERV_SUPPORT
+BuddyWindow *buddyWindow;
+GuildWindow *guildWindow;
+MagicDialog *magicDialog;
+NpcPostDialog *npcPostDialog;
+PartyWindow *partyWindow;
+#else
+StorageWindow *storageWindow;
+#endif
Minimap *minimap;
EquipmentWindow *equipmentWindow;
TradeWindow *tradeWindow;
@@ -129,13 +173,19 @@ HelpWindow *helpWindow;
DebugWindow *debugWindow;
ShortcutWindow *itemShortcutWindow;
ShortcutWindow *emoteShortcutWindow;
-StorageWindow *storageWindow;
BeingManager *beingManager = NULL;
FloorItemManager *floorItemManager = NULL;
-Particle* particleEngine = NULL;
+ChannelManager *channelManager = NULL;
+CommandHandler *commandHandler = NULL;
+Particle *particleEngine = NULL;
EffectManager *effectManager = NULL;
+ChatTab *localChatTab = NULL;
+#ifdef EATHENA_SUPPORT
+Party *playerParty = NULL;
+#endif
+
const int MAX_TIME = 10000;
/**
@@ -149,7 +199,9 @@ namespace {
if (event.getId() == "yes" || event.getId() == "ok")
done = true;
+#ifdef EATHENA_SUPPORT
exitConfirm = NULL;
+#endif
disconnectedDialog = NULL;
}
} exitListener;
@@ -187,33 +239,56 @@ int get_elapsed_time(int start_time)
/**
* Create all the various globally accessible gui windows
*/
+#ifdef TMWSERV_SUPPORT
+void createGuiWindows()
+#else
void createGuiWindows(Network *network)
+#endif
{
// Create dialogs
+#ifdef TMWSERV_SUPPORT
+ chatWindow = new ChatWindow;
+ buyDialog = new BuyDialog;
+ sellDialog = new SellDialog;
+ tradeWindow = new TradeWindow;
+ npcTextDialog = new NpcTextDialog;
+ npcIntegerDialog = new NpcIntegerDialog;
+ npcListDialog = new NpcListDialog;
+ npcStringDialog = new NpcStringDialog;
+ npcPostDialog = new NpcPostDialog();
+ magicDialog = new MagicDialog();
+ equipmentWindow = new EquipmentWindow(player_node->mEquipment.get());
+ buddyWindow = new BuddyWindow();
+ guildWindow = new GuildWindow();
+ partyWindow = new PartyWindow();
+#else
chatWindow = new ChatWindow(network);
- menuWindow = new MenuWindow();
- statusWindow = new StatusWindow(player_node);
- miniStatusWindow = new MiniStatusWindow();
buyDialog = new BuyDialog(network);
sellDialog = new SellDialog(network);
buySellDialog = new BuySellDialog(network);
- inventoryWindow = new InventoryWindow();
- emoteWindow = new EmoteWindow();
+ tradeWindow = new TradeWindow(network);
+ equipmentWindow = new EquipmentWindow;
npcTextDialog = new NpcTextDialog(network);
npcIntegerDialog = new NpcIntegerDialog(network);
npcListDialog = new NpcListDialog(network);
npcStringDialog = new NpcStringDialog(network);
- skillDialog = new SkillDialog();
- minimap = new Minimap();
- equipmentWindow = new EquipmentWindow();
- tradeWindow = new TradeWindow(network);
- helpWindow = new HelpWindow();
- debugWindow = new DebugWindow();
+ storageWindow = new StorageWindow(network);
+#endif
+ menuWindow = new MenuWindow;
+ statusWindow = new StatusWindow(player_node);
+ miniStatusWindow = new MiniStatusWindow;
+ inventoryWindow = new InventoryWindow;
+ emoteWindow = new EmoteWindow;
+ skillDialog = new SkillDialog;
+ minimap = new Minimap;
+ helpWindow = new HelpWindow;
+ debugWindow = new DebugWindow;
itemShortcutWindow = new ShortcutWindow("ItemShortcut",
new ItemShortcutContainer);
emoteShortcutWindow = new ShortcutWindow("emoteShortcut",
new EmoteShortcutContainer);
- storageWindow = new StorageWindow(network);
+
+ localChatTab = new ChatTab(_("General"));
// Set initial window visibility
chatWindow->setVisible((bool) config.getValue(
@@ -222,6 +297,8 @@ void createGuiWindows(Network *network)
miniStatusWindow->getPopupName() + "Visible", true));
buyDialog->setVisible(false);
sellDialog->setVisible(false);
+ minimap->setVisible((bool) config.getValue(
+ minimap->getWindowName() + "Visible", true));
tradeWindow->setVisible(false);
menuWindow->setVisible((bool) config.getValue(
menuWindow->getPopupName() + "Visible", true));
@@ -231,12 +308,21 @@ void createGuiWindows(Network *network)
emoteShortcutWindow->getWindowName() + "Visible", true));
minimap->setVisible((bool) config.getValue(
minimap->getWindowName() + "Visible", true));
+#ifdef EATHENA_SUPPORT
buySellDialog->setVisible(false);
+#endif
npcTextDialog->setVisible(false);
npcIntegerDialog->setVisible(false);
npcListDialog->setVisible(false);
npcStringDialog->setVisible(false);
+#ifdef EATHENA_SUPPORT
storageWindow->setVisible(false);
+#endif
+
+ if (config.getValue("logToChat", 0))
+ {
+ logger->setChatWindow(chatWindow);
+ }
}
/**
@@ -245,19 +331,29 @@ void createGuiWindows(Network *network)
void destroyGuiWindows()
{
logger->setChatWindow(NULL);
+ delete localChatTab; // Need to do this first, so it can remove itself
delete chatWindow;
delete statusWindow;
delete miniStatusWindow;
delete menuWindow;
delete buyDialog;
delete sellDialog;
+#ifdef EATHENA_SUPPORT
delete buySellDialog;
+#endif
delete inventoryWindow;
delete emoteWindow;
delete npcIntegerDialog;
delete npcListDialog;
delete npcTextDialog;
delete npcStringDialog;
+#ifdef TMWSERV_SUPPORT
+ delete npcPostDialog;
+ delete magicDialog;
+ delete buddyWindow;
+ delete guildWindow;
+ delete partyWindow;
+#endif
delete skillDialog;
delete minimap;
delete equipmentWindow;
@@ -266,36 +362,61 @@ void destroyGuiWindows()
delete debugWindow;
delete itemShortcutWindow;
delete emoteShortcutWindow;
+#ifdef EATHENA_SUPPORT
delete storageWindow;
+#endif
}
+#ifdef TMWSERV_SUPPORT
+Game::Game():
+ mBeingHandler(new BeingHandler()),
+ mGuildHandler(new GuildHandler()),
+ mPartyHandler(new PartyHandler()),
+ mEffectHandler(new EffectHandler()),
+#else
Game::Game(Network *network):
mNetwork(network),
mBeingHandler(new BeingHandler(config.getValue("EnableSync", 0) == 1)),
- mBuySellHandler(new BuySellHandler()),
- mChatHandler(new ChatHandler()),
- mEquipmentHandler(new EquipmentHandler()),
- mInventoryHandler(new InventoryHandler()),
- mItemHandler(new ItemHandler()),
- mNpcHandler(new NPCHandler()),
- mPlayerHandler(new PlayerHandler()),
- mSkillHandler(new SkillHandler()),
- mTradeHandler(new TradeHandler())
+ mEquipmentHandler(new EquipmentHandler),
+ mSkillHandler(new SkillHandler),
+#endif
+ mBuySellHandler(new BuySellHandler),
+ mChatHandler(new ChatHandler),
+ mInventoryHandler(new InventoryHandler),
+ mItemHandler(new ItemHandler),
+ mNpcHandler(new NPCHandler),
+ mPlayerHandler(new PlayerHandler),
+ mTradeHandler(new TradeHandler),
+ mLastTarget(Being::UNKNOWN),
+ mLogicCounterId(0), mSecondsCounterId(0)
{
+ done = false;
+
+#ifdef TMWSERV_SUPPORT
+ createGuiWindows();
+ engine = new Engine;
+
+ beingManager = new BeingManager;
+ commandHandler = new CommandHandler();
+#else
createGuiWindows(network);
engine = new Engine(network);
beingManager = new BeingManager(network);
- floorItemManager = new FloorItemManager();
- effectManager = new EffectManager();
+ commandHandler = new CommandHandler(network);
+#endif
+
+ floorItemManager = new FloorItemManager;
+ channelManager = new ChannelManager();
+ effectManager = new EffectManager;
particleEngine = new Particle(NULL);
particleEngine->setupEngine();
- // Initialize timers
+ // Initialize logic and seconds counters
tick_time = 0;
- SDL_AddTimer(10, nextTick, NULL); // Logic counter
- SDL_AddTimer(1000, nextSecond, NULL); // Seconds counter
+ mLogicCounterId = SDL_AddTimer(10, nextTick, NULL);
+ mSecondsCounterId = SDL_AddTimer(1000, nextSecond, NULL);
// Initialize frame limiting
config.addListener("fpslimit", this);
@@ -303,7 +424,10 @@ Game::Game(Network *network):
// Initialize beings
beingManager->setPlayer(player_node);
+#ifdef EATHENA_SUPPORT
player_node->setNetwork(network);
+ playerParty = new Party(network);
+#endif
Joystick::init();
// TODO: The user should be able to choose which one to use
@@ -311,6 +435,19 @@ Game::Game(Network *network):
if (Joystick::getNumberOfJoysticks() > 0)
joystick = new Joystick(0);
+#ifdef TMWSERV_SUPPORT
+ Net::registerHandler(mBeingHandler.get());
+ Net::registerHandler(mBuySellHandler.get());
+ Net::registerHandler(mChatHandler.get());
+ Net::registerHandler(mGuildHandler.get());
+ Net::registerHandler(mInventoryHandler.get());
+ Net::registerHandler(mItemHandler.get());
+ Net::registerHandler(mNpcHandler.get());
+ Net::registerHandler(mPartyHandler.get());
+ Net::registerHandler(mPlayerHandler.get());
+ Net::registerHandler(mTradeHandler.get());
+ Net::registerHandler(mEffectHandler.get());
+#else
network->registerHandler(mBeingHandler.get());
network->registerHandler(mBuySellHandler.get());
network->registerHandler(mChatHandler.get());
@@ -336,24 +473,38 @@ Game::Game(Network *network):
msg.writeInt32(tick_time);
engine->changeMap(map_path);
+#endif
setupWindow->setInGame(true);
}
Game::~Game()
{
- delete player_node;
+#ifdef TMWSERV_SUPPORT
+ Net::clearHandlers();
+#else
+ delete playerParty;
+#endif
+
destroyGuiWindows();
delete beingManager;
+ delete player_node;
delete floorItemManager;
+ delete channelManager;
+ delete commandHandler;
delete joystick;
delete particleEngine;
delete engine;
+ viewport->setMap(NULL);
+ player_node = NULL;
beingManager = NULL;
floorItemManager = NULL;
joystick = NULL;
+
+ SDL_RemoveTimer(mLogicCounterId);
+ SDL_RemoveTimer(mSecondsCounterId);
}
static bool saveScreenshot()
@@ -374,11 +525,11 @@ static bool saveScreenshot()
filenameSuffix.str("");
filename << PHYSFS_getUserDir();
#if (defined __USE_UNIX98 || defined __FreeBSD__)
- filenameSuffix << ".aethyra/";
+ filenameSuffix << ".tmw/";
#elif defined __APPLE__
filenameSuffix << "Desktop/";
#endif
- filenameSuffix << "Ae_Screenshot_" << screenshotCount << ".png";
+ filenameSuffix << "TMW_Screenshot_" << screenshotCount << ".png";
filename << filenameSuffix.str();
testExists.open(filename.str().c_str(), std::ios::in);
found = !testExists.is_open();
@@ -391,11 +542,11 @@ static bool saveScreenshot()
{
std::stringstream chatlogentry;
chatlogentry << _("Screenshot saved to ~/") << filenameSuffix.str();
- chatWindow->chatLog(chatlogentry.str(), BY_SERVER);
+ localChatTab->chatLog(chatlogentry.str(), BY_SERVER);
}
else
{
- chatWindow->chatLog(_("Saving screenshot failed!"), BY_SERVER);
+ localChatTab->chatLog(_("Saving screenshot failed!"), BY_SERVER);
logger->log("Error: could not save screenshot.");
}
@@ -467,6 +618,10 @@ void Game::logic()
}
// Handle network stuff
+#ifdef TMWSERV_SUPPORT
+ Net::flush();
+ // TODO: Fix notification when the connection is lost
+#else
mNetwork->flush();
mNetwork->dispatchMessages();
@@ -482,6 +637,7 @@ void Game::logic()
disconnectedDialog->requestMoveToTop();
}
}
+#endif
}
}
@@ -510,6 +666,23 @@ void Game::handleInput()
return;
}
+#ifdef TMWSERV_SUPPORT
+ // send straight to gui for certain windows
+ if (npcPostDialog->isVisible())
+ {
+ try
+ {
+ guiInput->pushInput(event);
+ }
+ catch (gcn::Exception e)
+ {
+ const char* err = e.getMessage().c_str();
+ logger->log("Warning: guichan input exception: %s", err);
+ }
+ return;
+ }
+#endif
+
// Mode switch to emotes
if (keyboard.isKeyActive(keyboard.KEY_EMOTE))
{
@@ -523,58 +696,54 @@ void Game::handleInput()
}
}
- if (keyboard.isKeyActive(keyboard.KEY_TOGGLE_CHAT) ||
- keyboard.isKeyActive(keyboard.KEY_OK))
- {
- // Input chat window
- if (!(chatWindow->isInputFocused() ||
- deathNotice ||
- weightNotice))
+ if (!(chatWindow->isInputFocused() || deathNotice || weightNotice))
+ if (keyboard.isKeyActive(keyboard.KEY_OK))
{
- // Quit by pressing Enter if the exit confirm is there
+#ifdef TMWSERV_SUPPORT
+ // Don not focus chat input when quit dialog is active
+ if (quitDialog != NULL && quitDialog->isVisible())
+ continue;
+#else
if (exitConfirm &&
keyboard.isKeyActive(keyboard.KEY_TOGGLE_CHAT))
done = true;
+#endif
// Close the Browser if opened
else if (helpWindow->isVisible() &&
- keyboard.isKeyActive(keyboard.KEY_OK))
+ keyboard.isKeyActive(keyboard.KEY_OK))
helpWindow->setVisible(false);
// Close the config window, cancelling changes if opened
else if (setupWindow->isVisible() &&
- keyboard.isKeyActive(keyboard.KEY_OK))
+ keyboard.isKeyActive(keyboard.KEY_OK))
setupWindow->action(gcn::ActionEvent(NULL, "cancel"));
// Submits the text and proceeds to the next dialog
else if (npcStringDialog->isVisible() &&
- keyboard.isKeyActive(keyboard.KEY_OK))
+ keyboard.isKeyActive(keyboard.KEY_OK))
npcStringDialog->action(gcn::ActionEvent(NULL, "ok"));
// Proceed to the next dialog option, or close the window
else if (npcTextDialog->isVisible() &&
- keyboard.isKeyActive(keyboard.KEY_OK))
+ keyboard.isKeyActive(keyboard.KEY_OK))
npcTextDialog->action(gcn::ActionEvent(NULL, "ok"));
// Choose the currently highlighted dialogue option
else if (npcListDialog->isVisible() &&
- keyboard.isKeyActive(keyboard.KEY_OK))
+ keyboard.isKeyActive(keyboard.KEY_OK))
npcListDialog->action(gcn::ActionEvent(NULL, "ok"));
// Submits the text and proceeds to the next dialog
else if (npcIntegerDialog->isVisible() &&
- keyboard.isKeyActive(keyboard.KEY_OK))
+ keyboard.isKeyActive(keyboard.KEY_OK))
npcIntegerDialog->action(gcn::ActionEvent(NULL, "ok"));
- else if (!(keyboard.getKeyValue(
- KeyboardConfig::KEY_TOGGLE_CHAT) ==
- keyboard.getKeyValue(
- KeyboardConfig::KEY_OK) &&
- (helpWindow->isVisible() ||
- setupWindow->isVisible() ||
- npcStringDialog->isVisible() ||
- npcTextDialog->isVisible() ||
- npcListDialog->isVisible() ||
- npcIntegerDialog->isVisible())))
+ /*
+ else if (guildWindow->isVisible())
{
- chatWindow->requestChatFocus();
- used = true;
+ // TODO: Check if a dialog is open and close it if so
}
+ */
+ }
+ if (keyboard.isKeyActive(keyboard.KEY_TOGGLE_CHAT))
+ {
+ if (chatWindow->requestChatFocus())
+ used = true;
}
- }
const int tKey = keyboard.getKeyIndex(event.key.keysym.sym);
switch (tKey)
@@ -607,6 +776,17 @@ void Game::handleInput()
break;
// Quitting confirmation dialog
case KeyboardConfig::KEY_QUIT:
+#ifdef TMWSERV_SUPPORT
+ if (!quitDialog)
+ {
+ quitDialog = new QuitDialog(&done, &quitDialog);
+ quitDialog->requestMoveToTop();
+ }
+ else
+ {
+ quitDialog->action(gcn::ActionEvent(NULL, "cancel"));
+ }
+#else
if (!exitConfirm)
{
exitConfirm = new ConfirmDialog(_("Quit"),
@@ -619,6 +799,7 @@ void Game::handleInput()
{
exitConfirm->action(gcn::ActionEvent(NULL, _("no")));
}
+#endif
break;
default:
break;
@@ -649,25 +830,34 @@ void Game::handleInput()
{
case KeyboardConfig::KEY_PICKUP:
{
- FloorItem *item = floorItemManager->findByCoordinates(
- player_node->mX,
- player_node->mY);
+#ifdef TMWSERV_SUPPORT
+ const Vector &pos = player_node->getPosition();
+ Uint16 x = (int) pos.x / 32;
+ Uint16 y = (int) pos.y / 32;
+#else
+ Uint16 x = player_node->mX;
+ Uint16 y = player_node->mY;
+#endif
+ FloorItem *item =
+ floorItemManager->findByCoordinates(x, y);
// If none below the player, try the tile in front
// of the player
if (!item)
{
- Uint16 x = player_node->mX;
- Uint16 y = player_node->mY;
- if (player_node->getDirection() & Being::UP)
- y--;
- if (player_node->getDirection() & Being::DOWN)
- y++;
- if (player_node->getDirection() & Being::LEFT)
- x--;
- if (player_node->getDirection() & Being::RIGHT)
- x++;
- item = floorItemManager->findByCoordinates(x, y);
+ // Temporary until tile-based picking is
+ // removed.
+ switch (player_node->getSpriteDirection())
+ {
+ case DIRECTION_UP : --y; break;
+ case DIRECTION_DOWN : ++y; break;
+ case DIRECTION_LEFT : --x; break;
+ case DIRECTION_RIGHT: ++x; break;
+ default: break;
+ }
+
+ item = floorItemManager->findByCoordinates(
+ x, y);
}
if (item)
@@ -693,6 +883,10 @@ void Game::handleInput()
equipmentWindow->setVisible(false);
helpWindow->setVisible(false);
debugWindow->setVisible(false);
+#ifdef TMWSERV_SUPPORT
+ guildWindow->setVisible(false);
+ buddyWindow->setVisible(false);
+#endif
}
break;
case KeyboardConfig::KEY_WINDOW_STATUS:
@@ -744,16 +938,16 @@ void Game::handleInput()
unsigned int deflt = player_relations.getDefault();
if (deflt & PlayerRelation::TRADE)
{
- chatWindow->chatLog(
- _("Ignoring incoming trade requests"),
- BY_SERVER);
+ localChatTab->chatLog(
+ _("Ignoring incoming trade requests"),
+ BY_SERVER);
deflt &= ~PlayerRelation::TRADE;
}
else
{
- chatWindow->chatLog(
- _("Accepting incoming trade requests"),
- BY_SERVER);
+ localChatTab->chatLog(
+ _("Accepting incoming trade requests"),
+ BY_SERVER);
deflt |= PlayerRelation::TRADE;
}
@@ -791,6 +985,7 @@ void Game::handleInput()
logger->log("Warning: guichan input exception: %s", err);
}
}
+
} // End while
// If the user is configuring the keys then don't respond.
@@ -799,7 +994,10 @@ void Game::handleInput()
// Moving player around
if (player_node->mAction != Being::DEAD &&
- current_npc == 0 && !chatWindow->isInputFocused())
+#ifdef EATHENA_SUPPORT
+ current_npc == 0 &&
+#endif
+ !chatWindow->isInputFocused())
{
// Get the state of the keyboard keys
keyboard.refreshActiveKeys();
@@ -813,41 +1011,67 @@ void Game::handleInput()
return;
}
+#ifdef TMWSERV_SUPPORT
+ const Vector &pos = player_node->getPosition();
+ const Uint16 x = (int) pos.x / 32;
+ const Uint16 y = (int) pos.y / 32;
+#else
const Uint16 x = player_node->mX;
const Uint16 y = player_node->mY;
+#endif
unsigned char direction = 0;
// Translate pressed keys to movement and direction
if (keyboard.isKeyActive(keyboard.KEY_MOVE_UP) ||
- (joystick && joystick->isUp()))
+ (joystick && joystick->isUp()))
{
direction |= Being::UP;
}
else if (keyboard.isKeyActive(keyboard.KEY_MOVE_DOWN) ||
- (joystick && joystick->isDown()))
+ (joystick && joystick->isDown()))
{
direction |= Being::DOWN;
}
if (keyboard.isKeyActive(keyboard.KEY_MOVE_LEFT) ||
- (joystick && joystick->isLeft()))
+ (joystick && joystick->isLeft()))
{
direction |= Being::LEFT;
}
else if (keyboard.isKeyActive(keyboard.KEY_MOVE_RIGHT) ||
- (joystick && joystick->isRight()))
+ (joystick && joystick->isRight()))
{
direction |= Being::RIGHT;
}
+#ifdef TMWSERV_SUPPORT
+ // First if player is pressing key for the direction he is already
+ // going
+ if (direction == player_node->getWalkingDir())
+ {
+ player_node->setWalkingDir(direction);
+ }
+ // Else if he is pressing a key, and its different from what he has
+ // been pressing, stop (do not send this stop to the server) and
+ // start in the new direction
+ else if (direction && direction != player_node->getWalkingDir())
+ {
+ player_node->stopWalking(false);
+ player_node->setWalkingDir(direction);
+ }
+ // Else, he is not pressing a key, stop (sending to server)
+ else
+ {
+ player_node->stopWalking(true);
+ }
+#else
player_node->setWalkingDir(direction);
// Attacking monsters
if (keyboard.isKeyActive(keyboard.KEY_ATTACK) ||
(joystick && joystick->buttonPressed(0)))
{
- Being *target = beingManager->findNearestLivingBeing(x, y, 20,
- Being::MONSTER);
+ Being *target = NULL;
bool newTarget = !keyboard.isKeyActive(keyboard.KEY_TARGET);
// A set target has highest priority
@@ -864,47 +1088,41 @@ void Game::handleInput()
default: break;
}
- // Attack priorioty is: Monster, Player, auto target
- target = beingManager->findBeing(targetX, targetY,
- Being::MONSTER);
- if (!target)
- target = beingManager->findBeing(targetX, targetY,
- Being::PLAYER);
+ // Only auto target Monsters
+ target = beingManager->findNearestLivingBeing(targetX, targetY,
+ 20, Being::MONSTER);
}
player_node->attack(target, newTarget);
}
+#endif
- // Target the nearest player if 'q' is pressed
- if ( keyboard.isKeyActive(keyboard.KEY_TARGET_PLAYER) &&
- !keyboard.isKeyActive(keyboard.KEY_TARGET) )
- {
- Being *target = beingManager->findNearestLivingBeing(player_node,
- 20, Being::PLAYER);
-
- player_node->setTarget(target);
- }
-
- // Target the nearest monster if 'a' pressed
- if ((keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) ||
- (joystick && joystick->buttonPressed(3))) &&
- !keyboard.isKeyActive(keyboard.KEY_TARGET))
+ // Target the nearest player/monster/npc
+ if ((keyboard.isKeyActive(keyboard.KEY_TARGET_PLAYER) ||
+ keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) ||
+ keyboard.isKeyActive(keyboard.KEY_TARGET_NPC) ||
+ (joystick && joystick->buttonPressed(3))) &&
+ !keyboard.isKeyActive(keyboard.KEY_TARGET))
{
- Being *target = beingManager->findNearestLivingBeing(
- x, y, 20, Being::MONSTER);
-
- player_node->setTarget(target);
- }
+ Being::Type currentTarget = Being::UNKNOWN;
+ if (keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) ||
+ (joystick && joystick->buttonPressed(3)))
+ currentTarget = Being::MONSTER;
+ else if (keyboard.isKeyActive(keyboard.KEY_TARGET_PLAYER))
+ currentTarget = Being::PLAYER;
+ else if (keyboard.isKeyActive(keyboard.KEY_TARGET_NPC))
+ currentTarget = Being::NPC;
- // Target the nearest npc if 'n' pressed
- if ( keyboard.isKeyActive(keyboard.KEY_TARGET_NPC) &&
- !keyboard.isKeyActive(keyboard.KEY_TARGET) )
- {
- Being *target = beingManager->findNearestLivingBeing(
- x, y, 20, Being::NPC);
+ Being *target = beingManager->findNearestLivingBeing(player_node,
+ 20, currentTarget);
- player_node->setTarget(target);
- }
+ if (target && (target != player_node->getTarget() ||
+ currentTarget != mLastTarget))
+ {
+ player_node->setTarget(target);
+ mLastTarget = currentTarget;
+ }
+ } else mLastTarget = Being::UNKNOWN; // Reset last target
// Talk to the nearest NPC if 't' pressed
if ( keyboard.isKeyActive(keyboard.KEY_TALK) )
@@ -914,12 +1132,6 @@ void Game::handleInput()
{
Being *target = player_node->getTarget();
- if (!target)
- {
- target = beingManager->findNearestLivingBeing(
- x, y, 20, Being::NPC);
- }
-
if (target)
{
if (target->getType() == Being::NPC)
@@ -928,11 +1140,13 @@ void Game::handleInput()
}
}
+#ifdef EATHENA_SUPPORT
// Stop attacking if shift is pressed
if (keyboard.isKeyActive(keyboard.KEY_TARGET))
{
player_node->stopAttack();
}
+#endif
if (joystick)
{
diff --git a/src/game.h b/src/game.h
index 85bb9c07..c537d147 100644
--- a/src/game.h
+++ b/src/game.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,10 +24,14 @@
#include <memory>
+#include "SDL.h"
+
#include "configlistener.h"
class MessageHandler;
+#ifdef EATHENA_SUPPORT
class Network;
+#endif
extern std::string map_path;
extern volatile int fps;
@@ -37,7 +40,11 @@ extern volatile int tick_time;
class Game : public ConfigListener
{
public:
+#ifdef TMWSERV_SUPPORT
+ Game();
+#else
Game(Network *network);
+#endif
~Game();
void logic();
@@ -47,7 +54,9 @@ class Game : public ConfigListener
void optionChanged(const std::string &name);
private:
+#ifdef EATHENA_SUPPORT
Network *mNetwork;
+#endif
/** Used to determine whether to draw the next frame. */
int mDrawTime;
@@ -57,15 +66,27 @@ class Game : public ConfigListener
typedef const std::auto_ptr<MessageHandler> MessageHandlerPtr;
MessageHandlerPtr mBeingHandler;
+#ifdef TMWSERV_SUPPORT
+ MessageHandlerPtr mGuildHandler;
+ MessageHandlerPtr mPartyHandler;
+ MessageHandlerPtr mEffectHandler;
+#else
+ MessageHandlerPtr mEquipmentHandler;
+ MessageHandlerPtr mSkillHandler;
+#endif
MessageHandlerPtr mBuySellHandler;
MessageHandlerPtr mChatHandler;
- MessageHandlerPtr mEquipmentHandler;
MessageHandlerPtr mInventoryHandler;
MessageHandlerPtr mItemHandler;
MessageHandlerPtr mNpcHandler;
MessageHandlerPtr mPlayerHandler;
- MessageHandlerPtr mSkillHandler;
+ MessageHandlerPtr mPostHandler;
MessageHandlerPtr mTradeHandler;
+
+ int mLastTarget;
+
+ SDL_TimerID mLogicCounterId;
+ SDL_TimerID mSecondsCounterId;
};
/**
diff --git a/src/graphics.cpp b/src/graphics.cpp
index ca86f536..2fbf5e20 100644
--- a/src/graphics.cpp
+++ b/src/graphics.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -242,7 +241,7 @@ void Graphics::updateScreen()
SDL_Flip(mScreen);
}
-SDL_Surface* Graphics::getScreenshot()
+SDL_Surface *Graphics::getScreenshot()
{
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
int rmask = 0xff000000;
diff --git a/src/graphics.h b/src/graphics.h
index ec0b5e9c..2b6ca60e 100644
--- a/src/graphics.h
+++ b/src/graphics.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -59,7 +58,7 @@ struct ImageRect
RIGHT = 5,
LOWER_LEFT = 6,
LOWER_CENTER = 7,
- LOWER_RIGHT = 8,
+ LOWER_RIGHT = 8
};
Image *grid[9];
diff --git a/src/gui/browserbox.cpp b/src/gui/browserbox.cpp
index 46c8bdf1..2f667237 100644
--- a/src/gui/browserbox.cpp
+++ b/src/gui/browserbox.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -419,4 +418,3 @@ void BrowserBox::draw(gcn::Graphics *graphics)
setHeight((mTextRows.size() + wrappedLines) * font->getHeight());
}
}
-
diff --git a/src/gui/browserbox.h b/src/gui/browserbox.h
index 500c9fba..090c03e1 100644
--- a/src/gui/browserbox.h
+++ b/src/gui/browserbox.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -163,4 +162,3 @@ class BrowserBox : public gcn::Widget, public gcn::MouseListener
};
#endif
-
diff --git a/src/gui/buddywindow.cpp b/src/gui/buddywindow.cpp
new file mode 100644
index 00000000..37301c86
--- /dev/null
+++ b/src/gui/buddywindow.cpp
@@ -0,0 +1,68 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "buddywindow.h"
+#include "chat.h"
+#include "icon.h"
+
+#include "widgets/avatar.h"
+
+#include "../resources/resourcemanager.h"
+#include "../utils/gettext.h"
+
+extern ChatWindow *chatWindow;
+
+BuddyWindow::BuddyWindow():
+ Window(_("Buddy"))
+{
+ setVisible(false);
+ setWindowName("Buddy Window");
+ setCaption(_("Buddy List"));
+ setResizable(true);
+ setCloseButton(true);
+ setMinWidth(110);
+ setMinHeight(200);
+ setDefaultSize(124, 41, 288, 330);
+
+ Image *addImg = ResourceManager::getInstance()->getImage("buddyadd.png");
+ Image *delImg = ResourceManager::getInstance()->getImage("buddydel.png");
+
+ if (addImg && delImg)
+ {
+ Icon *addBuddy = new Icon(addImg);
+ Icon *delBuddy = new Icon(delImg);
+
+ add(addBuddy);
+ add(delBuddy);
+ }
+
+ loadWindowState();
+}
+
+void BuddyWindow::action(const gcn::ActionEvent &event)
+{
+
+}
+
+void BuddyWindow::draw(gcn::Graphics *graphics)
+{
+ Window::draw(graphics);
+}
diff --git a/src/gui/buddywindow.h b/src/gui/buddywindow.h
new file mode 100644
index 00000000..aa654477
--- /dev/null
+++ b/src/gui/buddywindow.h
@@ -0,0 +1,60 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef BUDDYWINDOW_H
+#define BUDDYWINDOW_H
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/actionevent.hpp>
+
+#include "window.h"
+
+class Avatar;
+
+/**
+ * Window showing buddy list.
+ *
+ * \ingroup Interface
+ */
+class BuddyWindow : public Window, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ BuddyWindow();
+
+ /**
+ * Performs action.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Draws the window
+ */
+ void draw(gcn::Graphics *graphics);
+
+
+ private:
+ std::list<Avatar*> mBuddyList;
+};
+
+#endif /* BUDDYWINDOW_H */
diff --git a/src/gui/button.cpp b/src/gui/button.cpp
index 16a2853c..28b7c0d7 100644
--- a/src/gui/button.cpp
+++ b/src/gui/button.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -67,7 +66,7 @@ Button::Button():
init();
}
-Button::Button(const std::string& caption, const std::string &actionEventId,
+Button::Button(const std::string &caption, const std::string &actionEventId,
gcn::ActionListener *listener):
gcn::Button(caption),
mIsLogged(false)
diff --git a/src/gui/button.h b/src/gui/button.h
index f21d2661..abaf5c43 100644
--- a/src/gui/button.h
+++ b/src/gui/button.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp
index 43c423f1..6df2ae25 100644
--- a/src/gui/buy.cpp
+++ b/src/gui/buy.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,29 +19,45 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "button.h"
-#include "buy.h"
-#include "label.h"
-#include "scrollarea.h"
-#include "shop.h"
-#include "shoplistbox.h"
-#include "slider.h"
+#include "gui/buy.h"
-#include "widgets/layout.h"
+#include "gui/button.h"
+#include "gui/label.h"
+#include "gui/scrollarea.h"
+#include "gui/shop.h"
+#include "gui/shoplistbox.h"
+#include "gui/slider.h"
-#include "../npc.h"
+#include "gui/widgets/layout.h"
-#include "../net/messageout.h"
-#include "../net/protocol.h"
+#include "npc.h"
+#include "shopitem.h"
+#include "units.h"
-#include "../utils/gettext.h"
-#include "../utils/strprintf.h"
+#ifdef TMWSERV_SUPPORT
+#include "net/tmwserv/gameserver/player.h"
+#else
+#include "net/messageout.h"
+#include "net/ea/protocol.h"
+#endif
+#include "resources/iteminfo.h"
+
+#include "utils/gettext.h"
+#include "utils/strprintf.h"
+
+#ifdef TMWSERV_SUPPORT
+BuyDialog::BuyDialog():
+#else
BuyDialog::BuyDialog(Network *network):
- Window("Buy"), mNetwork(network),
+#endif
+ Window(_("Buy")),
+#ifndef TMWSERV_SUPPORT
+ mNetwork(network),
+#endif
mMoney(0), mAmountItems(0), mMaxItems(0)
{
- setWindowName(_("Buy"));
+ setWindowName("Buy");
setResizable(true);
setCloseButton(true);
setMinWidth(260);
@@ -56,10 +71,10 @@ BuyDialog::BuyDialog(Network *network):
mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
mSlider = new Slider(1.0);
-
mQuantityLabel = new Label(strprintf("%d / %d", mAmountItems, mMaxItems));
mQuantityLabel->setAlignment(gcn::Graphics::CENTER);
- mMoneyLabel = new Label(strprintf(_("Price: %d GP / Total: %d GP"), 0, 0));
+ mMoneyLabel = new gcn::Label(strprintf(_("Price: %s / Total: %s"),
+ "", ""));
mIncreaseButton = new Button("+", "+", this);
mDecreaseButton = new Button("-", "-", this);
@@ -99,6 +114,7 @@ BuyDialog::BuyDialog(Network *network):
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
+ center();
loadWindowState();
}
@@ -127,9 +143,9 @@ void BuyDialog::reset()
setMoney(0);
}
-void BuyDialog::addItem(int id, int price)
+void BuyDialog::addItem(int id, int amount, int price)
{
- mShopItems->addItem(id, price);
+ mShopItems->addItem(id, amount, price);
mShopItemList->adjustSize();
}
@@ -179,11 +195,16 @@ void BuyDialog::action(const gcn::ActionEvent &event)
else if (event.getId() == "buy" && mAmountItems > 0 &&
mAmountItems <= mMaxItems)
{
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::tradeWithNPC
+ (mShopItems->at(selectedItem)->getId(), mAmountItems);
+#else
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_NPC_BUY_REQUEST);
outMsg.writeInt16(8);
outMsg.writeInt16(mAmountItems);
outMsg.writeInt16(mShopItems->at(selectedItem)->getId());
+#endif
// Update money and adjust the max number of items that can be bought
mMaxItems -= mAmountItems;
@@ -250,7 +271,16 @@ void BuyDialog::updateButtonsAndLabels()
// Update quantity and money labels
mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems));
mMoneyLabel->setCaption
- (strprintf(_("Price: %d GP / Total: %d GP"), price, mMoney - price));
+ (strprintf(_("Price: %s / Total: %s"),
+ Units::formatCurrency(price).c_str(),
+ Units::formatCurrency(mMoney - price).c_str()));
+}
+
+void BuyDialog::logic()
+{
+ Window::logic();
+
+ if (!current_npc) setVisible(false);
}
void BuyDialog::setVisible(bool visible)
diff --git a/src/gui/buy.h b/src/gui/buy.h
index ffd3f5c9..200394b9 100644
--- a/src/gui/buy.h
+++ b/src/gui/buy.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,11 +25,13 @@
#include <guichan/actionlistener.hpp>
#include <guichan/selectionlistener.hpp>
-#include <SDL_types.h>
-
#include "window.h"
+#include "../guichanfwd.h"
+
+#ifndef TMWSERV_SUPPORT
class Network;
+#endif
class ShopItems;
class ShopListBox;
class ListBox;
@@ -49,7 +50,11 @@ class BuyDialog : public Window, public gcn::ActionListener,
*
* @see Window::Window
*/
+#ifdef TMWSERV_SUPPORT
+ BuyDialog();
+#else
BuyDialog(Network *network);
+#endif
/**
* Destructor
@@ -69,7 +74,7 @@ class BuyDialog : public Window, public gcn::ActionListener,
/**
* Adds an item to the shop inventory.
*/
- void addItem(int id, int price);
+ void addItem(int id, int amount, int price);
/**
* Called when receiving actions from the widgets.
@@ -97,6 +102,11 @@ class BuyDialog : public Window, public gcn::ActionListener,
void updateButtonsAndLabels();
/**
+ * Check for current NPC
+ */
+ void logic();
+
+ /**
* Sets the visibility of this window.
*/
void setVisible(bool visible);
@@ -106,7 +116,9 @@ class BuyDialog : public Window, public gcn::ActionListener,
*/
void close();
private:
+#ifdef EATHENA_SUPPORT
Network *mNetwork;
+#endif
gcn::Button *mBuyButton;
gcn::Button *mQuitButton;
gcn::Button *mAddMaxButton;
@@ -122,9 +134,9 @@ class BuyDialog : public Window, public gcn::ActionListener,
ShopItems *mShopItems;
- Uint32 mMoney;
- Uint32 mAmountItems;
- Uint32 mMaxItems;
+ int mMoney;
+ int mAmountItems;
+ int mMaxItems;
};
extern BuyDialog *buyDialog;
diff --git a/src/gui/buysell.cpp b/src/gui/buysell.cpp
index df222797..b9a6a1dc 100644
--- a/src/gui/buysell.cpp
+++ b/src/gui/buysell.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,7 +25,9 @@
#include "../npc.h"
#include "../net/messageout.h"
-#include "../net/protocol.h"
+#ifdef EATHENA_SUPPORT
+#include "../net/ea/protocol.h"
+#endif
#include "../utils/gettext.h"
@@ -43,16 +44,18 @@ BuySellDialog::BuySellDialog(Network *network):
for (const char **curBtn = buttonNames; *curBtn; curBtn++)
{
Button *btn = new Button(gettext(*curBtn), *curBtn, this);
- if (!buyButton) buyButton = btn; // For focus request
+ if (!buyButton)
+ buyButton = btn; // For focus request
btn->setPosition(x, y);
add(btn);
x += btn->getWidth() + 10;
}
buyButton->requestFocus();
- setDefaultSize(x + getPadding(), (2 * y + buyButton->getHeight() +
- getTitleBarHeight()), ImageRect::CENTER);
+ setContentSize(x, 2 * y + buyButton->getHeight());
+ center();
+ setDefaultSize();
loadWindowState();
}
@@ -77,7 +80,7 @@ void BuySellDialog::action(const gcn::ActionEvent &event)
setVisible(false);
int action = 0;
- NPC::mTalking = false;
+ NPC::isTalking = false;
if (event.getId() == "Buy")
{
@@ -93,8 +96,10 @@ void BuySellDialog::action(const gcn::ActionEvent &event)
return;
}
+#ifdef EATHENA_SUPPORT
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_NPC_BUY_SELL_REQUEST);
outMsg.writeInt32(current_npc);
outMsg.writeInt8(action);
+#endif
}
diff --git a/src/gui/buysell.h b/src/gui/buysell.h
index c6989709..4b137554 100644
--- a/src/gui/buysell.h
+++ b/src/gui/buysell.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -46,8 +45,6 @@ class BuySellDialog : public Window, public gcn::ActionListener
BuySellDialog(Network *network);
/**
-<<<<<<< HEAD:src/gui/buysell.h
-=======
* Check for current NPC
*/
void logic();
@@ -55,7 +52,6 @@ class BuySellDialog : public Window, public gcn::ActionListener
void setVisible(bool visible);
/**
->>>>>>> f64903f... Fix up the NPC interraction widnows a bit:src/gui/buysell.h
* Called when receiving actions from the widgets.
*/
void action(const gcn::ActionEvent &event);
diff --git a/src/gui/changeemaildialog.cpp b/src/gui/changeemaildialog.cpp
new file mode 100644
index 00000000..0ed95bd7
--- /dev/null
+++ b/src/gui/changeemaildialog.cpp
@@ -0,0 +1,167 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "changeemaildialog.h"
+
+#include <string>
+#include <sstream>
+
+#include <guichan/widgets/label.hpp>
+
+#include "../main.h"
+#include "../log.h"
+#include "../logindata.h"
+
+#include "button.h"
+#include "register.h"
+#include "textfield.h"
+#include "ok_dialog.h"
+
+#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
+
+ChangeEmailDialog::ChangeEmailDialog(Window *parent, LoginData *loginData):
+ Window(_("Change Email Address"), true, parent),
+ mWrongDataNoticeListener(new WrongDataNoticeListener()),
+ mLoginData(loginData)
+{
+ gcn::Label *accountLabel = new gcn::Label(strprintf(_("Account: %s"),
+ mLoginData->username.c_str()));
+ gcn::Label *newEmailLabel = new gcn::Label(_("Type New Email Address twice:"));
+ mFirstEmailField = new TextField();
+ mSecondEmailField = new TextField();
+ mChangeEmailButton = new Button(_("Change Email Address"), "change_email", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+
+ const int width = 200;
+ const int height = 130;
+ setContentSize(width, height);
+
+ accountLabel->setPosition(5, 5);
+ accountLabel->setWidth(130);
+
+ newEmailLabel->setPosition(
+ 5, accountLabel->getY() + accountLabel->getHeight() + 7);
+ newEmailLabel->setWidth(width - 5);
+
+ mFirstEmailField->setPosition(
+ 5, newEmailLabel->getY() + newEmailLabel->getHeight() + 7);
+ mFirstEmailField->setWidth(130);
+
+ mSecondEmailField->setPosition(
+ 5, mFirstEmailField->getY() + mFirstEmailField->getHeight() + 7);
+ mSecondEmailField->setWidth(130);
+
+ mCancelButton->setPosition(
+ width - 5 - mCancelButton->getWidth(),
+ height - 5 - mCancelButton->getHeight());
+ mChangeEmailButton->setPosition(
+ mCancelButton->getX() - 5 - mChangeEmailButton->getWidth(),
+ mCancelButton->getY());
+
+ add(accountLabel);
+ add(newEmailLabel);
+ add(mFirstEmailField);
+ add(mSecondEmailField);
+ add(mChangeEmailButton);
+ add(mCancelButton);
+
+ setLocationRelativeTo(getParent());
+ setVisible(true);
+ mFirstEmailField->requestFocus();
+
+ mFirstEmailField->setActionEventId("change_email");
+ mSecondEmailField->setActionEventId("change_email");
+}
+
+ChangeEmailDialog::~ChangeEmailDialog()
+{
+ delete mWrongDataNoticeListener;
+}
+
+void
+ChangeEmailDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "cancel")
+ {
+ scheduleDelete();
+ }
+ else if (event.getId() == "change_email")
+ {
+
+ const std::string username = mLoginData->username.c_str();
+ const std::string newFirstEmail = mFirstEmailField->getText();
+ const std::string newSecondEmail = mSecondEmailField->getText();
+ logger->log("ChangeEmailDialog::Email change, Username is %s",
+ username.c_str());
+
+ std::stringstream errorMsg;
+ int error = 0;
+
+ if (newFirstEmail.length() < LEN_MIN_PASSWORD)
+ {
+ // First email address too short
+ errorMsg << "The new email address needs to be at least "
+ << LEN_MIN_PASSWORD
+ << " characters long.";
+ error = 1;
+ }
+ else if (newFirstEmail.length() > LEN_MAX_PASSWORD - 1 )
+ {
+ // First email address too long
+ errorMsg << "The new email address needs to be less than "
+ << LEN_MAX_PASSWORD
+ << " characters long.";
+ error = 1;
+ }
+ else if (newFirstEmail != newSecondEmail)
+ {
+ // Second Pass mismatch
+ errorMsg << "The email address entries mismatch.";
+ error = 2;
+ }
+
+ if (error > 0)
+ {
+ if (error == 1)
+ {
+ mWrongDataNoticeListener->setTarget(this->mFirstEmailField);
+ }
+ else if (error == 2)
+ {
+ mWrongDataNoticeListener->setTarget(this->mSecondEmailField);
+ }
+
+ OkDialog *dlg = new OkDialog("Error", errorMsg.str());
+ dlg->addActionListener(mWrongDataNoticeListener);
+ }
+ else
+ {
+ // No errors detected, change account password.
+ mChangeEmailButton->setEnabled(false);
+ // Set the new email address
+ mLoginData->newEmail = newFirstEmail;
+ state = STATE_CHANGEEMAIL_ATTEMPT;
+ scheduleDelete();
+ }
+
+ }
+}
diff --git a/src/gui/changeemaildialog.h b/src/gui/changeemaildialog.h
new file mode 100644
index 00000000..145c54b1
--- /dev/null
+++ b/src/gui/changeemaildialog.h
@@ -0,0 +1,72 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef GUI_CHANGEEMAIL_H
+#define GUI_CHANGEEMAIL_H
+
+#include <iosfwd>
+#include <guichan/actionlistener.hpp>
+
+#include "window.h"
+#include "../guichanfwd.h"
+
+class LoginData;
+class OkDialog;
+class WrongDataNoticeListener;
+
+/**
+ * The Change email dialog.
+ *
+ * \ingroup Interface
+ */
+class ChangeEmailDialog : public Window, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ *
+ * @see Window::Window
+ */
+ ChangeEmailDialog(Window *parent, LoginData *loginData);
+
+ /**
+ * Destructor.
+ */
+ ~ChangeEmailDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ private:
+ gcn::TextField *mFirstEmailField;
+ gcn::TextField *mSecondEmailField;
+
+ gcn::Button *mChangeEmailButton;
+ gcn::Button *mCancelButton;
+
+ WrongDataNoticeListener *mWrongDataNoticeListener;
+
+ LoginData *mLoginData;
+};
+
+#endif // GUI_CHANGEEMAIL_H
diff --git a/src/gui/changepassworddialog.cpp b/src/gui/changepassworddialog.cpp
new file mode 100644
index 00000000..7c1e5bcd
--- /dev/null
+++ b/src/gui/changepassworddialog.cpp
@@ -0,0 +1,193 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "changepassworddialog.h"
+
+#include <string>
+#include <sstream>
+
+#include <guichan/widgets/label.hpp>
+
+#include "../main.h"
+#include "../log.h"
+#include "../logindata.h"
+
+#include "button.h"
+#include "register.h"
+#include "passwordfield.h"
+#include "textfield.h"
+#include "ok_dialog.h"
+
+#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
+
+ChangePasswordDialog::ChangePasswordDialog(Window *parent, LoginData *loginData):
+ Window(_("Change Password"), true, parent),
+ mWrongDataNoticeListener(new WrongDataNoticeListener()),
+ mLoginData(loginData)
+{
+ gcn::Label *accountLabel = new gcn::Label(strprintf(_("Account: %s"),
+ mLoginData->username.c_str()));
+ gcn::Label *oldPassLabel = new gcn::Label(_("Password:"));
+ mOldPassField = new PasswordField();
+ gcn::Label *newPassLabel = new gcn::Label(_("Type New Password twice:"));
+ mFirstPassField = new PasswordField();
+ mSecondPassField = new PasswordField();
+ mChangePassButton = new Button(_("Change Password"), "change_password", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+
+ const int width = 200;
+ const int height = 170;
+ setContentSize(width, height);
+
+ accountLabel->setPosition(5, 5);
+ accountLabel->setWidth(130);
+ oldPassLabel->setPosition(
+ 5, accountLabel->getY() + accountLabel->getHeight() + 7);
+ oldPassLabel->setWidth(130);
+
+ mOldPassField->setPosition(
+ 5, oldPassLabel->getY() + oldPassLabel->getHeight() + 7);
+ mOldPassField->setWidth(130);
+
+ newPassLabel->setPosition(
+ 5, mOldPassField->getY() + mOldPassField->getHeight() + 7);
+ newPassLabel->setWidth(width - 5);
+
+ mFirstPassField->setPosition(
+ 5, newPassLabel->getY() + newPassLabel->getHeight() + 7);
+ mFirstPassField->setWidth(130);
+
+ mSecondPassField->setPosition(
+ 5, mFirstPassField->getY() + mFirstPassField->getHeight() + 7);
+ mSecondPassField->setWidth(130);
+
+ mCancelButton->setPosition(
+ width - 5 - mCancelButton->getWidth(),
+ height - 5 - mCancelButton->getHeight());
+ mChangePassButton->setPosition(
+ mCancelButton->getX() - 5 - mChangePassButton->getWidth(),
+ mCancelButton->getY());
+
+ add(accountLabel);
+ add(oldPassLabel);
+ add(mOldPassField);
+ add(newPassLabel);
+ add(mFirstPassField);
+ add(mSecondPassField);
+ add(mChangePassButton);
+ add(mCancelButton);
+
+ setLocationRelativeTo(getParent());
+ setVisible(true);
+ mOldPassField->requestFocus();
+
+ mOldPassField->setActionEventId("change_password");
+ mFirstPassField->setActionEventId("change_password");
+ mSecondPassField->setActionEventId("change_password");
+}
+
+ChangePasswordDialog::~ChangePasswordDialog()
+{
+ delete mWrongDataNoticeListener;
+}
+
+void
+ChangePasswordDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "cancel")
+ {
+ scheduleDelete();
+ }
+ else if (event.getId() == "change_password")
+ {
+
+ const std::string username = mLoginData->username.c_str();
+ const std::string oldPassword = mOldPassField->getText();
+ const std::string newFirstPass = mFirstPassField->getText();
+ const std::string newSecondPass = mSecondPassField->getText();
+ logger->log("ChangePasswordDialog::Password change, Username is %s",
+ username.c_str());
+
+ std::stringstream errorMsg;
+ int error = 0;
+
+ // Check old Password
+ if (oldPassword.empty())
+ {
+ // No old password
+ errorMsg << "Enter the old Password first.";
+ error = 1;
+ }
+ else if (newFirstPass.length() < LEN_MIN_PASSWORD)
+ {
+ // First password too short
+ errorMsg << "The new password needs to be at least "
+ << LEN_MIN_PASSWORD
+ << " characters long.";
+ error = 2;
+ }
+ else if (newFirstPass.length() > LEN_MAX_PASSWORD - 1 )
+ {
+ // First password too long
+ errorMsg << "The new password needs to be less than "
+ << LEN_MAX_PASSWORD
+ << " characters long.";
+ error = 2;
+ }
+ else if (newFirstPass != newSecondPass)
+ {
+ // Second Pass mismatch
+ errorMsg << "The new password entries mismatch.";
+ error = 3;
+ }
+
+ if (error > 0)
+ {
+ if (error == 1)
+ {
+ mWrongDataNoticeListener->setTarget(this->mOldPassField);
+ }
+ else if (error == 2)
+ {
+ mWrongDataNoticeListener->setTarget(this->mFirstPassField);
+ }
+ else if (error == 3)
+ {
+ mWrongDataNoticeListener->setTarget(this->mSecondPassField);
+ }
+
+ OkDialog *dlg = new OkDialog("Error", errorMsg.str());
+ dlg->addActionListener(mWrongDataNoticeListener);
+ }
+ else
+ {
+ // No errors detected, change account password.
+ mChangePassButton->setEnabled(false);
+ // Set the new password
+ mLoginData->password = oldPassword;
+ mLoginData->newPassword = newFirstPass;
+ state = STATE_CHANGEPASSWORD_ATTEMPT;
+ scheduleDelete();
+ }
+
+ }
+}
diff --git a/src/gui/changepassworddialog.h b/src/gui/changepassworddialog.h
new file mode 100644
index 00000000..ad1c0b2a
--- /dev/null
+++ b/src/gui/changepassworddialog.h
@@ -0,0 +1,72 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef CHANGEPASSWORDDIALOG_H
+#define CHANGEPASSWORDDIALOG_H
+
+#include <iosfwd>
+#include <guichan/actionlistener.hpp>
+
+#include "window.h"
+#include "../guichanfwd.h"
+
+class LoginData;
+class OkDialog;
+class WrongDataNoticeListener;
+
+/**
+ * The Change password dialog.
+ *
+ * \ingroup Interface
+ */
+class ChangePasswordDialog : public Window, public gcn::ActionListener {
+ public:
+ /**
+ * Constructor
+ *
+ * @see Window::Window
+ */
+ ChangePasswordDialog(Window *parent,LoginData *loginData);
+
+ /**
+ * Destructor
+ */
+ ~ChangePasswordDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ private:
+ gcn::TextField *mOldPassField;
+ gcn::TextField *mFirstPassField;
+ gcn::TextField *mSecondPassField;
+
+ gcn::Button *mChangePassButton;
+ gcn::Button *mCancelButton;
+
+ WrongDataNoticeListener *mWrongDataNoticeListener;
+
+ LoginData *mLoginData;
+};
+
+#endif
diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp
index f88736c1..4ab3d9ef 100644
--- a/src/gui/char_select.cpp
+++ b/src/gui/char_select.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,13 +31,29 @@
#include "playerbox.h"
#include "textfield.h"
+#ifdef TMWSERV_SUPPORT
+#include "radiobutton.h"
+#include "slider.h"
+
+#include "unregisterdialog.h"
+#include "changepassworddialog.h"
+#include "changeemaildialog.h"
+
+#include "../logindata.h"
+
+#include "../net/tmwserv/accountserver/account.h"
+#include "../net/tmwserv/charserverhandler.h"
+#else
+#include "../net/ea/charserverhandler.h"
+#endif
+
#include "widgets/layout.h"
#include "../game.h"
#include "../localplayer.h"
#include "../main.h"
+#include "../units.h"
-#include "../net/charserverhandler.h"
#include "../net/messageout.h"
#include "../resources/colordb.h"
@@ -47,6 +62,8 @@
#include "../utils/strprintf.h"
#include "../utils/stringutils.h"
+#define MAX_SLOT 2
+
// Defined in main.cpp, used here for setting the char create dialog
extern CharServerHandler charServerHandler;
@@ -79,30 +96,80 @@ void CharDeleteConfirm::action(const gcn::ActionEvent &event)
ConfirmDialog::action(event);
}
+#ifdef TMWSERV_SUPPORT
+CharSelectDialog::CharSelectDialog(LockedArray<LocalPlayer*> *charInfo,
+ LoginData *loginData):
+ Window(_("Account and Character Management")),
+ mCharInfo(charInfo), mCharSelected(false), mLoginData(loginData)
+#else
CharSelectDialog::CharSelectDialog(Network *network,
LockedArray<LocalPlayer*> *charInfo,
Gender gender):
Window(_("Select Character")), mNetwork(network),
- mCharInfo(charInfo), mGender(gender), mCharSelected(false)
+ mCharInfo(charInfo),
+ mCharSelected(false),
+ mGender(gender)
+#endif
{
+ mSelectButton = new Button(_("Ok"), "ok", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+ mPreviousButton = new Button(_("Previous"), "previous", this);
+ mNextButton = new Button(_("Next"), "next", this);
+ mNameLabel = new Label(strprintf(_("Name: %s"), ""));
+ mLevelLabel = new Label(strprintf(_("Level: %d"), 0));
+#ifdef TMWSERV_SUPPORT
+ mNewCharButton = new Button(_("New"), "new", this);
+ mDelCharButton = new Button(_("Delete"), "delete", this);
+ mUnRegisterButton = new Button(_("Unregister"), "unregister", this);
+ mChangePasswordButton = new Button(_("Change Password"), "change_password", this);
+ mChangeEmailButton = new Button(_("Change Email Address"), "change_email", this);
+
+ mAccountNameLabel = new Label(strprintf(_("Account: %s"), mLoginData->username.c_str()));
+ mNameLabel = new Label(strprintf(_("Name: %s"), ""));
+ mLevelLabel = new Label(strprintf(_("Level: %d"), 0));
+ mMoneyLabel = new Label(strprintf(_("Money: %d"), 0));
+
+ // Control that shows the Player
+ mPlayerBox = new PlayerBox;
+ mPlayerBox->setWidth(74);
+
+ ContainerPlacer place;
+ place = getPlacer(0, 0);
+ place(0, 0, mAccountNameLabel);
+ place(0, 1, mUnRegisterButton);
+ place(0, 2, mChangePasswordButton);
+ place(1, 2, mChangeEmailButton);
+ place = getPlacer(0, 1);
+ place(0, 0, mPlayerBox, 1, 5).setPadding(3);
+ place(1, 0, mNameLabel, 3);
+ place(1, 1, mLevelLabel, 3);
+ place(1, 2, mMoneyLabel, 3);
+ place(1, 3, mPreviousButton);
+ place(2, 3, mNextButton);
+ place(1, 4, mNewCharButton);
+ place(2, 4, mDelCharButton);
+ place.getCell().matchColWidth(1, 2);
+ place = getPlacer(0, 2);
+ place(0, 0, mSelectButton);
+ place(1, 0, mCancelButton);
+ reflowLayout(265, 0);
+#else
+ mCharInfo->select(0);
+ LocalPlayer *pi = mCharInfo->getEntry();
+ if (pi)
+ mMoney = Units::formatCurrency(pi->getMoney());
// Control that shows the Player
mPlayerBox = new PlayerBox;
mPlayerBox->setWidth(74);
- mNameLabel = new Label(strprintf(_("Name: %s"), ""));
- mLevelLabel = new Label(strprintf(_("Level: %d"), 0));
mJobLevelLabel = new Label(strprintf(_("Job Level: %d"), 0));
- mMoneyLabel = new Label(strprintf(_("Money: %d"), 0));
+ mMoneyLabel = new Label(strprintf(_("Money: %s"), mMoney.c_str()));
const std::string tempString = getFont()->getWidth(_("New")) <
getFont()->getWidth(_("Delete")) ?
_("Delete") : _("New");
- mPreviousButton = new Button(_("Previous"), "previous", this);
- mNextButton = new Button(_("Next"), "next", this);
mNewDelCharButton = new Button(tempString, "newdel", this);
- mSelectButton = new Button(_("Ok"), "ok", this);
- mCancelButton = new Button(_("Cancel"), "cancel", this);
ContainerPlacer place;
place = getPlacer(0, 0);
@@ -121,8 +188,9 @@ CharSelectDialog::CharSelectDialog(Network *network,
place(5, 0, mSelectButton);
reflowLayout(250, 0);
+#endif
- setLocationRelativeTo(getParent());
+ center();
setVisible(true);
mSelectButton->requestFocus();
updatePlayerInfo();
@@ -130,10 +198,21 @@ CharSelectDialog::CharSelectDialog(Network *network,
void CharSelectDialog::action(const gcn::ActionEvent &event)
{
+#ifdef TMWSERV_SUPPORT
+ // The pointers are set to NULL if there is no character stored
+ if (event.getId() == "ok" && (mCharInfo->getEntry()))
+#else
if (event.getId() == "ok" && n_character > 0)
+#endif
{
// Start game
+#ifdef TMWSERV_SUPPORT
+ mNewCharButton->setEnabled(false);
+ mDelCharButton->setEnabled(false);
+ mUnRegisterButton->setEnabled(false);
+#else
mNewDelCharButton->setEnabled(false);
+#endif
mSelectButton->setEnabled(false);
mPreviousButton->setEnabled(false);
mNextButton->setEnabled(false);
@@ -142,8 +221,35 @@ void CharSelectDialog::action(const gcn::ActionEvent &event)
}
else if (event.getId() == "cancel")
{
- state = EXIT_STATE;
+#ifdef TMWSERV_SUPPORT
+ mCharInfo->clear();
+ state = STATE_SWITCH_ACCOUNTSERVER_ATTEMPT;
+#else
+ state = STATE_EXIT;
+#endif
+ }
+#ifdef TMWSERV_SUPPORT
+ else if (event.getId() == "new")
+ {
+ // TODO: Search the first free slot, and start CharCreateDialog
+ // maybe add that search to the constructor.
+ if (!(mCharInfo->getEntry()))
+ {
+ // Start new character dialog
+ CharCreateDialog *charCreateDialog =
+ new CharCreateDialog(this, mCharInfo->getPos());
+ charServerHandler.setCharCreateDialog(charCreateDialog);
+ }
+ }
+ else if (event.getId() == "delete")
+ {
+ // Delete character
+ if (mCharInfo->getEntry())
+ {
+ new CharDeleteConfirm(this);
+ }
}
+#else
else if (event.getId() == "newdel")
{
// Check for a character
@@ -160,14 +266,35 @@ void CharSelectDialog::action(const gcn::ActionEvent &event)
charServerHandler.setCharCreateDialog(charCreateDialog);
}
}
+#endif
else if (event.getId() == "previous")
{
mCharInfo->prev();
+ LocalPlayer *pi = mCharInfo->getEntry();
+ if (pi)
+ mMoney = Units::formatCurrency(pi->getMoney());
}
else if (event.getId() == "next")
{
mCharInfo->next();
+ LocalPlayer *pi = mCharInfo->getEntry();
+ if (pi)
+ mMoney = Units::formatCurrency(pi->getMoney());
+ }
+#ifdef TMWSERV_SUPPORT
+ else if (event.getId() == "unregister")
+ {
+ new UnRegisterDialog(this, mLoginData);
+ }
+ else if (event.getId() == "change_password")
+ {
+ new ChangePasswordDialog(this, mLoginData);
}
+ else if (event.getId() == "change_email")
+ {
+ new ChangeEmailDialog(this, mLoginData);
+ }
+#endif
}
void CharSelectDialog::updatePlayerInfo()
@@ -176,13 +303,22 @@ void CharSelectDialog::updatePlayerInfo()
if (pi)
{
- mNameLabel->setCaption(strprintf(_("Name: %s"), pi->getName().c_str()));
- mLevelLabel->setCaption(strprintf(_("Level: %d"), pi->mLevel));
- mJobLevelLabel->setCaption(strprintf(_("Job Level: %d"), pi->mJobLevel));
- mMoneyLabel->setCaption(strprintf(_("Gold: %d"), pi->mGp));
+ mNameLabel->setCaption(strprintf(_("Name: %s"),
+ pi->getName().c_str()));
+ mLevelLabel->setCaption(strprintf(_("Level: %d"), pi->getLevel()));
+#ifndef TMWSERV_SUPPORT
+ mJobLevelLabel->setCaption(strprintf(_("Job Level: %d"),
+ pi->mJobLevel));
+#endif
+ mMoneyLabel->setCaption(strprintf(_("Money: %s"), mMoney.c_str()));
if (!mCharSelected)
{
+#ifdef TMWSERV_SUPPORT
+ mNewCharButton->setEnabled(false);
+ mDelCharButton->setEnabled(true);
+#else
mNewDelCharButton->setCaption(_("Delete"));
+#endif
mSelectButton->setEnabled(true);
}
}
@@ -190,9 +326,16 @@ void CharSelectDialog::updatePlayerInfo()
{
mNameLabel->setCaption(strprintf(_("Name: %s"), ""));
mLevelLabel->setCaption(strprintf(_("Level: %d"), 0));
+#ifndef TMWSERV_SUPPORT
mJobLevelLabel->setCaption(strprintf(_("Job Level: %d"), 0));
+#endif
mMoneyLabel->setCaption(strprintf(_("Money: %s"), ""));
+#ifdef TMWSERV_SUPPORT
+ mNewCharButton->setEnabled(true);
+ mDelCharButton->setEnabled(false);
+#else
mNewDelCharButton->setCaption(_("New"));
+#endif
mSelectButton->setEnabled(false);
}
@@ -201,20 +344,28 @@ void CharSelectDialog::updatePlayerInfo()
void CharSelectDialog::attemptCharDelete()
{
+#ifdef TMWSERV_SUPPORT
+ Net::AccountServer::Account::deleteCharacter(mCharInfo->getPos());
+#else
// Request character deletion
MessageOut outMsg(mNetwork);
outMsg.writeInt16(0x0068);
outMsg.writeInt32(mCharInfo->getEntry()->mCharId);
outMsg.writeString("a@a.com", 40);
+#endif
mCharInfo->lock();
}
void CharSelectDialog::attemptCharSelect()
{
+#ifdef TMWSERV_SUPPORT
+ Net::AccountServer::Account::selectCharacter(mCharInfo->getPos());
+#else
// Request character selection
MessageOut outMsg(mNetwork);
outMsg.writeInt16(0x0066);
outMsg.writeInt8(mCharInfo->getPos());
+#endif
mCharInfo->lock();
}
@@ -246,16 +397,29 @@ bool CharSelectDialog::selectByName(const std::string &name)
return false;
}
+#ifdef TMWSERV_SUPPORT
+CharCreateDialog::CharCreateDialog(Window *parent, int slot):
+#else
CharCreateDialog::CharCreateDialog(Window *parent, int slot, Network *network,
Gender gender):
- Window(_("Create Character"), true, parent), mNetwork(network), mSlot(slot)
+#endif
+ Window(_("Create Character"), true, parent),
+#ifndef TMWSERV_SUPPORT
+ mNetwork(network),
+#endif
+ mSlot(slot)
{
mPlayer = new Player(0, 0, NULL);
+#ifdef TMWSERV_SUPPORT
+ mPlayer->setGender(GENDER_MALE);
+#else
mPlayer->setGender(gender);
+#endif
int numberOfHairColors = ColorDB::size();
- mPlayer->setHairStyle(rand() % mPlayer->getNumOfHairstyles(), rand() % numberOfHairColors);
+ mPlayer->setHairStyle(rand() % mPlayer->getNumOfHairstyles(),
+ rand() % numberOfHairColors);
mNameField = new TextField("");
mNameLabel = new Label(_("Name:"));
@@ -267,6 +431,19 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot, Network *network,
mHairStyleLabel = new Label(_("Hair Style:"));
mCreateButton = new Button(_("Create"), "create", this);
mCancelButton = new Button(_("Cancel"), "cancel", this);
+#ifdef TMWSERV_SUPPORT
+ mMale = new RadioButton(_("Male"), "gender");
+ mFemale = new RadioButton(_("Female"), "gender");
+
+ // Default to a Male character
+ mMale->setSelected(true);
+
+ mMale->setActionEventId("gender");
+ mFemale->setActionEventId("gender");
+
+ mMale->addActionListener(this);
+ mFemale->addActionListener(this);
+#endif
mPlayerBox = new PlayerBox(mPlayer);
mPlayerBox->setWidth(74);
@@ -274,6 +451,81 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot, Network *network,
mNameField->setActionEventId("create");
mNameField->addActionListener(this);
+#ifdef TMWSERV_SUPPORT
+ mAttributeLabel[0] = new gcn::Label(_("Strength:"));
+ mAttributeLabel[1] = new gcn::Label(_("Agility:"));
+ mAttributeLabel[2] = new gcn::Label(_("Dexterity:"));
+ mAttributeLabel[3] = new gcn::Label(_("Vitality:"));
+ mAttributeLabel[4] = new gcn::Label(_("Intelligence:"));
+ mAttributeLabel[5] = new gcn::Label(_("Willpower:"));
+ for (int i = 0; i < 6; i++)
+ {
+ mAttributeLabel[i]->setWidth(70);
+ mAttributeSlider[i] = new Slider(1, 20);
+ mAttributeValue[i] = new gcn::Label("1");
+ };
+
+ mAttributesLeft = new gcn::Label(strprintf(_("Please distribute %d points"), 99));
+
+ int w = 200;
+ int h = 330;
+ setContentSize(w, h);
+ mPlayerBox->setDimension(gcn::Rectangle(80, 30, 110, 85));
+ mNameLabel->setPosition(5, 5);
+ mNameField->setDimension(
+ gcn::Rectangle(45, 5, w - 45 - 7, mNameField->getHeight()));
+ mPrevHairColorButton->setPosition(90, 35);
+ mNextHairColorButton->setPosition(165, 35);
+ mHairColorLabel->setPosition(5, 40);
+ mPrevHairStyleButton->setPosition(90, 64);
+ mNextHairStyleButton->setPosition(165, 64);
+ mHairStyleLabel->setPosition(5, 70);
+ for (int i=0; i<6; i++)
+ {
+ mAttributeSlider[i]->setValue(10);
+ mAttributeSlider[i]->setDimension(gcn::Rectangle( 75, 140 + i*20,
+ 100, 10));
+ mAttributeSlider[i]->setActionEventId("statslider");
+ mAttributeSlider[i]->addActionListener(this);
+ mAttributeValue[i]->setPosition(180, 140 + i*20);
+ mAttributeLabel[i]->setPosition(5, 140 + i*20);
+ };
+ mAttributesLeft->setPosition(15, 280);
+ updateSliders();
+ mCancelButton->setPosition(
+ w - 5 - mCancelButton->getWidth(),
+ h - 5 - mCancelButton->getHeight());
+ mCreateButton->setPosition(
+ mCancelButton->getX() - 5 - mCreateButton->getWidth(),
+ h - 5 - mCancelButton->getHeight());
+
+ mMale->setPosition(30, 120);
+ mFemale->setPosition(100, 120);
+
+ add(mPlayerBox);
+ add(mNameField);
+ add(mNameLabel);
+ add(mNextHairColorButton);
+ add(mPrevHairColorButton);
+ add(mHairColorLabel);
+ add(mNextHairStyleButton);
+ add(mPrevHairStyleButton);
+ add(mHairStyleLabel);
+ for (int i = 0; i < 6; i++)
+ {
+ add(mAttributeSlider[i]);
+ add(mAttributeValue[i]);
+ add(mAttributeLabel[i]);
+ };
+ add(mAttributesLeft);
+ add(mCreateButton);
+ add(mCancelButton);
+
+ add(mMale);
+ add(mFemale);
+
+#else
+
ContainerPlacer place;
place = getPlacer(0, 0);
@@ -292,8 +544,9 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot, Network *network,
place(5, 0, mCreateButton);
reflowLayout(225, 0);
+#endif
- setLocationRelativeTo(getParent());
+ center();
setVisible(true);
mNameField->requestFocus();
}
@@ -315,12 +568,35 @@ void CharCreateDialog::action(const gcn::ActionEvent &event)
{
// Attempt to create the character
mCreateButton->setEnabled(false);
+#ifdef TMWSERV_SUPPORT
+ unsigned int genderSelected;
+ if (mMale->isSelected()) {
+ genderSelected = GENDER_MALE;
+ } else {
+ genderSelected = GENDER_FEMALE;
+ }
+
+ Net::AccountServer::Account::createCharacter(
+ getName(),
+ mPlayer->getHairStyle(),
+ mPlayer->getHairColor(),
+ genderSelected, // 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
+ );
+#else
attemptCharCreate();
+#endif
}
else
{
- new OkDialog("Error",
- "Your name needs to be at least 4 characters.", this);
+ new OkDialog(_("Error"),
+ _("Your name needs to be at least 4 characters."),
+ this);
}
}
else if (event.getId() == "cancel")
@@ -339,6 +615,18 @@ void CharCreateDialog::action(const gcn::ActionEvent &event)
mPlayer->setHairStyle(mPlayer->getHairStyle() +
mPlayer->getNumOfHairstyles() - 1,
mPlayer->getHairColor());
+#ifdef TMWSERV_SUPPORT
+ else if (event.getId() == "statslider") {
+ updateSliders();
+ }
+ else if (event.getId() == "gender"){
+ if (mMale->isSelected()) {
+ mPlayer->setGender(GENDER_MALE);
+ } else {
+ mPlayer->setGender(GENDER_FEMALE);
+ }
+ }
+#endif
}
std::string CharCreateDialog::getName()
@@ -348,11 +636,60 @@ std::string CharCreateDialog::getName()
return name;
}
+#ifdef TMWSERV_SUPPORT
+void CharCreateDialog::updateSliders()
+{
+ for (int i = 0; i < 6; i++)
+ {
+ // Update captions
+ mAttributeValue[i]->setCaption(
+ toString((int) (mAttributeSlider[i]->getValue())));
+ mAttributeValue[i]->adjustSize();
+ }
+
+ // Update distributed points
+ int pointsLeft = 60 - getDistributedPoints();
+ if (pointsLeft == 0)
+ {
+ mAttributesLeft->setCaption(_("Character stats OK"));
+ mCreateButton->setEnabled(true);
+ }
+ else
+ {
+ mCreateButton->setEnabled(false);
+ if (pointsLeft > 0)
+ {
+ mAttributesLeft->setCaption(strprintf(_("Please distribute %d points"), pointsLeft));
+ }
+ else
+ {
+ mAttributesLeft->setCaption(strprintf(_("Please remove %d points"), -pointsLeft));
+ }
+ }
+
+ mAttributesLeft->adjustSize();
+}
+#endif
+
void CharCreateDialog::unlock()
{
mCreateButton->setEnabled(true);
}
+#ifdef TMWSERV_SUPPORT
+int CharCreateDialog::getDistributedPoints()
+{
+ int points = 0;
+
+ for (int i = 0; i < 6; i++)
+ {
+ points += (int) mAttributeSlider[i]->getValue();
+ }
+ return points;
+}
+#endif
+
+#ifndef TMWSERV_SUPPORT
void CharCreateDialog::attemptCharCreate()
{
// Send character infos
@@ -369,3 +706,4 @@ void CharCreateDialog::attemptCharCreate()
outMsg.writeInt16(mPlayer->getHairColor());
outMsg.writeInt16(mPlayer->getHairStyle());
}
+#endif
diff --git a/src/gui/char_select.h b/src/gui/char_select.h
index 037b809f..7f376692 100644
--- a/src/gui/char_select.h
+++ b/src/gui/char_select.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,10 +27,16 @@
#include "window.h"
#include "../being.h"
+#include "../guichanfwd.h"
#include "../lockedarray.h"
-class LocalPlayer;
+#ifdef TMWSERV_SUPPORT
+#include "../logindata.h"
+#else
class Network;
+#endif
+
+class LocalPlayer;
class Player;
class PlayerBox;
@@ -47,9 +52,14 @@ class CharSelectDialog : public Window, public gcn::ActionListener
/**
* Constructor.
*/
+#ifdef TMWSERV_SUPPORT
+ CharSelectDialog(LockedArray<LocalPlayer*> *charInfo,
+ LoginData *loginData);
+#else
CharSelectDialog(Network *network,
LockedArray<LocalPlayer*> *charInfo,
Gender gender);
+#endif
void action(const gcn::ActionEvent &event);
@@ -60,25 +70,40 @@ class CharSelectDialog : public Window, public gcn::ActionListener
bool selectByName(const std::string &name);
private:
+#ifdef EATHENA_SUPPORT
Network *mNetwork;
+#endif
LockedArray<LocalPlayer*> *mCharInfo;
gcn::Button *mSelectButton;
gcn::Button *mCancelButton;
- gcn::Button *mNewDelCharButton;
gcn::Button *mPreviousButton;
gcn::Button *mNextButton;
gcn::Label *mNameLabel;
gcn::Label *mLevelLabel;
- gcn::Label *mJobLevelLabel;
gcn::Label *mMoneyLabel;
+ std::string mMoney;
PlayerBox *mPlayerBox;
- Gender mGender;
bool mCharSelected;
+#ifdef TMWSERV_SUPPORT
+ gcn::Button *mNewCharButton;
+ gcn::Button *mDelCharButton;
+ gcn::Button *mUnRegisterButton;
+ gcn::Button *mChangePasswordButton;
+ gcn::Button *mChangeEmailButton;
+ gcn::Label *mAccountNameLabel;
+
+ LoginData *mLoginData;
+#else
+ gcn::Button *mNewDelCharButton;
+ gcn::Label *mJobLevelLabel;
+ Gender mGender;
+#endif
+
/**
* Communicate character deletion to the server.
*/
@@ -93,7 +118,7 @@ class CharSelectDialog : public Window, public gcn::ActionListener
/**
* Character creation dialog.
*
- * \ingroup GUI
+ * \ingroup Interface
*/
class CharCreateDialog : public Window, public gcn::ActionListener
{
@@ -101,8 +126,12 @@ class CharCreateDialog : public Window, public gcn::ActionListener
/**
* Constructor.
*/
+#ifdef TMWSERV_SUPPORT
+ CharCreateDialog(Window *parent, int slot);
+#else
CharCreateDialog(Window *parent, int slot, Network *network,
Gender gender);
+#endif
/**
* Destructor.
@@ -117,6 +146,12 @@ class CharCreateDialog : public Window, public gcn::ActionListener
void unlock();
private:
+#ifdef TMWSERV_SUPPORT
+ int getDistributedPoints();
+
+ void updateSliders();
+#endif
+
/**
* Returns the name of the character to create.
*/
@@ -127,7 +162,9 @@ class CharCreateDialog : public Window, public gcn::ActionListener
*/
void attemptCharCreate();
+#ifdef EATHENA_SUPPORT
Network *mNetwork;
+#endif
gcn::TextField *mNameField;
gcn::Label *mNameLabel;
gcn::Button *mNextHairColorButton;
@@ -136,6 +173,20 @@ class CharCreateDialog : public Window, public gcn::ActionListener
gcn::Button *mNextHairStyleButton;
gcn::Button *mPrevHairStyleButton;
gcn::Label *mHairStyleLabel;
+
+#ifdef TMWSERV_SUPPORT
+ gcn::RadioButton *mMale;
+ gcn::RadioButton *mFemale;
+
+ gcn::Slider *mAttributeSlider[6];
+ gcn::Label *mAttributeLabel[6];
+ gcn::Label *mAttributeValue[6];
+ gcn::Label *mAttributesLeft;
+
+ static const int mMaxPoints = 60;
+ int mUsedPoints;
+#endif
+
gcn::Button *mCreateButton;
gcn::Button *mCancelButton;
diff --git a/src/gui/char_server.cpp b/src/gui/char_server.cpp
index 6977a104..5cfcef4d 100644
--- a/src/gui/char_server.cpp
+++ b/src/gui/char_server.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -51,7 +50,7 @@ ServerSelectDialog::ServerSelectDialog(LoginData *loginData, int nextState):
mLoginData(loginData),
mNextState(nextState)
{
- mServerListModel = new ServerListModel();
+ mServerListModel = new ServerListModel;
mServerList = new ListBox(mServerListModel);
ScrollArea *mScrollArea = new ScrollArea(mServerList);
mOkButton = new Button(_("OK"), "ok", this);
@@ -86,7 +85,7 @@ ServerSelectDialog::ServerSelectDialog(LoginData *loginData, int nextState):
// Select first server
mServerList->setSelected(1);
- setLocationRelativeTo(getParent());
+ center();
setVisible(true);
mOkButton->requestFocus();
}
@@ -108,7 +107,7 @@ void ServerSelectDialog::action(const gcn::ActionEvent &event)
state = mNextState;
}
else if (event.getId() == "cancel")
- state = LOGIN_STATE;
+ state = STATE_LOGIN;
}
int ServerListModel::getNumberOfElements()
diff --git a/src/gui/char_server.h b/src/gui/char_server.h
index 207fb86e..49a5b47b 100644
--- a/src/gui/char_server.h
+++ b/src/gui/char_server.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp
index 5ff9ed46..7861bdb6 100644
--- a/src/gui/chat.cpp
+++ b/src/gui/chat.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,68 +19,52 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <guichan/focushandler.hpp>
-
-#include "browserbox.h"
#include "chat.h"
-#include "chatinput.h"
-#include "itemlinkhandler.h"
-#include "recorder.h"
-#include "scrollarea.h"
-#include "sdlinput.h"
-#include "windowcontainer.h"
-#include "widgets/layout.h"
+#include "gui/chatinput.h"
+#include "gui/itemlinkhandler.h"
+#include "gui/recorder.h"
+#include "gui/scrollarea.h"
+#include "gui/sdlinput.h"
-#include "../beingmanager.h"
-#include "../configuration.h"
-#include "../game.h"
-#include "../localplayer.h"
-#include "../party.h"
+#include "gui/widgets/tabbedarea.h"
+#include "gui/widgets/whispertab.h"
-#include "../net/messageout.h"
-#include "../net/protocol.h"
+#include "beingmanager.h"
+#include "configuration.h"
+#include "localplayer.h"
-#include "../resources/iteminfo.h"
-#include "../resources/itemdb.h"
+#include "utils/dtor.h"
+#include "utils/stringutils.h"
-#include "../utils/gettext.h"
-#include "../utils/strprintf.h"
-#include "../utils/stringutils.h"
+#include <guichan/focushandler.hpp>
+#ifdef TMWSERV_SUPPORT
+ChatWindow::ChatWindow():
+ Window("Chat"),
+#else
ChatWindow::ChatWindow(Network * network):
-Window(""), mNetwork(network), mTmpVisible(false)
+ Window(""), mNetwork(network),
+#endif
+ mTmpVisible(false)
{
- setWindowName(_("Chat"));
+ setWindowName("Chat");
setResizable(true);
setDefaultSize(600, 123, ImageRect::LOWER_LEFT);
setMinWidth(150);
setMinHeight(90);
- mItemLinkHandler = new ItemLinkHandler();
+ mItemLinkHandler = new ItemLinkHandler;
mChatInput = new ChatInput;
mChatInput->setActionEventId("chatinput");
mChatInput->addActionListener(this);
- mTextOutput = new BrowserBox(BrowserBox::AUTO_WRAP);
- mTextOutput->setOpaque(false);
- mTextOutput->setMaxRow((int) config.getValue("ChatLogLength", 0));
- mTextOutput->setLinkHandler(mItemLinkHandler);
-
- mScrollArea = new ScrollArea(mTextOutput);
- mScrollArea->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER,
- gcn::ScrollArea::SHOW_ALWAYS);
- mScrollArea->setScrollAmount(0, 1);
- mScrollArea->setOpaque(false);
+ mChatTabs = new TabbedArea();
- place(0, 0, mScrollArea, 5, 5).setPadding(0);
- place(0, 5, mChatInput, 5).setPadding(1);
-
- Layout &layout = getLayout();
- layout.setRowHeight(0, Layout::AUTO_SET);
- layout.setMargin(2);
+ add(mChatTabs);
+ add(mChatInput);
loadWindowState();
@@ -89,28 +72,33 @@ Window(""), mNetwork(network), mTmpVisible(false)
mChatInput->addKeyListener(this);
mCurHist = mHistory.end();
+#ifdef EATHENA_SUPPORT
// Read the party prefix
std::string partyPrefix = config.getValue("PartyPrefix", "$");
mPartyPrefix = (partyPrefix.empty() ? '$' : partyPrefix.at(0));
mReturnToggles = config.getValue("ReturnToggles", "0") == "1";
- mRecorder = new Recorder(this);
- mParty = new Party(this, mNetwork);
// If the player had @assert on in the last session, ask the server to
// run the @assert command for the player again. Convenience for GMs.
- if (config.getValue(player_node->getName() + "GMassert", 0))
- chatSend(player_node->getName(), "@assert");
+ if (config.getValue(player_node->getName() + "GMassert", 0)) {
+ std::string cmd = "@assert";
+ chatSend(cmd);
+ }
+#endif
+ mRecorder = new Recorder(this);
}
ChatWindow::~ChatWindow()
{
+#ifdef EATHENA_SUPPORT
char partyPrefix[2] = ".";
*partyPrefix = mPartyPrefix;
config.setValue("PartyPrefix", partyPrefix);
config.setValue("ReturnToggles", mReturnToggles ? "1" : "0");
delete mRecorder;
+#endif
+ delete_all(mWhispers);
delete mItemLinkHandler;
- delete mParty;
}
void ChatWindow::resetToDefaultSize()
@@ -119,178 +107,63 @@ void ChatWindow::resetToDefaultSize()
Window::resetToDefaultSize();
}
-void ChatWindow::chatLog(std::string line, int own, bool ignoreRecord)
+void ChatWindow::adjustTabSize()
{
- // Trim whitespace
- trim(line);
-
- if (line.empty())
- return;
-
- CHATLOG tmp;
- tmp.own = own;
- tmp.nick = "";
- tmp.text = line;
-
- std::string::size_type pos = line.find(" : ");
- if (pos != std::string::npos)
- {
- tmp.nick = line.substr(0, pos);
- tmp.text = line.substr(pos + 3);
- }
- else
- {
- // Fix the owner of welcome message.
- if (line.substr(0, 7) == "Welcome")
- {
- own = BY_SERVER;
- }
- }
-
- // *implements actions in a backwards compatible way*
- if (own == BY_PLAYER &&
- tmp.text.at(0) == '*' &&
- tmp.text.at(tmp.text.length()-1) == '*')
- {
- tmp.text[0] = ' ';
- tmp.text.erase(tmp.text.length() - 1);
- own = ACT_IS;
- }
+ const gcn::Rectangle area = getChildrenArea();
- std::string lineColor = "##C";
- switch (own)
- {
- case BY_GM:
- if (tmp.nick.empty())
- {
- tmp.nick = std::string(_("Global announcement: "));
- lineColor = "##G";
- }
- else
- {
- tmp.nick = strprintf(_("Global announcement from %s: "),
- tmp.nick.c_str());
- lineColor = "##1"; // Equiv. to BrowserBox::RED
- }
- break;
- case BY_PLAYER:
- tmp.nick += CAT_NORMAL;
- lineColor = "##Y";
- break;
- case BY_OTHER:
- tmp.nick += CAT_NORMAL;
- lineColor = "##C";
- break;
- case BY_SERVER:
- tmp.nick = _("Server:");
- tmp.nick += " ";
- tmp.text = line;
- lineColor = "##S";
- break;
- case BY_PARTY:
- tmp.nick += CAT_NORMAL;
- lineColor = "##P";
- break;
- case ACT_WHISPER:
- tmp.nick += CAT_WHISPER;
- lineColor = "##W";
- break;
- case ACT_IS:
- tmp.nick += CAT_IS;
- lineColor = "##I";
- break;
- case BY_LOGGER:
- tmp.nick = "";
- tmp.text = line;
- lineColor = "##L";
- break;
- }
+ mChatInput->setPosition(mChatInput->getFrameSize(),
+ area.height - mChatInput->getHeight() -
+ mChatInput->getFrameSize());
+ mChatInput->setWidth(area.width - 2 * mChatInput->getFrameSize());
- if (tmp.nick == ": ")
- {
- tmp.nick = "";
- lineColor = "##S";
- }
+ mChatTabs->setWidth(area.width - 2 * mChatTabs->getFrameSize());
+ mChatTabs->setHeight(area.height - 2 * mChatTabs->getFrameSize() -
+ (mChatInput->getHeight() + mChatInput->getFrameSize() * 2));
- if (tmp.nick.empty() && tmp.text.substr(0, 17) == "Visible GM status")
- {
- player_node->setGM();
+ ChatTab *tab = getFocused();
+ if (tab) {
+ gcn::Widget *content = tab->mScrollArea;
+ content->setSize(mChatTabs->getWidth() - 2 * content->getFrameSize(),
+ mChatTabs->getContainerHeight() - 2 * content->getFrameSize());
+ content->logic();
}
+}
- // Get the current system time
- time_t t;
- time(&t);
-
- // Format the time string properly
- std::stringstream timeStr;
- timeStr << "[" << ((((t / 60) / 60) % 24 < 10) ? "0" : "")
- << (int) (((t / 60) / 60) % 24)
- << ":" << (((t / 60) % 60 < 10) ? "0" : "")
- << (int) ((t / 60) % 60)
- << "] ";
-
- // Check for item link
- std::string::size_type start = tmp.text.find('[');
- while (start != std::string::npos && tmp.text[start+1] != '@')
- {
- std::string::size_type end = tmp.text.find(']', start);
- if (start+1 != end && end != std::string::npos)
- {
- // Catch multiple embeds and ignore them
- // so it doesn't crash the client.
- while ((tmp.text.find('[', start + 1) != std::string::npos) &&
- (tmp.text.find('[', start + 1) < end))
- {
- start = tmp.text.find('[', start + 1);
- }
-
- std::string temp = tmp.text.substr(start+1, end - start - 1);
+void ChatWindow::widgetResized(const gcn::Event &event)
+{
+ Window::widgetResized(event);
- trim(temp);
+ adjustTabSize();
+}
- for (unsigned int i = 0; i < temp.size(); i++)
- {
- temp[i] = (char) tolower(temp[i]);
- }
+void ChatWindow::logic()
+{
+ Window::logic();
- const ItemInfo itemInfo = ItemDB::get(temp);
- if (itemInfo.getName() != _("Unknown item"))
- {
- tmp.text.insert(end, "@@");
- tmp.text.insert(start+1, "|");
- tmp.text.insert(start+1, toString(itemInfo.getId()));
- tmp.text.insert(start+1, "@@");
- }
- }
- start = tmp.text.find('[', start + 1);
+ Tab *tab = getFocused();
+ if (tab != mCurrentTab) {
+ mCurrentTab = tab;
+ adjustTabSize();
}
+}
- line = lineColor + timeStr.str() + tmp.nick + tmp.text;
-
- // We look if the Vertical Scroll Bar is set at the max before
- // adding a row, otherwise the max will always be a row higher
- // at comparison.
- if (mScrollArea->getVerticalScrollAmount() ==
- mScrollArea->getVerticalMaxScroll())
- {
- mTextOutput->addRow(line);
- mScrollArea->setVerticalScrollAmount(mScrollArea->
- getVerticalMaxScroll());
- }
- else
- {
- mTextOutput->addRow(line);
- }
+ChatTab *ChatWindow::getFocused() const
+{
+ return dynamic_cast<ChatTab*>(mChatTabs->getSelectedTab());
+}
- mRecorder->record(line.substr(3));
+void ChatWindow::clearTab(ChatTab *tab)
+{
+ if (tab)
+ tab->clearText();
}
-void ChatWindow::chatLog(CHATSKILL act)
+void ChatWindow::clearTab()
{
- chatLog(const_msg(act), BY_SERVER);
+ clearTab(getFocused());
}
-void ChatWindow::action(const gcn::ActionEvent & event)
+void ChatWindow::action(const gcn::ActionEvent &event)
{
if (event.getId() == "chatinput")
{
@@ -307,7 +180,7 @@ void ChatWindow::action(const gcn::ActionEvent & event)
mCurHist = mHistory.end();
// Send the message to the server
- chatSend(player_node->getName(), message);
+ chatSend(message);
// Clear the text from the chat input
mChatInput->setText("");
@@ -326,7 +199,7 @@ void ChatWindow::action(const gcn::ActionEvent & event)
}
}
-void ChatWindow::requestChatFocus()
+bool ChatWindow::requestChatFocus()
{
// Make sure chatWindow is visible
if (!isVisible())
@@ -341,9 +214,14 @@ void ChatWindow::requestChatFocus()
mTmpVisible = true;
}
+ // Don't do anything else if the input is already visible and has focus
+ if (mChatInput->isVisible() && mChatInput->isFocused())
+ return false;
+
// Give focus to the chat input
mChatInput->setVisible(true);
mChatInput->requestFocus();
+ return true;
}
bool ChatWindow::isInputFocused()
@@ -351,376 +229,74 @@ bool ChatWindow::isInputFocused()
return mChatInput->isFocused();
}
-void ChatWindow::whisper(const std::string &nick, std::string msg)
+void ChatWindow::removeTab(ChatTab *tab)
{
- std::string recvnick = "";
-
- if (msg.substr(0, 1) == "\"")
- {
- const std::string::size_type pos = msg.find('"', 1);
- if (pos != std::string::npos)
- {
- recvnick = msg.substr(1, pos - 1);
- msg.erase(0, pos + 2);
- }
- }
- else
- {
- const std::string::size_type pos = msg.find(" ");
- if (pos != std::string::npos)
- {
- recvnick = msg.substr(0, pos);
- msg.erase(0, pos + 1);
- }
- }
-
- trim(msg);
-
- std::string playerName = player_node->getName();
- std::string tempNick = recvnick;
-
- toLower(playerName);
- toLower(tempNick);
-
- if (tempNick.compare(playerName) == 0 || msg.empty())
- return;
-
- MessageOut outMsg(mNetwork);
- outMsg.writeInt16(CMSG_CHAT_WHISPER);
- outMsg.writeInt16(msg.length() + 28);
- outMsg.writeString(recvnick, 24);
- outMsg.writeString(msg, msg.length());
-
- chatLog(strprintf(_("Whispering to %s: %s"),
- recvnick.c_str(), msg.c_str()),
- BY_PLAYER);
+ // Prevent removal of the local chat tab
+ if (tab != localChatTab) mChatTabs->removeTab(tab);
}
-void ChatWindow::chatSend(const std::string &nick, std::string msg)
+void ChatWindow::addTab(ChatTab *tab)
{
- /* Some messages are managed client side, while others
- * require server handling by proper packet. Probably
- * those if elses should be replaced by protocol calls */
-
- trim(msg);
+ // Make sure we don't end up with duplicates in the gui
+ // TODO
- if (msg.compare("") == 0)
- return;
-
- // Send party message
- if (msg.at(0) == mPartyPrefix)
- {
- msg.erase(0, 1);
- std::size_t length = msg.length() + 1;
+ mChatTabs->addTab(tab, tab->mScrollArea);
- if (length == 0)
- {
- chatLog(_("Trying to send a blank party message."), BY_SERVER);
- return;
- }
- MessageOut outMsg(mNetwork);
-
- outMsg.writeInt16(CMSG_PARTY_MESSAGE);
- outMsg.writeInt16(length + 4);
- outMsg.writeString(msg, length);
- return;
- }
-
- // Prepare ordinary message
- if (msg.substr(0, 1) != "/")
- {
- msg = nick + " : " + msg;
-
- MessageOut outMsg(mNetwork);
- outMsg.writeInt16(CMSG_CHAT_MESSAGE);
- // Added + 1 in order to let eAthena parse admin commands correctly
- outMsg.writeInt16(msg.length() + 4 + 1);
- outMsg.writeString(msg, msg.length() + 1);
- return;
- }
-
- msg.erase(0, 1);
- trim(msg);
-
- std::size_t space = msg.find(" ");
- std::string command = msg.substr(0, space);
-
- if (space == std::string::npos)
- {
- msg = "";
- }
- else
- {
- msg = msg.substr(space);
- trim(msg);
- }
-
- if (command == "announce")
- {
- MessageOut outMsg(mNetwork);
- outMsg.writeInt16(0x0099);
- outMsg.writeInt16(msg.length() + 4);
- outMsg.writeString(msg, msg.length());
- }
- else if (command == "help")
- {
- trim(msg);
- std::size_t space = msg.find(" ");
- std::string msg1;
-
- if (space == std::string::npos)
- {
- msg1 = "";
- }
- else
- {
- msg1 = msg.substr(space + 1, msg.length());
- msg = msg.substr(0, space);
- }
-
- if (!msg.empty() && msg.at(0) == '/')
- {
- msg.erase(0, 1);
- }
+ // Fix for layout issues when adding the first tab
+ if (tab == localChatTab)
+ adjustTabSize();
- trim(msg1);
- help(msg, msg1);
- }
- else if (command == "where")
- {
- // Display the current map, X, and Y
- std::ostringstream where;
- where << map_path << " " << player_node->mX << "," << player_node->mY;
- chatLog(where.str(), BY_SERVER);
- }
- else if (command == "who")
- {
- MessageOut outMsg(mNetwork);
- outMsg.writeInt16(0x00c1);
- }
- else if (command == "clear")
- mTextOutput->clearRows();
- else if (command == "whisper" || command == "msg" || command == "w")
- whisper(nick, msg);
- else if (command == "record")
- mRecorder->changeRecordingStatus(msg);
- else if (command == "toggle")
- {
- if (msg.empty())
- {
- chatLog(mReturnToggles ? _("Return toggles chat.")
- : _("Message closes chat."), BY_SERVER);
- return;
- }
-
- msg = msg.substr(0, 1);
-
- if (msg == "1" ||
- msg == "y" || msg == "Y" ||
- msg == "t" || msg == "T")
- {
- chatLog(_("Return now toggles chat."), BY_SERVER);
- mReturnToggles = true;
- return;
- }
- else if (msg == "0" ||
- msg == "n" || msg == "N" ||
- msg == "f" || msg == "F")
- {
- chatLog(_("Message now closes chat."), BY_SERVER);
- mReturnToggles = false;
- return;
- }
- else
- chatLog(_("Options to /toggle are \"yes\", \"no\", \"true\", "
- "\"false\", \"1\", \"0\"."), BY_SERVER);
- }
- else if (command == "party")
- {
- if (msg.empty())
- {
- chatLog(_("Unknown party command... Type \"/help\" party for more "
- "information."), BY_SERVER);
- return;
- }
+ // Update UI
+ logic();
+}
- const std::string::size_type space = msg.find(" ");
- std::string rest = (space == std::string::npos ? ""
- : msg.substr(space + 1, msg.length()));
+void ChatWindow::chatSend(std::string &msg)
+{
+ ChatTab *tab = getFocused();
+ tab->chatSend(msg);
+}
- if (!rest.empty())
- {
- msg = msg.substr(0, space);
- trim(msg);
- }
+void ChatWindow::doPresent()
+{
+ Beings & beings = beingManager->getAll();
+ std::string response = "";
- party(msg, rest);
- return;
- }
- else if (command == "cast")
+ for (BeingIterator bi = beings.begin(), be = beings.end();
+ bi != be; ++bi)
{
- /*
- * This will eventually be replaced by a GUI, so
- * we don't need to get too sophisticated
- */
- MessageOut outMsg(mNetwork);
- if (msg == "heal")
- {
- outMsg.writeInt16(0x03f3);
- outMsg.writeInt16(0x01);
- outMsg.writeInt32(0);
- outMsg.writeInt8(0);
- outMsg.writeInt8(0);
- outMsg.writeString("", 24);
- }
- else if (msg == "gather")
- {
- outMsg.writeInt16(0x03f3);
- outMsg.writeInt16(0x02);
- outMsg.writeInt32(0);
- outMsg.writeInt8(0);
- outMsg.writeInt8(0);
- outMsg.writeString("", 24);
- }
- else
- chatLog(_("No such spell!"), BY_SERVER);
- }
- else if (command == "present")
- {
- Beings & beings = beingManager->getAll();
- std::string response = "";
-
- for (BeingIterator bi = beings.begin(), be = beings.end();
- bi != be; ++bi)
+ if ((*bi)->getType() == Being::PLAYER)
{
- if ((*bi)->getType() == Being::PLAYER)
+ if (!response.empty())
{
- if (!response.empty())
- {
- response += ", ";
- }
- response += (*bi)->getName();
+ response += ", ";
}
- }
-
- if (mRecorder->isRecording())
- {
- // Get the current system time
- time_t t;
- time(&t);
-
- // Format the time string properly
- std::stringstream timeStr;
- timeStr << "[" << ((((t / 60) / 60) % 24 < 10) ? "0" : "")
- << (int) (((t / 60) / 60) % 24)
- << ":" << (((t / 60) % 60 < 10) ? "0" : "")
- << (int) ((t / 60) % 60)
- << "] ";
-
-
- mRecorder->record(timeStr.str() + _("Present: ") + response + ".");
- chatLog(_("Attendance written to record log."), BY_SERVER, true);
- }
- else
- {
- chatLog(_("Present: ") + response, BY_SERVER);
+ response += (*bi)->getName();
}
}
- else if (command == "me")
- {
- std::stringstream actionStr;
- actionStr << "*" << msg << "*";
- chatSend(player_node->getName(), actionStr.str());
- }
- else
- {
- chatLog(_("Unknown command"), BY_SERVER);
- }
-}
-std::string ChatWindow::const_msg(CHATSKILL act)
-{
- std::string msg;
- if (act.success == SKILL_FAILED && act.skill == SKILL_BASIC)
+ if (mRecorder->isRecording())
{
- switch (act.bskill)
- {
- case BSKILL_TRADE:
- msg = _("Trade failed!");
- break;
- case BSKILL_EMOTE:
- msg = _("Emote failed!");
- break;
- case BSKILL_SIT:
- msg = _("Sit failed!");
- break;
- case BSKILL_CREATECHAT:
- msg = _("Chat creating failed!");
- break;
- case BSKILL_JOINPARTY:
- msg = _("Could not join party!");
- break;
- case BSKILL_SHOUT:
- msg = _("Cannot shout!");
- break;
- }
+ // Get the current system time
+ time_t t;
+ time(&t);
- msg += " ";
+ // Format the time string properly
+ std::stringstream timeStr;
+ timeStr << "[" << ((((t / 60) / 60) % 24 < 10) ? "0" : "")
+ << (int) (((t / 60) / 60) % 24)
+ << ":" << (((t / 60) % 60 < 10) ? "0" : "")
+ << (int) ((t / 60) % 60)
+ << "] ";
- switch (act.reason)
- {
- case RFAIL_SKILLDEP:
- msg += _("You have not yet reached a high enough lvl!");
- break;
- case RFAIL_INSUFHP:
- msg += _("Insufficient HP!");
- break;
- case RFAIL_INSUFSP:
- msg += _("Insufficient SP!");
- break;
- case RFAIL_NOMEMO:
- msg += _("You have no memos!");
- break;
- case RFAIL_SKILLDELAY:
- msg += _("You cannot do that right now!");
- break;
- case RFAIL_ZENY:
- msg += _("Seems you need more GP... ;-)");
- break;
- case RFAIL_WEAPON:
- msg += _("You cannot use this skill with that kind of weapon!");
- break;
- case RFAIL_REDGEM:
- msg += _("You need another red gem!");
- break;
- case RFAIL_BLUEGEM:
- msg += _("You need another blue gem!");
- break;
- case RFAIL_OVERWEIGHT:
- msg += _("You're carrying to much to do this!");
- break;
- default:
- msg += _("Huh? What's that?");
- break;
- }
+
+ mRecorder->record(timeStr.str() + _("Present: ") + response + ".");
+ localChatTab->chatLog(_("Attendance written to record log."),
+ BY_SERVER, true);
}
else
{
- switch (act.skill)
- {
- case SKILL_WARP :
- msg = _("Warp failed...");
- break;
- case SKILL_STEAL :
- msg = _("Could not steal anything...");
- break;
- case SKILL_ENVENOM :
- msg = _("Poison had no effect...");
- break;
- }
+ localChatTab->chatLog(_("Present: ") + response, BY_SERVER);
}
-
- return msg;
}
void ChatWindow::scroll(int amount)
@@ -728,16 +304,12 @@ void ChatWindow::scroll(int amount)
if (!isVisible())
return;
- int range = mScrollArea->getHeight() / 8 * amount;
- gcn::Rectangle scr;
- scr.y = mScrollArea->getVerticalScrollAmount() + range;
- scr.height = abs(range);
- mTextOutput->showPart(scr);
+ ChatTab *tab = getFocused();
+ if (tab) tab->scroll(amount);
}
-void ChatWindow::keyPressed(gcn::KeyEvent & event)
+void ChatWindow::keyPressed(gcn::KeyEvent &event)
{
-
if (event.getKey().getValue() == Key::DOWN &&
mCurHist != mHistory.end())
{
@@ -786,150 +358,36 @@ void ChatWindow::setVisible(bool isVisible)
* For whatever reason, if setVisible is called, the mTmpVisible effect
* should be disabled.
*/
-
mTmpVisible = false;
}
-void ChatWindow::party(const std::string & command, const std::string & rest)
+void ChatWindow::setRecordingFile(const std::string &msg)
{
- if (command == "prefix")
- {
- if (rest.empty())
- {
- char temp[2] = ".";
- *temp = mPartyPrefix;
- chatLog(_("The current party prefix is ") + std::string(temp),
- BY_SERVER);
- }
- else if (rest.length() != 1)
- {
- chatLog(_("Party prefix must be one character long."), BY_SERVER);
- }
- else
- {
- if (rest == "/")
- {
- chatLog(_("Cannot use a '/' as the prefix."), BY_SERVER);
- }
- else
- {
- mPartyPrefix = rest.at(0);
- chatLog(_("Changing prefix to ") + rest, BY_SERVER);
- }
- }
- }
- else
- mParty->respond(command, rest);
+ mRecorder->setRecordingFile(msg);
}
-void ChatWindow::help(const std::string & msg1, const std::string & msg2)
+void ChatWindow::whisper(std::string nick, std::string mes, bool own)
{
- chatLog(_("-- Help --"), BY_SERVER);
- if (msg1.empty())
- {
- chatLog(_("/announce: Global announcement (GM only)"), BY_SERVER);
- chatLog(_("/clear: Clears this window"), BY_SERVER);
- chatLog(_("/help: Display this help"), BY_SERVER);
- chatLog(_("/me <message>: Tell something about yourself"), BY_SERVER);
- chatLog(_("/msg <nick> <message>: Alternate form for /whisper"),
- BY_SERVER);
- chatLog(_("/party <command> <params>: Party commands"), BY_SERVER);
- chatLog(_("/present: Get list of players present"), BY_SERVER);
- chatLog(_("/record <filename>: Start recording the chat to an "
- "external file"), BY_SERVER);
- chatLog(_("/toggle: Determine whether <return> toggles the chat log"),
- BY_SERVER);
- chatLog(_("/w <nick> <message>: Short form for /whisper"), BY_SERVER);
- chatLog(_("/where: Display map name"), BY_SERVER);
- chatLog(_("/whisper <nick> <message>: Sends a private <message> "
- "to <nick>"), BY_SERVER);
- chatLog(_("/who: Display number of online users"), BY_SERVER);
- chatLog(_("For more information, type /help <command>"), BY_SERVER);
- }
- else if (msg1 == "announce")
- {
- chatLog(_("Command: /announce <msg>"), BY_SERVER);
- chatLog(_("*** only available to a GM ***"), BY_SERVER);
- chatLog(_("This command sends the message <msg> to "
- "all players currently online."), BY_SERVER);
- }
- else if (msg1 == "clear")
- {
- chatLog(_("Command: /clear"), BY_SERVER);
- chatLog(_("This command clears the chat log of previous chat."),
- BY_SERVER);
- }
- else if (msg1 == "help")
- {
- chatLog(_("Command: /help"), BY_SERVER);
- chatLog(_("This command displays a list of all commands available."),
- BY_SERVER);
- chatLog(_("Command: /help <command>"), BY_SERVER);
- chatLog(_("This command displays help on <command>."), BY_SERVER);
- }
- else if (msg1 == "me")
- {
- chatLog(_("Command: /me <msg>"), BY_SERVER);
- chatLog(_("This command tell others you are (doing) <msg>."),
- BY_SERVER);
- }
- else if (msg1 == "party")
- {
- mParty->help(msg2);
- }
- else if (msg1 == "present")
- {
- chatLog(_("Command: /present"), BY_SERVER);
- chatLog(_("This command gets a list of players within hearing and "
- "sends it to either the record log if recording, or the chat "
- "log otherwise."), BY_SERVER);
- }
- else if (msg1 == "record")
- {
- chatLog(_("Command: /record <filename>"), BY_SERVER);
- chatLog(_("This command starts recording the chat log to the file "
- "<filename>."), BY_SERVER);
- chatLog(_("Command: /record"), BY_SERVER);
- chatLog(_("This command finishes a recording session."), BY_SERVER);
- }
- else if (msg1 == "toggle")
- {
- chatLog(_("Command: /toggle <state>"), BY_SERVER);
- chatLog(_("This command sets whether the return key should toggle the "
- "chat log, or whether the chat log turns off automatically."),
- BY_SERVER);
- chatLog(_("<state> can be one of \"1\", \"yes\", \"true\" to "
- "turn the toggle on, or \"0\", \"no\", \"false\" to turn the "
- "toggle off."), BY_SERVER);
- chatLog(_("Command: /toggle"), BY_SERVER);
- chatLog(_("This command displays the return toggle status."),
- BY_SERVER);
- }
- else if (msg1 == "where")
- {
- chatLog(_("Command: /where"), BY_SERVER);
- chatLog(_("This command displays the name of the current map."),
- BY_SERVER);
- }
- else if (msg1 == "whisper" || msg1 == "msg" || msg1 == "w")
- {
- chatLog(_("Command: /msg <nick> <msg>"), BY_SERVER);
- chatLog(_("Command: /whisper <nick> <msg>"), BY_SERVER);
- chatLog(_("Command: /w <nick> <msg>"), BY_SERVER);
- chatLog(_("This command sends the message <msg> to <nick>."),
- BY_SERVER);
- chatLog(_("If the <nick> has spaces in it, enclose it in "
- "double quotes (\")."), BY_SERVER);
- }
- else if (msg1 == "who")
+ if (mes.length() == 0) return;
+ std::string playerName = player_node->getName();
+ std::string tempNick = nick;
+
+ toLower(playerName);
+ toLower(tempNick);
+
+ if (!own && tempNick.compare(playerName) == 0)
+ return;
+
+ ChatTab *tab = mWhispers[tempNick];
+
+ if (!tab)
{
- chatLog(_("Command: /who"), BY_SERVER);
- chatLog(_("This command displays the number of players currently "
- "online."), BY_SERVER);
+ tab = new WhisperTab(tempNick);
+ mWhispers[tempNick] = tab;
}
+
+ if (own)
+ tab->chatSend(mes);
else
- {
- chatLog(_("Unknown command."), BY_SERVER);
- chatLog(_("Type /help for a list of commands."), BY_SERVER);
- }
+ tab->chatLog(nick, mes);
}
diff --git a/src/gui/chat.h b/src/gui/chat.h
index 8b710dc8..7c080960 100644
--- a/src/gui/chat.h
+++ b/src/gui/chat.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,29 +24,28 @@
#include <list>
#include <string>
+#include <map>
#include <guichan/actionlistener.hpp>
#include <guichan/keylistener.hpp>
+#include <guichan/widget.hpp>
+#include <guichan/widgetlistener.hpp>
+
+#include "widgets/chattab.h"
#include "window.h"
class BrowserBox;
-class Network;
+class Channel;
+class ChatTab;
class Recorder;
-class Party;
class ScrollArea;
+class TabbedArea;
class ItemLinkHandler;
-
-#define BY_GM 0 // those should be self-explanatory =)
-#define BY_PLAYER 1
-#define BY_OTHER 2
-#define BY_SERVER 3
-#define BY_PARTY 4
-
-#define ACT_WHISPER 5 // getting whispered at
-#define ACT_IS 6 // equivalent to "/me" on IRC
-
-#define BY_LOGGER 7
+#ifdef EATHENA_SUPPORT
+class Network;
+#endif
+class WhisperTab;
/**
* gets in between usernick and message text depending on
@@ -57,47 +55,14 @@ class ItemLinkHandler;
#define CAT_IS ""
#define CAT_WHISPER " whispers: "
-/** job dependend identifiers (?) */
-#define SKILL_BASIC 0x0001
-#define SKILL_WARP 0x001b
-#define SKILL_STEAL 0x0032
-#define SKILL_ENVENOM 0x0034
-
-/** basic skills identifiers */
-#define BSKILL_TRADE 0x0000
-#define BSKILL_EMOTE 0x0001
-#define BSKILL_SIT 0x0002
-#define BSKILL_CREATECHAT 0x0003
-#define BSKILL_JOINPARTY 0x0004
-#define BSKILL_SHOUT 0x0005
-#define BSKILL_PK 0x0006 // ??
-#define BSKILL_SETALLIGN 0x0007 // ??
-
-/** reasons why action failed */
-#define RFAIL_SKILLDEP 0x00
-#define RFAIL_INSUFHP 0x01
-#define RFAIL_INSUFSP 0x02
-#define RFAIL_NOMEMO 0x03
-#define RFAIL_SKILLDELAY 0x04
-#define RFAIL_ZENY 0x05
-#define RFAIL_WEAPON 0x06
-#define RFAIL_REDGEM 0x07
-#define RFAIL_BLUEGEM 0x08
-#define RFAIL_OVERWEIGHT 0x09
-#define RFAIL_GENERIC 0x0a
-
-/** should always be zero if failed */
-#define SKILL_FAILED 0x00
-
#define DEFAULT_CHAT_WINDOW_SCROLL 7 // 1 means `1/8th of the window size'.
-struct CHATSKILL
+/** One item in the chat log */
+struct CHATLOG
{
- short skill;
- short bskill;
- short unused;
- char success;
- char reason;
+ std::string nick;
+ std::string text;
+ int own;
};
/**
@@ -105,14 +70,19 @@ struct CHATSKILL
*
* \ingroup Interface
*/
-class ChatWindow : public Window, public gcn::ActionListener,
+class ChatWindow : public Window,
+ public gcn::ActionListener,
public gcn::KeyListener
{
public:
/**
* Constructor.
*/
+#ifdef TMWSERV_SUPPORT
+ ChatWindow();
+#else
ChatWindow(Network *network);
+#endif
/**
* Destructor: used to write back values to the config file
@@ -120,23 +90,33 @@ class ChatWindow : public Window, public gcn::ActionListener,
~ChatWindow();
/**
+ * Called when the widget changes size. Used for adapting the size of
+ * the tabbed area.
+ */
+ void widgetResized(const gcn::Event &event);
+
+ void logic();
+
+ /**
* Reset the chat window and recorder window attached to it to their
* default positions.
*/
void resetToDefaultSize();
/**
- * Adds a line of text to our message list. Parameters:
- *
- * @param line Text message.
- * @parem own Type of message (usually the owner-type).
+ * Gets the focused tab.
*/
- void chatLog(std::string line, int own, bool ignoreRecord = false);
+ ChatTab* getFocused() const;
/**
- * Calls original chat_log() after processing the packet.
+ * Clear the given tab.
*/
- void chatLog(CHATSKILL);
+ void clearTab(ChatTab* tab);
+
+ /**
+ * Clear the current tab.
+ */
+ void clearTab();
/**
* Performs action.
@@ -145,8 +125,11 @@ class ChatWindow : public Window, public gcn::ActionListener,
/**
* Request focus for typing chat message.
+ *
+ * \returns true if the input was shown
+ * false otherwise
*/
- void requestChatFocus();
+ bool requestChatFocus();
/**
* Checks whether ChatWindow is Focused or not.
@@ -154,30 +137,12 @@ class ChatWindow : public Window, public gcn::ActionListener,
bool isInputFocused();
/**
- * Determines whether to send a command or an ordinary message, then
- * contructs packets & sends them.
- *
- * @param nick The character's name to display in front.
- * @param msg The message text which is to be send.
+ * Passes the text to the current tab as input
*
- * NOTE:
- * The nickname is required by the server, if not specified
- * the message may not be sent unless a command was intended
- * which requires another packet to be constructed! you can
- * achieve this by putting a slash ("/") infront of the
- * message followed by the command name and the message.
- * of course all slash-commands need implemented handler-
- * routines. ;-)
- * remember, a line starting with "@" is not a command that needs
- * to be parsed rather is sent using the normal chat-packet.
+ * @param msg The message text which is to be sent.
*
- * EXAMPLE:
- * // for an global announcement /- command
- * chatlog.chat_send("", "/announce Hello to all logged in users!");
- * // for simple message by a user /- message
- * chatlog.chat_send("Zaeiru", "Hello to all users on the screen!");
*/
- void chatSend(const std::string &nick, std::string msg);
+ void chatSend(std::string &msg);
/** Called when key is pressed */
void keyPressed(gcn::KeyEvent &event);
@@ -191,65 +156,77 @@ class ChatWindow : public Window, public gcn::ActionListener,
/** Override to reset mTmpVisible */
void setVisible(bool visible);
- /**
- * Scrolls the chat window
- *
- * @param amount direction and amount to scroll. Negative numbers scroll
- * up, positive numbers scroll down. The absolute amount indicates the
- * amount of 1/8ths of chat window real estate that should be scrolled.
- */
- void scroll(int amount);
-
/**
- * party implements the partying chat commands
+ * Scrolls the chat window
*
- * @param command is the party command to perform
- * @param msg is the remainder of the message
+ * @param amount direction and amount to scroll. Negative numbers scroll
+ * up, positive numbers scroll down. The absolute amount indicates the
+ * amount of 1/8ths of chat window real estate that should be scrolled.
*/
- void party(const std::string &command, const std::string &msg);
+ void scroll(int amount);
+
+#ifdef EATHENA_SUPPORT
+ char getPartyPrefix() const { return mPartyPrefix; }
+ void setPartyPrefix(char prefix) { mPartyPrefix = prefix; }
+#endif
/**
- * help implements the /help command
+ * Sets the file being recorded to
*
- * @param msg1 is the command that the player needs help on
- * @param msg2 is the sub-command relating to the command
+ * @param msg The file to write out to. If null, then stop recording.
*/
- void help(const std::string &msg1, const std::string &msg2);
+ void setRecordingFile(const std::string &msg);
- private:
+ bool getReturnTogglesChat() const { return mReturnToggles; }
+ void setReturnTogglesChat(bool toggles) { mReturnToggles = toggles; }
+
+ void doPresent();
+
+ void whisper(std::string nick, std::string mes, bool own = false);
+
+ protected:
+ friend class ChatTab;
+ friend class WhisperTab;
+ /** Remove the given tab from the window */
+ void removeTab(ChatTab *tab);
+
+ /** Add the tab to the window */
+ void addTab(ChatTab *tab);
+
+ void adjustTabSize();
+
+#ifdef EATHENA_SUPPORT
Network *mNetwork;
- bool mTmpVisible;
+ char mPartyPrefix; /**< Messages beginning with the prefix are sent to
+ the party */
+#endif
+ /** Used for showing item popup on clicking links **/
+ ItemLinkHandler *mItemLinkHandler;
+ Recorder *mRecorder;
- void whisper(const std::string &nick, std::string msg);
+ /** Input box for typing chat messages. */
+ gcn::TextField *mChatInput;
- /** One item in the chat log */
- struct CHATLOG
- {
- std::string nick;
- std::string text;
- int own;
- };
+ private:
+ bool mTmpVisible;
- /** Constructs failed messages for actions */
- std::string const_msg(CHATSKILL);
+ /** Tabbed area for holding each channel. */
+ TabbedArea *mChatTabs;
+ Tab *mCurrentTab;
+
+ typedef std::map<const std::string, ChatTab*> TabMap;
+ /** Manage whisper tabs */
+ TabMap mWhispers;
- gcn::TextField *mChatInput; /**< Input box for typing chat messages */
- BrowserBox *mTextOutput; /**< Text box for displaying chat history */
- ScrollArea *mScrollArea; /**< Scroll area around text output */
- ItemLinkHandler *mItemLinkHandler; /** Used for showing item popup on
- clicking links **/
typedef std::list<std::string> History;
typedef History::iterator HistoryIterator;
- History mHistory; /**< Command history */
- HistoryIterator mCurHist; /**< History iterator */
- Recorder *mRecorder; /**< Recording class */
- char mPartyPrefix; /**< Messages beginning with the prefix are
- sent to the party */
- bool mReturnToggles; /**< Marks whether <Return> toggles the chat
- log or not */
- Party *mParty;
+ History mHistory; /**< Command history. */
+ HistoryIterator mCurHist; /**< History iterator. */
+ bool mReturnToggles; /**< Marks whether <Return> toggles the chat log
+ or not */
};
+
extern ChatWindow *chatWindow;
#endif
diff --git a/src/gui/chatinput.cpp b/src/gui/chatinput.cpp
index 42c6d4de..43f3cde4 100644
--- a/src/gui/chatinput.cpp
+++ b/src/gui/chatinput.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/chatinput.h b/src/gui/chatinput.h
index 96c30b3f..3bc16928 100644
--- a/src/gui/chatinput.h
+++ b/src/gui/chatinput.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,6 +26,8 @@
#include "textfield.h"
+#include <guichan/focuslistener.hpp>
+
/**
* The chat input hides when it loses focus. It is also invisible by default.
*/
diff --git a/src/gui/checkbox.cpp b/src/gui/checkbox.cpp
index f6cce581..2623e2c6 100644
--- a/src/gui/checkbox.cpp
+++ b/src/gui/checkbox.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,7 +35,7 @@ Image *CheckBox::checkBoxChecked;
Image *CheckBox::checkBoxDisabled;
Image *CheckBox::checkBoxDisabledChecked;
-CheckBox::CheckBox(const std::string& caption, bool selected):
+CheckBox::CheckBox(const std::string &caption, bool selected):
gcn::CheckBox(caption, selected)
{
if (instances == 0)
diff --git a/src/gui/checkbox.h b/src/gui/checkbox.h
index 93b62b9d..303782b0 100644
--- a/src/gui/checkbox.h
+++ b/src/gui/checkbox.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -38,7 +37,7 @@ class CheckBox : public gcn::CheckBox
/**
* Constructor.
*/
- CheckBox(const std::string& caption, bool selected = false);
+ CheckBox(const std::string &caption, bool selected = false);
/**
* Destructor.
diff --git a/src/gui/confirm_dialog.cpp b/src/gui/confirm_dialog.cpp
index 4c08eb73..e1c32759 100644
--- a/src/gui/confirm_dialog.cpp
+++ b/src/gui/confirm_dialog.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,7 +33,7 @@ ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg,
Window *parent):
Window(title, true, parent)
{
- mTextBox = new TextBox();
+ mTextBox = new TextBox;
mTextBox->setEditable(false);
mTextBox->setOpaque(false);
@@ -75,11 +74,11 @@ ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg,
add(yesButton);
add(noButton);
- setLocationRelativeTo(getParent());
-
if (getParent())
+ {
+ center();
getParent()->moveToTop(this);
-
+ }
setVisible(true);
yesButton->requestFocus();
}
diff --git a/src/gui/confirm_dialog.h b/src/gui/confirm_dialog.h
index 493e9dda..8d8c0436 100644
--- a/src/gui/confirm_dialog.h
+++ b/src/gui/confirm_dialog.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -56,7 +55,6 @@ class ConfirmDialog : public Window, public gcn::ActionListener
private:
TextBox *mTextBox;
ScrollArea *mTextArea;
- gcn::Button *okButton;
};
#endif
diff --git a/src/gui/connection.cpp b/src/gui/connection.cpp
index d4a2b18a..5fb21ff2 100644
--- a/src/gui/connection.cpp
+++ b/src/gui/connection.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,31 +19,22 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <guichan/actionlistener.hpp>
-
#include "button.h"
#include "connection.h"
#include "label.h"
#include "progressbar.h"
#include "../main.h"
+#include "../log.h"
#include "../utils/gettext.h"
-namespace
-{
- struct ConnectionActionListener : public gcn::ActionListener
- {
- void action(const gcn::ActionEvent &event) { state = EXIT_STATE; }
- } listener;
-}
-
-ConnectionDialog::ConnectionDialog():
- Window("Info"), mProgress(0)
+ConnectionDialog::ConnectionDialog(int previousState):
+ Window("Info"), mProgress(0), mPreviousState(previousState)
{
setContentSize(200, 100);
- Button *cancelButton = new Button(_("Cancel"), "cancelButton", &listener);
+ Button *cancelButton = new Button(_("Cancel"), "cancelButton", this);
mProgressBar = new ProgressBar(0.0, 200 - 10, 20, 128, 128, 128);
gcn::Label *label = new Label(_("Connecting..."));
@@ -56,10 +46,16 @@ ConnectionDialog::ConnectionDialog():
add(cancelButton);
add(mProgressBar);
- setLocationRelativeTo(getParent());
+ center();
setVisible(true);
}
+void ConnectionDialog::action(gcn::ActionEvent const &)
+{
+ logger->log("Cancel pressed");
+ state = mPreviousState;
+}
+
void ConnectionDialog::logic()
{
mProgress += 0.005f;
diff --git a/src/gui/connection.h b/src/gui/connection.h
index f91a0ad1..0e347266 100644
--- a/src/gui/connection.h
+++ b/src/gui/connection.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,6 +22,8 @@
#ifndef CONNECTION_H
#define CONNECTION_H
+#include <guichan/actionlistener.hpp>
+
#include "window.h"
class ProgressBar;
@@ -32,7 +33,7 @@ class ProgressBar;
*
* \ingroup Interface
*/
-class ConnectionDialog : public Window
+class ConnectionDialog : public Window, gcn::ActionListener
{
public:
/**
@@ -40,13 +41,20 @@ class ConnectionDialog : public Window
*
* @see Window::Window
*/
- ConnectionDialog();
+ ConnectionDialog(int previousState);
+
+ /**
+ * Called when the user presses Cancel. Restores the global state to
+ * the previous one.
+ */
+ void action(gcn::ActionEvent const &);
void logic();
private:
ProgressBar *mProgressBar;
float mProgress;
+ int mPreviousState;
};
#endif
diff --git a/src/gui/debugwindow.cpp b/src/gui/debugwindow.cpp
index 9b8ea6bd..a98c9af4 100644
--- a/src/gui/debugwindow.cpp
+++ b/src/gui/debugwindow.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/debugwindow.h b/src/gui/debugwindow.h
index c82521f9..8097132c 100644
--- a/src/gui/debugwindow.h
+++ b/src/gui/debugwindow.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/emotecontainer.cpp b/src/gui/emotecontainer.cpp
index 22b4cf50..ececd9aa 100644
--- a/src/gui/emotecontainer.cpp
+++ b/src/gui/emotecontainer.cpp
@@ -2,8 +2,7 @@
* Extended support for activating emotes
* Copyright (C) 2009 Aethyra Development Team
*
- * This file is part of Aethyra derived from original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/emotecontainer.h b/src/gui/emotecontainer.h
index 7e88cb71..88df29fc 100644
--- a/src/gui/emotecontainer.h
+++ b/src/gui/emotecontainer.h
@@ -2,8 +2,7 @@
* Extended support for activating emotes
* Copyright (C) 2009 Aethyra Development Team
*
- * This file is part of Aethyra derived from original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/emoteshortcutcontainer.cpp b/src/gui/emoteshortcutcontainer.cpp
index 47fb9b06..661f42a7 100644
--- a/src/gui/emoteshortcutcontainer.cpp
+++ b/src/gui/emoteshortcutcontainer.cpp
@@ -2,8 +2,7 @@
* Extended support for activating emotes
* Copyright (C) 2009 Aethyra Development Team
*
- * This file is part of Aethyra derived from original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/emoteshortcutcontainer.h b/src/gui/emoteshortcutcontainer.h
index ff9f929c..2997cb09 100644
--- a/src/gui/emoteshortcutcontainer.h
+++ b/src/gui/emoteshortcutcontainer.h
@@ -2,8 +2,7 @@
* Extended support for activating emotes
* Copyright (C) 2009 Aethyra Development Team
*
- * This file is part of Aethyra derived from original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/emotewindow.cpp b/src/gui/emotewindow.cpp
index 77168993..d4b3cf2e 100644
--- a/src/gui/emotewindow.cpp
+++ b/src/gui/emotewindow.cpp
@@ -2,7 +2,7 @@
* Extended support for activating emotes
* Copyright (C) 2009 Aethyra Development Team
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,7 +35,7 @@
EmoteWindow::EmoteWindow():
Window(_("Emote"))
{
- setWindowName(_("Emote"));
+ setWindowName("Emote");
setResizable(true);
setCloseButton(true);
setMinWidth(80);
@@ -44,7 +44,7 @@ EmoteWindow::EmoteWindow():
mUseButton = new Button(_("Use"), "use", this);
- mEmotes = new EmoteContainer();
+ mEmotes = new EmoteContainer;
mEmotes->addSelectionListener(this);
mEmoteScroll = new ScrollArea(mEmotes);
diff --git a/src/gui/emotewindow.h b/src/gui/emotewindow.h
index 81ee4f05..8af24a7b 100644
--- a/src/gui/emotewindow.h
+++ b/src/gui/emotewindow.h
@@ -2,7 +2,7 @@
* Extended support for activating emotes
* Copyright (C) 2009 Aethyra Development Team
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp
index 168ae22f..96500e88 100644
--- a/src/gui/equipmentwindow.cpp
+++ b/src/gui/equipmentwindow.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra derived from original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -38,6 +37,7 @@
#include "../item.h"
#include "../localplayer.h"
+#include "../resources/image.h"
#include "../resources/iteminfo.h"
#include "../resources/resourcemanager.h"
@@ -59,11 +59,19 @@ static const int boxPosition[][2] = {
{129, 78} // EQUIP_AMMO_SLOT
};
+#ifdef TMWSERV_SUPPORT
+EquipmentWindow::EquipmentWindow(Equipment *equipment):
+#else
EquipmentWindow::EquipmentWindow():
+#endif
Window(_("Equipment")),
+#ifdef TMWSERV_SUPPORT
+ mEquipment(equipment),
+#endif
+ mBackground(NULL),
mSelected(-1)
{
- mItemPopup = new ItemPopup();
+ mItemPopup = new ItemPopup;
mItemPopup->setOpaque(false);
// Control that shows the Player
@@ -84,19 +92,31 @@ EquipmentWindow::EquipmentWindow():
add(mPlayerBox);
add(mUnequip);
+#ifdef TMWSERV_SUPPORT
+ for (int i = 0; i < EQUIPMENT_SIZE; i++)
+#else
for (int i = EQUIP_LEGS_SLOT; i < EQUIP_VECTOREND; i++)
+#endif
{
mEquipBox[i].posX = boxPosition[i][0] + getPadding();
mEquipBox[i].posY = boxPosition[i][1] + getTitleBarHeight();
}
+ ResourceManager *resman = ResourceManager::getInstance();
+ mBackground = resman->getImage("graphics/gui/equip_bg.png");
+ mBackground->setAlpha(0.3);
+
+#ifdef EATHENA_SUPPORT
mEquipment = player_node->mEquipment.get();
mInventory = player_node->getInventory();
+#endif
}
EquipmentWindow::~EquipmentWindow()
{
+ mBackground->decRef();
delete mItemPopup;
+ delete mUnequip;
}
void EquipmentWindow::draw(gcn::Graphics *graphics)
@@ -107,13 +127,15 @@ void EquipmentWindow::draw(gcn::Graphics *graphics)
// Draw window graphics
Window::draw(graphics);
- Item* item;
-
Graphics *g = static_cast<Graphics*>(graphics);
Window::drawChildren(graphics);
+#ifdef TMWSERV_SUPPORT
+ for (int i = 0; i < EQUIPMENT_SIZE; i++)
+#else
for (int i = EQUIP_LEGS_SLOT; i < EQUIP_VECTOREND; i++)
+#endif
{
if (i == mSelected)
{
@@ -131,14 +153,19 @@ void EquipmentWindow::draw(gcn::Graphics *graphics)
g->drawRectangle(gcn::Rectangle(mEquipBox[i].posX, mEquipBox[i].posY,
BOX_WIDTH, BOX_HEIGHT));
- item = (i != EQUIP_AMMO_SLOT) ?
+#ifdef TMWSERV_SUPPORT
+ Item *item = mEquipment->getEquipment(i);
+#else
+ Item *item = (i != EQUIP_AMMO_SLOT) ?
mInventory->getItem(mEquipment->getEquipment(i)) :
mInventory->getItem(mEquipment->getArrows());
+#endif
if (item)
{
// Draw Item.
- Image* image = item->getImage();
+ Image *image = item->getImage();
g->drawImage(image, mEquipBox[i].posX, mEquipBox[i].posY);
+#ifdef EATHENA_SUPPORT
if (i == EQUIP_AMMO_SLOT)
{
g->setColor(guiPalette->getColor(Palette::TEXT));
@@ -147,6 +174,7 @@ void EquipmentWindow::draw(gcn::Graphics *graphics)
mEquipBox[i].posY - getFont()->getHeight(),
gcn::Graphics::CENTER);
}
+#endif
}
}
}
@@ -155,26 +183,38 @@ void EquipmentWindow::action(const gcn::ActionEvent &event)
{
if (event.getId() == "unequip" && mSelected > -1)
{
+#ifdef TMWSERV_SUPPORT
+ player_node->unequipItem(mSelected);
+#else
Item* item = (mSelected != EQUIP_AMMO_SLOT) ?
mInventory->getItem(mEquipment->getEquipment(mSelected)) :
mInventory->getItem(mEquipment->getArrows());
player_node->unequipItem(item);
+#endif
mSelected = -1;
}
}
-Item* EquipmentWindow::getItem(const int &x, const int &y)
+Item* EquipmentWindow::getItem(int x, int y) const
{
+#ifdef TMWSERV_SUPPORT
+ for (int i = 0; i < EQUIPMENT_SIZE; i++)
+#else
for (int i = EQUIP_LEGS_SLOT; i < EQUIP_VECTOREND; i++)
+#endif
{
gcn::Rectangle tRect(mEquipBox[i].posX, mEquipBox[i].posY,
BOX_WIDTH, BOX_HEIGHT);
if (tRect.isPointInRect(x, y))
{
+#ifdef TMWSERV_SUPPORT
+ return mEquipment->getEquipment(i);
+#else
return (i != EQUIP_AMMO_SLOT) ?
mInventory->getItem(mEquipment->getEquipment(i)) :
mInventory->getItem(mEquipment->getArrows());
+#endif
}
}
return NULL;
@@ -192,11 +232,19 @@ void EquipmentWindow::mousePressed(gcn::MouseEvent& mouseEvent)
if (mouseEvent.getButton() == gcn::MouseEvent::LEFT)
{
// Checks if any of the presses were in the equip boxes.
+#ifdef TMWSERV_SUPPORT
+ for (int i = 0; i < EQUIPMENT_SIZE; i++)
+#else
for (int i = EQUIP_LEGS_SLOT; i < EQUIP_VECTOREND; i++)
+#endif
{
+#ifdef TMWSERV_SUPPORT
+ item = mEquipment->getEquipment(i);
+#else
item = (i != EQUIP_AMMO_SLOT) ?
mInventory->getItem(mEquipment->getEquipment(i)) :
mInventory->getItem(mEquipment->getArrows());
+#endif
gcn::Rectangle tRect(mEquipBox[i].posX, mEquipBox[i].posY,
BOX_WIDTH, BOX_HEIGHT);
diff --git a/src/gui/equipmentwindow.h b/src/gui/equipmentwindow.h
index 7fdbaac8..7f7150ff 100644
--- a/src/gui/equipmentwindow.h
+++ b/src/gui/equipmentwindow.h
@@ -1,33 +1,33 @@
/*
- * Aethyra
- * Copyright 2004 The Mana World Development Team
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra derived from original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
- * The Mana World is free software; you can redistribute it and/or modify
+ * This program is free software; you can redistribute it and/or modify
* it under the 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,
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef EQUIPMENT_WINDOW_H
-#define EQUIPMENT_WINDOW_H
+#ifndef EQUIPMENTWINDOW_H
+#define EQUIPMENTWINDOW_H
#include <guichan/actionlistener.hpp>
#include "window.h"
class Equipment;
+class Image;
class Inventory;
class Item;
class ItemPopup;
@@ -53,7 +53,11 @@ class EquipmentWindow : public Window, public gcn::ActionListener
/**
* Constructor.
*/
+#ifdef TMWSERV_SUPPORT
+ EquipmentWindow(Equipment *equipment);
+#else
EquipmentWindow();
+#endif
/**
* Destructor.
@@ -69,6 +73,23 @@ class EquipmentWindow : public Window, public gcn::ActionListener
void mousePressed(gcn::MouseEvent& mouseEvent);
+#ifdef TMWSERV_SUPPORT
+ enum{
+ // Equipment rules:
+ EQUIP_TORSO_SLOT = 0,
+ EQUIP_ARMS_SLOT = 1,
+ EQUIP_HEAD_SLOT = 2,
+ EQUIP_LEGS_SLOT = 3,
+ EQUIP_FEET_SLOT = 4,
+ EQUIP_RING1_SLOT = 5,
+ EQUIP_RING2_SLOT = 6,
+ EQUIP_NECKLACE_SLOT = 7,
+ EQUIP_FIGHT1_SLOT = 8,
+ EQUIP_FIGHT2_SLOT = 9,
+ EQUIP_PROJECTILE_SLOT = 10,
+ EQUIP_VECTOREND
+ };
+#else
enum {
// Equipment rules:
EQUIP_LEGS_SLOT = 0,
@@ -84,17 +105,20 @@ class EquipmentWindow : public Window, public gcn::ActionListener
EQUIP_AMMO_SLOT,
EQUIP_VECTOREND
};
-
+#endif
private:
void mouseExited(gcn::MouseEvent &event);
void mouseMoved(gcn::MouseEvent &event);
- Item* getItem(const int &x, const int &y);
+ Item* getItem(int x, int y) const;
Equipment *mEquipment;
+#ifdef EATHENA_SUPPORT
Inventory *mInventory;
+#endif
gcn::Button *mUnequip; /**< Button for unequipping. */
+ Image *mBackground; /**< Background Image. */
EquipBox mEquipBox[EQUIP_VECTOREND]; /**< Equipment Boxes. */
ItemPopup *mItemPopup;
diff --git a/src/gui/focushandler.cpp b/src/gui/focushandler.cpp
index c642127d..b9cfd789 100644
--- a/src/gui/focushandler.cpp
+++ b/src/gui/focushandler.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/focushandler.h b/src/gui/focushandler.h
index fc5dd240..b0639bd8 100644
--- a/src/gui/focushandler.h
+++ b/src/gui/focushandler.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/gccontainer.cpp b/src/gui/gccontainer.cpp
index 7aebed15..8325ccd4 100644
--- a/src/gui/gccontainer.cpp
+++ b/src/gui/gccontainer.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/gccontainer.h b/src/gui/gccontainer.h
index 2071955d..da584a42 100644
--- a/src/gui/gccontainer.h
+++ b/src/gui/gccontainer.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index 5bdab453..87ce74fa 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -95,7 +94,7 @@ Gui::Gui(Graphics *graphics):
mFocusHandler = new FocusHandler;
// Initialize top GUI widget
- WindowContainer *guiTop = new WindowContainer();
+ WindowContainer *guiTop = new WindowContainer;
guiTop->setDimension(gcn::Rectangle(0, 0,
graphics->getWidth(), graphics->getHeight()));
guiTop->setOpaque(false);
@@ -105,7 +104,8 @@ Gui::Gui(Graphics *graphics):
ResourceManager *resman = ResourceManager::getInstance();
// Set global font
- std::string path = resman->getPath("fonts/dejavusans.ttf");
+ std::string path = resman->getPath(
+ branding.getValue("font", "fonts/dejavusans.ttf"));
try
{
const int fontSize = (int)config.getValue("fontSize", 11);
@@ -119,7 +119,8 @@ Gui::Gui(Graphics *graphics):
}
// Set bold font
- path = resman->getPath("fonts/dejavusans-bold.ttf");
+ path = resman->getPath(
+ branding.getValue("boldFont", "fonts/dejavusans.ttf"));
try
{
const int fontSize = (int)config.getValue("fontSize", 11);
@@ -139,7 +140,7 @@ Gui::Gui(Graphics *graphics):
config.addListener("customcursor", mConfigListener);
// Create the viewport
- viewport = new Viewport();
+ viewport = new Viewport;
viewport->setDimension(gcn::Rectangle(0, 0,
graphics->getWidth(), graphics->getHeight()));
guiTop->add(viewport);
diff --git a/src/gui/gui.h b/src/gui/gui.h
index 609648fd..2ce153db 100644
--- a/src/gui/gui.h
+++ b/src/gui/gui.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/guildlistbox.cpp b/src/gui/guildlistbox.cpp
new file mode 100644
index 00000000..a4d39741
--- /dev/null
+++ b/src/gui/guildlistbox.cpp
@@ -0,0 +1,130 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "guildlistbox.h"
+
+#include "../graphics.h"
+
+#include "../resources/image.h"
+#include "../resources/resourcemanager.h"
+
+#include <guichan/font.hpp>
+
+GuildListBox::GuildListBox():
+ ListBox(NULL)
+{
+ onlineIcon = ResourceManager::getInstance()->getImage("graphics/gui/circle-green.png");
+ offlineIcon = ResourceManager::getInstance()->getImage("graphics/gui/circle-gray.png");
+}
+
+void GuildListBox::draw(gcn::Graphics *gcnGraphics)
+{
+ if (!mListModel)
+ return;
+
+ Graphics *graphics = static_cast<Graphics*>(gcnGraphics);
+
+ graphics->setColor(gcn::Color(110, 160, 255));
+ graphics->setFont(getFont());
+
+ int fontHeight = getFont()->getHeight();
+
+ // Draw rectangle below the selected list element
+ if (mSelected >= 0) {
+ graphics->fillRectangle(gcn::Rectangle(0, fontHeight * mSelected,
+ getWidth(), fontHeight));
+ }
+
+ // Draw the list elements
+ for (int i = 0, y = 0;
+ i < mListModel->getNumberOfElements();
+ ++i, y += fontHeight)
+ {
+ // Draw online status
+ bool online = false;
+ UserMap::iterator itr = mUsers.find(mListModel->getElementAt(i));
+ if (itr != mUsers.end())
+ {
+ online = itr->second;
+ }
+ Image *icon = online ? onlineIcon : offlineIcon;
+ if (icon)
+ graphics->drawImage(icon, 1, y);
+ // Draw Name
+ graphics->setColor(gcn::Color(0, 0, 0));
+ graphics->drawText(mListModel->getElementAt(i), 33, y);
+ }
+}
+/*
+void GuildListBox::setSelected(int selected)
+{
+ if (!mListModel)
+ {
+ mSelected = -1;
+ }
+ else
+ {
+ // Update mSelected with bounds checking
+ mSelected = std::min(mListModel->getNumberOfElements() - 1,
+ std::max(-1, selected));
+
+ gcn::Widget *parent;
+ parent = (gcn::Widget*)getParent();
+ if (parent)
+ {
+ gcn::Rectangle scroll;
+ scroll.y = (mSelected < 0) ? 0 : getFont()->getHeight() * mSelected;
+ scroll.height = getFont()->getHeight();
+ parent->showWidgetPart(this, scroll);
+ }
+ }
+
+ distributeValueChangedEvent();
+}
+*/
+void GuildListBox::mousePressed(gcn::MouseEvent &event)
+{
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ int y = event.getY();
+ setSelected(y / getFont()->getHeight());
+ distributeActionEvent();
+ }
+ // TODO: Add guild functions, ie private messaging
+ if (event.getButton() == gcn::MouseEvent::RIGHT)
+ {
+ // Show context menu
+ }
+}
+
+void GuildListBox::setOnlineStatus(const std::string &user, bool online)
+{
+ UserMap::iterator itr = mUsers.find(user);
+ if (itr == mUsers.end())
+ {
+ mUsers.insert(std::pair<std::string, bool>(user, online));
+ }
+ else
+ {
+ itr->second = online;
+ }
+ adjustSize();
+}
diff --git a/src/gui/guildlistbox.h b/src/gui/guildlistbox.h
new file mode 100644
index 00000000..8d6e74f1
--- /dev/null
+++ b/src/gui/guildlistbox.h
@@ -0,0 +1,65 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef GUI_GUILDLISTBOX_H
+#define GUI_GUILDLISTBOX_H
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "listbox.h"
+
+class Image;
+
+class GuildListBox : public ListBox
+{
+public:
+ /**
+ * Constructor
+ */
+ GuildListBox();
+
+ /**
+ * Draws the list box.
+ */
+ void draw(gcn::Graphics *gcnGraphics);
+
+ void mousePressed(gcn::MouseEvent &event);
+
+ /**
+ * Sets the index of the selected element.
+ */
+// void setSelected(int selected);
+
+ /**
+ * Set whether a member is online or offline
+ */
+ void setOnlineStatus(const std::string &user, bool online);
+
+private:
+ Image *onlineIcon;
+ Image *offlineIcon;
+ typedef std::map<std::string, bool> UserMap;
+ UserMap mUsers;
+};
+
+#endif
diff --git a/src/gui/guildwindow.cpp b/src/gui/guildwindow.cpp
new file mode 100644
index 00000000..c8a1872f
--- /dev/null
+++ b/src/gui/guildwindow.cpp
@@ -0,0 +1,273 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * $$
+ */
+
+#include "guildwindow.h"
+
+#include "button.h"
+#include "chat.h"
+#include "confirm_dialog.h"
+#include "guildlistbox.h"
+#include "scrollarea.h"
+#include "textdialog.h"
+#include "windowcontainer.h"
+
+#include "widgets/layout.h"
+#include "widgets/tabbedarea.h"
+
+#include "../guild.h"
+#include "../log.h"
+#include "../localplayer.h"
+
+#include "../net/tmwserv/chatserver/guild.h"
+#include "../utils/dtor.h"
+#include "../utils/gettext.h"
+
+#include <algorithm>
+
+#include <guichan/widgets/tab.hpp>
+
+GuildWindow::GuildWindow():
+ Window(_("Guild")),
+ mFocus(false)
+{
+ setWindowName("Guild");
+ setCaption(_("Guild"));
+ setResizable(false);
+ setCloseButton(true);
+ setMinWidth(200);
+ setMinHeight(280);
+ setDefaultSize(124, 41, 288, 330);
+
+ // Set button events Id
+ mGuildButton[0] = new Button(_("Create Guild"), "CREATE_GUILD", this);
+ mGuildButton[1] = new Button(_("Invite User"), "INVITE_USER", this);
+ mGuildButton[2] = new Button(_("Quit Guild"), "QUIT_GUILD", this);
+ mGuildButton[1]->setEnabled(false);
+ mGuildButton[2]->setEnabled(false);
+
+ mGuildTabs = new TabbedArea();
+
+ place(0, 0, mGuildButton[0]);
+ place(1, 0, mGuildButton[1]);
+ place(2, 0, mGuildButton[2]);
+ place(0, 1, mGuildTabs);
+ Layout &layout = getLayout();
+ layout.setColWidth(0, 48);
+ layout.setColWidth(1, 65);
+
+ loadWindowState();
+}
+
+GuildWindow::~GuildWindow()
+{
+ delete mGuildTabs;
+}
+
+void GuildWindow::update()
+{
+ updateTab();
+
+ if (mGuildButton[2]->isEnabled() && mGuildTabs->getNumberOfTabs() <= 0)
+ {
+ mGuildButton[2]->setEnabled(false);
+ mGuildButton[1]->setEnabled(false);
+ }
+}
+
+void GuildWindow::draw(gcn::Graphics *g)
+{
+ update();
+
+ Window::draw(g);
+}
+
+void GuildWindow::action(const gcn::ActionEvent &event)
+{
+ const std::string &eventId = event.getId();
+
+ // Stats Part
+ if (eventId == "CREATE_GUILD")
+ {
+ // Set focus so that guild name to be created can be typed.
+ mFocus = true;
+ guildDialog = new TextDialog("Guild Name", "Choose your guild's name", this);
+ guildDialog->setOKButtonActionId("CREATE_GUILD_OK");
+ guildDialog->addActionListener(this);
+ }
+ else if (eventId == "INVITE_USER")
+ {
+ // TODO - Give feedback on whether the invite succeeded
+ mFocus = true;
+ inviteDialog = new TextDialog("Member Invite", "Who would you like to invite?", this);
+ inviteDialog->setOKButtonActionId("INVITE_USER_OK");
+ inviteDialog->addActionListener(this);
+ }
+ else if (eventId == "QUIT_GUILD")
+ {
+ short guild = getSelectedGuild();
+ if (guild)
+ {
+ Net::ChatServer::Guild::quitGuild(guild);
+ localChatTab->chatLog("Guild " + mGuildTabs->getSelectedTab()->getCaption() + " quit", BY_SERVER);
+ }
+ }
+ else if (eventId == "CREATE_GUILD_OK")
+ {
+ std::string name = guildDialog->getText();
+ if(name.size() > 16)
+ {
+ // TODO : State too many characters in input.
+ return;
+ }
+ // Process guild name to be created, and unfocus.
+ Net::ChatServer::Guild::createGuild(name);
+
+ // Defocus dialog
+ mFocus = false;
+ localChatTab->chatLog("Creating Guild called " + name, BY_SERVER);
+ guildDialog->scheduleDelete();
+ }
+ else if (eventId == "INVITE_USER_OK")
+ {
+ std::string name = inviteDialog->getText();
+ short selectedGuild = getSelectedGuild();
+
+ // Process invited user to be created and unfocus.
+ Net::ChatServer::Guild::invitePlayer(name, selectedGuild);
+
+ // Defocus dialog
+ mFocus = false;
+ localChatTab->chatLog("Invited user " + name, BY_SERVER);
+ inviteDialog->scheduleDelete();
+ }
+ else if (eventId == "yes")
+ {
+ logger->log("Sending invitation acceptance.");
+ Net::ChatServer::Guild::acceptInvite(invitedGuild);
+ }
+}
+
+void GuildWindow::newGuildTab(const std::string &guildName)
+{
+ // Create new tab
+ GuildListBox *list = new GuildListBox();
+ list->setListModel(player_node->getGuild(guildName));
+ ScrollArea *sa = new ScrollArea(list);
+ sa->setDimension(gcn::Rectangle(5, 5, 135, 250));
+
+ // Add the listbox to the map
+ mGuildLists.insert(std::pair<std::string, GuildListBox*>(guildName, list));
+
+ mGuildTabs->addTab(guildName, sa);
+ mGuildTabs->setDimension(gcn::Rectangle(28,35,140,250));
+
+ updateTab();
+}
+
+void GuildWindow::updateTab()
+{
+ gcn::Tab *tab = mGuildTabs->getSelectedTab();
+ if (tab)
+ {
+ setTab(tab->getCaption());
+ }
+ mGuildTabs->logic();
+}
+
+void GuildWindow::setTab(const std::string &guildName)
+{
+ // Only enable invite button if user has rights
+ if(player_node->checkInviteRights(guildName))
+ {
+ mGuildButton[1]->setEnabled(true);
+ }
+ else
+ {
+ mGuildButton[1]->setEnabled(false);
+ }
+
+ mGuildButton[2]->setEnabled(true);
+}
+
+bool GuildWindow::isWindowFocused()
+{
+ return mFocus;
+}
+
+short GuildWindow::getSelectedGuild()
+{
+ if (mGuildTabs->getNumberOfTabs() > 0)
+ {
+
+ Guild *guild = player_node->getGuild(mGuildTabs->getSelectedTab()->getCaption());
+
+ if (guild)
+ {
+ return guild->getId();
+ }
+ }
+
+ return 0;
+}
+
+void GuildWindow::openAcceptDialog(const std::string &inviterName,
+ const std::string &guildName)
+{
+ std::string msg = inviterName + " has invited you to join the guild " + guildName;
+ localChatTab->chatLog(msg, BY_SERVER);
+
+ acceptDialog = new ConfirmDialog("Accept Guild Invite", msg, this);
+ acceptDialog->addActionListener(this);
+
+ invitedGuild = guildName;
+}
+
+void GuildWindow::requestMemberList(short guildId)
+{
+ // Get the list of members for displaying in the guild window.
+ Net::ChatServer::Guild::getGuildMembers(guildId);
+}
+
+void GuildWindow::removeTab(int guildId)
+{
+ Guild* guild = player_node->getGuild(guildId);
+ if (guild)
+ {
+ Tab *tab = mGuildTabs->getTab(guild->getName());
+ if (tab)
+ {
+ mGuildTabs->removeTab(tab);
+ }
+ updateTab();
+ }
+ mGuildTabs->logic();
+}
+
+void GuildWindow::setOnline(const std::string &guildName, const std::string &member,
+ bool online)
+{
+ GuildListMap::iterator itr = mGuildLists.find(guildName);
+ if (itr != mGuildLists.end())
+ {
+ itr->second->setOnlineStatus(member, online);
+ }
+}
diff --git a/src/gui/guildwindow.h b/src/gui/guildwindow.h
new file mode 100644
index 00000000..88a084e9
--- /dev/null
+++ b/src/gui/guildwindow.h
@@ -0,0 +1,135 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef GUI_GUILDWINDOW_H
+#define GUI_GUILDWINDOW_H
+
+#include <iosfwd>
+#include <map>
+#include <vector>
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/widgets/listbox.hpp>
+
+#include "window.h"
+
+#include "../guichanfwd.h"
+
+class LocalPlayer;
+class TextDialog;
+class ConfirmDialog;
+class GuildListBox;
+class ScrollArea;
+class GCContainer;
+class TabbedArea;
+
+class GuildWindow : public Window, public gcn::ActionListener
+{
+public:
+ /**
+ * Constructor.
+ */
+ GuildWindow();
+
+ /**
+ * Destructor.
+ */
+ ~GuildWindow();
+
+ /**
+ * Called when receiving actions from widget.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Draw this window.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Updates this dialog.
+ */
+ void update();
+
+ /**
+ * Create a new tab for a guild list.
+ */
+ void newGuildTab(const std::string &guildName);
+
+ /**
+ * Display guild's member list to active tab
+ */
+ void setTab(const std::string &guildName);
+
+ /**
+ * Update the contents of the active tab
+ */
+ void updateTab();
+
+ /**
+ * Check if the window is in focus.
+ */
+ bool isWindowFocused();
+
+ /**
+ * Create a dialog for accepting an invite
+ */
+ void openAcceptDialog(const std::string &inviterName, const std::string &guildName);
+
+ /**
+ * Request member list
+ */
+ void requestMemberList(short guildId);
+
+ /**
+ * Removes the selected tab
+ */
+ void removeTab(int guildId);
+
+ /**
+ * Set guild member status in userlist
+ */
+ void setOnline(const std::string &guildName, const std::string &member,
+ bool online);
+
+protected:
+ /**
+ * Get selected guild tab
+ * @return Returns selected guild
+ */
+ short getSelectedGuild();
+
+private:
+ gcn::Button *mGuildButton[3];
+ TextDialog *guildDialog;
+ TextDialog *inviteDialog;
+ ConfirmDialog *acceptDialog;
+ TabbedArea *mGuildTabs;
+ ScrollArea *mScrollArea;
+ bool mFocus;
+ std::string invitedGuild;
+ typedef std::map<std::string, GuildListBox*> GuildListMap;
+ GuildListMap mGuildLists;
+};
+
+extern GuildWindow *guildWindow;
+
+#endif
diff --git a/src/gui/help.cpp b/src/gui/help.cpp
index 0974abf7..4b4ba983 100644
--- a/src/gui/help.cpp
+++ b/src/gui/help.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,12 +36,12 @@ HelpWindow::HelpWindow():
setMinWidth(300);
setMinHeight(250);
setContentSize(455, 350);
- setWindowName(_("Help"));
+ setWindowName("Help");
setResizable(true);
setDefaultSize(500, 400, ImageRect::CENTER);
- mBrowserBox = new BrowserBox();
+ mBrowserBox = new BrowserBox;
mBrowserBox->setOpaque(false);
mScrollArea = new ScrollArea(mBrowserBox);
Button *okButton = new Button(_("Close"), "close", this);
@@ -71,7 +70,7 @@ void HelpWindow::action(const gcn::ActionEvent &event)
}
}
-void HelpWindow::handleLink(const std::string& link)
+void HelpWindow::handleLink(const std::string &link)
{
std::string helpFile = link;
loadHelp(helpFile);
diff --git a/src/gui/help.h b/src/gui/help.h
index 93d32c18..8764e733 100644
--- a/src/gui/help.h
+++ b/src/gui/help.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -50,7 +49,7 @@ class HelpWindow : public Window, public LinkHandler,
/**
* Handles link action.
*/
- void handleLink(const std::string& link);
+ void handleLink(const std::string &link);
/**
* Loads help in the dialog.
diff --git a/src/gui/icon.cpp b/src/gui/icon.cpp
new file mode 100644
index 00000000..c4f0ecc3
--- /dev/null
+++ b/src/gui/icon.cpp
@@ -0,0 +1,58 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "icon.h"
+
+#include "../graphics.h"
+
+#include "../resources/image.h"
+#include "../resources/resourcemanager.h"
+
+Icon::Icon(const std::string &file)
+ : mImage(0)
+{
+ mImage = ResourceManager::getInstance()->getImage(file);
+ setSize(mImage->getWidth(), mImage->getHeight());
+
+}
+
+Icon::Icon(Image *image)
+ : mImage(image)
+{
+ setSize(mImage->getWidth(), mImage->getHeight());
+}
+
+void Icon::setImage(Image *image)
+{
+ mImage = image;
+ setSize(mImage->getWidth(), mImage->getHeight());
+}
+
+void Icon::draw(gcn::Graphics *g)
+{
+ if(mImage)
+ {
+ Graphics *graphics = static_cast<Graphics*>(g);
+ const int x = (getWidth() - mImage->getWidth()) / 2;
+ const int y = (getHeight() - mImage->getHeight()) / 2;
+ graphics->drawImage(mImage, x, y);
+ }
+}
diff --git a/src/gui/icon.h b/src/gui/icon.h
new file mode 100644
index 00000000..f8d77e0f
--- /dev/null
+++ b/src/gui/icon.h
@@ -0,0 +1,66 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef ICON_H
+#define ICON_H
+
+#include <guichan/widget.hpp>
+
+class Image;
+
+/**
+ * An icon.
+ *
+ * \ingroup GUI
+ */
+class Icon : public gcn::Widget
+{
+ public:
+ /**
+ * Constructor.
+ */
+ Icon(const std::string &filename);
+
+ /**
+ * Constructor, uses an existing Image.
+ */
+ Icon(Image *image);
+
+ /**
+ * Gets the current Image.
+ */
+ Image *getImage() const { return mImage; }
+
+ /**
+ * Sets the image to display.
+ */
+ void setImage(Image *image);
+
+ /**
+ * Draws the Icon.
+ */
+ void draw(gcn::Graphics *g);
+
+ private:
+ Image *mImage;
+};
+
+#endif // ICON_H
diff --git a/src/gui/inttextfield.cpp b/src/gui/inttextfield.cpp
index 40bbd887..d3fe448b 100644
--- a/src/gui/inttextfield.cpp
+++ b/src/gui/inttextfield.cpp
@@ -1,8 +1,8 @@
/*
- * Aethyra
- * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net>
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -57,6 +57,16 @@ void IntTextField::setRange(int min, int max)
{
mMin = min;
mMax = max;
+
+ if (mValue < mMin)
+ mValue = mMin;
+ else if (mValue > mMax)
+ mValue = mMax;
+
+ if (mDefault < mMin)
+ mDefault = mMin;
+ else if (mDefault > mMax)
+ mDefault = mMax;
}
int IntTextField::getValue()
@@ -66,18 +76,28 @@ int IntTextField::getValue()
void IntTextField::setValue(int i)
{
- if (i >= mMin && i <= mMax)
- mValue = i;
- else if (i < mMin)
+ if (i < mMin)
mValue = mMin;
else if (i > mMax)
mValue = mMax;
+ else
+ mValue = i;
const std::string valStr = toString(mValue);
setText(valStr);
setCaretPosition(valStr.length() + 1);
}
+void IntTextField::setDefaultValue(int value)
+{
+ if (value < mMin)
+ mDefault = mMin;
+ else if (value > mMax)
+ mDefault = mMax;
+ else
+ mDefault = value;
+}
+
void IntTextField::reset()
{
setValue(mDefault);
diff --git a/src/gui/inttextfield.h b/src/gui/inttextfield.h
index f2e294ca..ec768bea 100644
--- a/src/gui/inttextfield.h
+++ b/src/gui/inttextfield.h
@@ -1,8 +1,8 @@
/*
- * Aethyra
- * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net>
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -56,6 +56,11 @@ class IntTextField : public TextField
void setValue(int value);
/**
+ * Set the default value of the text box to the specified value.
+ */
+ void setDefaultValue(int value);
+
+ /**
* Responds to key presses.
*/
void keyPressed(gcn::KeyEvent &event);
diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp
index fef55b6c..21d2df3f 100644
--- a/src/gui/inventorywindow.cpp
+++ b/src/gui/inventorywindow.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,6 +31,7 @@
#include "label.h"
#include "progressbar.h"
#include "scrollarea.h"
+#include "sdlinput.h"
#include "viewport.h"
#include "widgets/layout.h"
@@ -39,6 +39,7 @@
#include "../inventory.h"
#include "../item.h"
#include "../localplayer.h"
+#include "../units.h"
#include "../resources/iteminfo.h"
@@ -48,14 +49,19 @@
InventoryWindow::InventoryWindow(int invSize):
Window(_("Inventory")),
mMaxSlots(invSize),
+ mSplit(false),
mItemDesc(false)
{
- setWindowName(_("Inventory"));
- setResizable(true);
+ setWindowName("Inventory");
+ setResizable(false);
setCloseButton(true);
-
+ // LEEOR/TODO: Since this window is not resizable, do we really need to set these
+ // values or can we drop them?
+ setMinWidth(375);
+ setMinHeight(283);
// If you adjust these defaults, don't forget to adjust the trade window's.
setDefaultSize(375, 300, ImageRect::CENTER);
+ addKeyListener(this);
std::string longestUseString = getFont()->getWidth(_("Equip")) >
getFont()->getWidth(_("Use")) ?
@@ -69,16 +75,23 @@ InventoryWindow::InventoryWindow(int invSize):
mUseButton = new Button(longestUseString, "use", this);
mDropButton = new Button(_("Drop"), "drop", this);
-
- mItems = new ItemContainer(player_node->getInventory(), 2);
+#ifdef TMWSERV_SUPPORT
+ mSplitButton = new Button(_("Split"), "split", this);
+#endif
+
+#ifdef TMWSERV_SUPPORT
+ mItems = new ItemContainer(player_node->getInventory(), 10, 5);
+#else
+ mItems = new ItemContainer(player_node->getInventory(), 10, 5, 2);
+#endif
mItems->addSelectionListener(this);
mInvenScroll = new ScrollArea(mItems);
mInvenScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
- mTotalWeight = player_node->mTotalWeight;
- mMaxWeight = player_node->mMaxWeight;
- mUsedSlots = player_node->getInventory()->getNumberOfSlotsUsed();
+ mTotalWeight = -1;
+ mMaxWeight = -1;
+ mUsedSlots = -1;
mSlotsLabel = new Label(_("Slots: "));
mWeightLabel = new Label(_("Weight: "));
@@ -93,12 +106,15 @@ InventoryWindow::InventoryWindow(int invSize):
place(1, 0, mWeightBar, 3);
place(4, 0, mSlotsLabel).setPadding(3);
place(5, 0, mSlotsBar, 2);
- place(0, 1, mInvenScroll, 7, 4);
- place(5, 5, mDropButton);
- place(6, 5, mUseButton);
+ place(0, 1, mInvenScroll, 100).setPadding(3);
+ place(0, 2, mUseButton);
+ place(1, 2, mDropButton);
+#ifdef TMWSERV_SUPPORT
+ place(2, 2, mSplitButton);
+#endif
Layout &layout = getLayout();
- layout.setRowHeight(0, mDropButton->getHeight());
+ layout.setRowHeight(0, Layout::AUTO_SET);
loadWindowState();
}
@@ -121,17 +137,18 @@ void InventoryWindow::logic()
const int usedSlots = player_node->getInventory()->getNumberOfSlotsUsed();
- if (mMaxWeight != player_node->mMaxWeight ||
- mTotalWeight != player_node->mTotalWeight || mUsedSlots != usedSlots)
+ if (mMaxWeight != player_node->getMaxWeight() ||
+ mTotalWeight != player_node->getTotalWeight() ||
+ mUsedSlots != usedSlots)
{
- mTotalWeight = player_node->mTotalWeight;
- mMaxWeight = player_node->mMaxWeight;
+ mTotalWeight = player_node->getTotalWeight();
+ mMaxWeight = player_node->getMaxWeight();
mUsedSlots = usedSlots;
// Weight Bar coloration
if (mTotalWeight < (mMaxWeight / 3))
mWeightBar->setColor(0, 0, 255); // Blue
- else if (mTotalWeight < ((mMaxWeight / 3) * 2))
+ else if (mTotalWeight < ((mMaxWeight * 2) / 3))
mWeightBar->setColor(255, 255, 0); // Yellow
else
mWeightBar->setColor(255, 0, 0); // Red
@@ -141,7 +158,9 @@ void InventoryWindow::logic()
mWeightBar->setProgress((float) mTotalWeight / mMaxWeight);
mSlotsBar->setText(strprintf("%d/%d", mUsedSlots, mMaxSlots));
- mWeightBar->setText(strprintf("%dg/%dg", mTotalWeight, mMaxWeight));
+ mWeightBar->setText(strprintf("%s/%s",
+ Units::formatWeight(mTotalWeight).c_str(),
+ Units::formatWeight(mMaxWeight).c_str()));
}
}
@@ -154,6 +173,14 @@ void InventoryWindow::action(const gcn::ActionEvent &event)
if (event.getId() == "use")
{
+#ifdef TMWSERV_SUPPORT
+ if (item->isEquipment()) {
+ player_node->equipItem(item);
+ }
+ else {
+ player_node->useItem(item->getInvIndex());
+ }
+#else
if (item->isEquipment())
{
if (item->isEquipped())
@@ -163,19 +190,33 @@ void InventoryWindow::action(const gcn::ActionEvent &event)
}
else
player_node->useItem(item);
+#endif
}
else if (event.getId() == "drop")
{
- if (item->getQuantity() == 1)
- player_node->dropItem(item, 1);
- else
- {
+ if (item->getQuantity() > 1) {
// Choose amount of items to drop
new ItemAmountWindow(AMOUNT_ITEM_DROP, this, item);
}
+ else {
+ player_node->dropItem(item, 1);
+ }
+ mItems->selectNone();
+ }
+ else if (event.getId() == "split")
+ {
+ if (item && !item->isEquipment() && item->getQuantity() > 1) {
+ new ItemAmountWindow(AMOUNT_ITEM_SPLIT, this, item,
+ (item->getQuantity() - 1));
+ }
}
}
+Item* InventoryWindow::getSelectedItem() const
+{
+ return mItems->getSelectedItem();
+}
+
void InventoryWindow::mouseClicked(gcn::MouseEvent &event)
{
Window::mouseClicked(event);
@@ -196,15 +237,55 @@ void InventoryWindow::mouseClicked(gcn::MouseEvent &event)
}
}
+#ifdef TMWSERV_SUPPORT
+void InventoryWindow::keyPressed(gcn::KeyEvent &event)
+{
+ switch (event.getKey().getValue())
+ {
+ case Key::LEFT_SHIFT:
+ case Key::RIGHT_SHIFT:
+ mSplit = true;
+ break;
+ }
+}
+
+void InventoryWindow::keyReleased(gcn::KeyEvent &event)
+{
+ switch (event.getKey().getValue())
+ {
+ case Key::LEFT_SHIFT:
+ case Key::RIGHT_SHIFT:
+ mSplit = false;
+ break;
+ }
+}
+#endif
+
+void InventoryWindow::valueChanged(const gcn::SelectionEvent &event)
+{
+ if (mSplit)
+ {
+ Item *item = mItems->getSelectedItem();
+
+ if (item && !item->isEquipment() && item->getQuantity() > 1)
+ {
+ mSplit = false;
+ new ItemAmountWindow(AMOUNT_ITEM_SPLIT, this, item, (item->getQuantity() - 1));
+ }
+ }
+}
+
void InventoryWindow::updateButtons()
{
const Item *selectedItem = mItems->getSelectedItem();
if (selectedItem && selectedItem->isEquipment())
{
+#ifdef EATHENA_SUPPORT
if (selectedItem->isEquipped())
mUseButton->setCaption(_("Unequip"));
else
+#endif
mUseButton->setCaption(_("Equip"));
}
else
@@ -212,9 +293,15 @@ void InventoryWindow::updateButtons()
mUseButton->setEnabled(selectedItem != 0);
mDropButton->setEnabled(selectedItem != 0);
-}
-Item* InventoryWindow::getSelectedItem() const
-{
- return mItems->getSelectedItem();
+#ifdef TMWSERV_SUPPORT
+ if (selectedItem && !selectedItem->isEquipment() &&
+ selectedItem->getQuantity() > 1)
+ {
+ mSplitButton->setEnabled(true);
+ }
+ else {
+ mSplitButton->setEnabled(false);
+ }
+#endif
}
diff --git a/src/gui/inventorywindow.h b/src/gui/inventorywindow.h
index 5035bf1c..0bdc8809 100644
--- a/src/gui/inventorywindow.h
+++ b/src/gui/inventorywindow.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,13 +22,14 @@
#ifndef INVENTORYWINDOW_H
#define INVENTORYWINDOW_H
-#include <guichan/actionlistener.hpp>
-#include <guichan/selectionlistener.hpp>
-
#include "window.h"
#include "../inventory.h"
+#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
+#include <guichan/selectionlistener.hpp>
+
class Item;
class ItemContainer;
class ProgressBar;
@@ -40,14 +40,20 @@ class TextBox;
*
* \ingroup Interface
*/
-class InventoryWindow : public Window, gcn::ActionListener,
- gcn::SelectionListener
+class InventoryWindow : public Window,
+ public gcn::ActionListener,
+ public gcn::KeyListener,
+ public gcn::SelectionListener
{
public:
/**
* Constructor.
*/
+#ifdef TMWSERV_SUPPORT
+ InventoryWindow(int invSize = (INVENTORY_SIZE));
+#else
InventoryWindow(int invSize = (INVENTORY_SIZE - 2));
+#endif
/**
* Destructor.
@@ -69,8 +75,28 @@ class InventoryWindow : public Window, gcn::ActionListener,
*/
Item* getSelectedItem() const;
+ /**
+ * Handles the mouse clicks.
+ */
void mouseClicked(gcn::MouseEvent &event);
+#ifdef TMWSERV_SUPPORT
+ /**
+ * Handles the key presses.
+ */
+ void keyPressed(gcn::KeyEvent &event);
+
+ /**
+ * Handles the key releases.
+ */
+ void keyReleased(gcn::KeyEvent &event);
+#endif
+
+ /**
+ * Updates labels to currently selected item.
+ */
+ void valueChanged(const gcn::SelectionEvent &event);
+
private:
void updateButtons(); /**< Updates button states. */
@@ -81,9 +107,12 @@ class InventoryWindow : public Window, gcn::ActionListener,
int mUsedSlots;
int mTotalWeight;
int mMaxWeight;
- gcn::Button *mUseButton, *mDropButton;
- gcn::ScrollArea *mInvenScroll;
-
+ gcn::Button *mUseButton;
+ gcn::Button *mDropButton;
+#ifdef TMWSERV_SUPPORT
+ gcn::Button *mSplitButton;
+#endif
+ gcn::ScrollArea *mInvenScroll; /**< Inventory Scroll Area. */
gcn::Label *mWeightLabel;
gcn::Label *mSlotsLabel;
@@ -92,6 +121,7 @@ class InventoryWindow : public Window, gcn::ActionListener,
int mMaxSlots;
+ bool mSplit;
bool mItemDesc;
};
diff --git a/src/gui/item_amount.cpp b/src/gui/item_amount.cpp
index 5b3380c2..0f6aa593 100644
--- a/src/gui/item_amount.cpp
+++ b/src/gui/item_amount.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,7 +23,9 @@
#include "item_amount.h"
#include "label.h"
#include "slider.h"
+#ifdef EATHENA_SUPPORT
#include "storagewindow.h"
+#endif
#include "trade.h"
#include "widgets/layout.h"
@@ -35,12 +36,16 @@
#include "../utils/gettext.h"
#include "../utils/strprintf.h"
-ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item):
+ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item,
+ int maxRange):
Window("", true, parent),
mItem(item),
- mMax(item->getQuantity()),
+ mMax(maxRange),
mUsage(usage)
{
+ if (!mMax)
+ mMax = mItem->getQuantity();
+
setCloseButton(true);
// Integer field
@@ -94,6 +99,9 @@ ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item):
case AMOUNT_STORE_REMOVE:
setCaption(_("Select amount of items to retrieve."));
break;
+ case AMOUNT_ITEM_SPLIT:
+ setCaption(_("Select amount of items to split."));
+ break;
default:
break;
}
@@ -140,12 +148,18 @@ void ItemAmountWindow::action(const gcn::ActionEvent &event)
case AMOUNT_ITEM_DROP:
player_node->dropItem(mItem, amount);
break;
+#ifdef TMWSERV_SUPPORT
+ case AMOUNT_ITEM_SPLIT:
+ player_node->splitItem(mItem, amount);
+ break;
+#else
case AMOUNT_STORE_ADD:
storageWindow->addStore(mItem, amount);
break;
case AMOUNT_STORE_REMOVE:
storageWindow->removeStore(mItem, amount);
break;
+#endif
default:
return;
break;
diff --git a/src/gui/item_amount.h b/src/gui/item_amount.h
index 34b33b37..344f8c28 100644
--- a/src/gui/item_amount.h
+++ b/src/gui/item_amount.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,9 +33,10 @@ class Item;
#define AMOUNT_ITEM_DROP 2
#define AMOUNT_STORE_ADD 3
#define AMOUNT_STORE_REMOVE 4
+#define AMOUNT_ITEM_SPLIT 5
/**
- * Window used for selecting the amount of items to drop or trade.
+ * Window used for selecting the amount of items to drop, trade or split.
*
* \ingroup Interface
*/
@@ -46,7 +46,7 @@ class ItemAmountWindow : public Window, public gcn::ActionListener
/**
* Constructor.
*/
- ItemAmountWindow(int usage, Window *parent, Item *item);
+ ItemAmountWindow(int usage, Window *parent, Item *item, int maxRange = 0);
/**
* Called when receiving actions from widget.
diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp
index 8139e85e..960f58ad 100644
--- a/src/gui/itemcontainer.cpp
+++ b/src/gui/itemcontainer.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,49 +19,72 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <guichan/mouseinput.hpp>
-#include <guichan/selectionlistener.hpp>
+#include "gui/itemcontainer.h"
-#include "itemcontainer.h"
-#include "itempopup.h"
-#include "palette.h"
-#include "viewport.h"
+#include "gui/chat.h"
+#include "gui/itempopup.h"
+#include "gui/palette.h"
+#include "gui/sdlinput.h"
+#include "gui/viewport.h"
-#include "../graphics.h"
-#include "../inventory.h"
-#include "../item.h"
-#include "../itemshortcut.h"
-#include "../localplayer.h"
-#include "../log.h"
+#include "graphics.h"
+#include "inventory.h"
+#include "item.h"
+#include "itemshortcut.h"
+#include "localplayer.h"
+#include "log.h"
-#include "../resources/image.h"
-#include "../resources/resourcemanager.h"
+#include "resources/image.h"
+#include "resources/iteminfo.h"
+#include "resources/resourcemanager.h"
-#include "../utils/stringutils.h"
+#include "utils/stringutils.h"
-const int ItemContainer::gridWidth = 36; // item icon width + 4
-const int ItemContainer::gridHeight = 42; // item icon height + 10
+#include <guichan/mouseinput.hpp>
+#include <guichan/selectionlistener.hpp>
-static const int NO_ITEM = -1;
+// TODO: Add support for adding items to the item shortcut window (global
+// itemShortcut).
-ItemContainer::ItemContainer(Inventory *inventory, int offset):
+static const int BOX_WIDTH = 36;
+static const int BOX_HEIGHT = 44;
+
+enum
+{
+ SEL_NONE = 0,
+ SEL_SELECTED,
+ SEL_SELECTING,
+ SEL_DESELECTING,
+ SEL_DRAGGING
+};
+
+ItemContainer::ItemContainer(Inventory *inventory,
+ int gridColumns,
+ int gridRows,
+ int offset):
mInventory(inventory),
- mSelectedItemIndex(NO_ITEM),
- mLastSelectedItemId(NO_ITEM),
- mOffset(offset)
+ mGridColumns(gridColumns),
+ mGridRows(gridRows),
+ mOffset(offset),
+ mSelectedItem(NULL),
+ mHighlightedItem(NULL),
+ mSelectionStatus(SEL_NONE),
+ mSwapItems(false),
+ mDescItems(false)
{
mItemPopup = new ItemPopup();
- mItemPopup->setOpaque(false);
+ setFocusable(true);
ResourceManager *resman = ResourceManager::getInstance();
mSelImg = resman->getImage("graphics/gui/selection.png");
if (!mSelImg) logger->error("Unable to load selection.png");
- mMaxItems = mInventory->getLastUsedSlot() - (mOffset - 1); // Count from 0, usage from 2
-
+ addKeyListener(this);
addMouseListener(this);
- addWidgetListener(this);
+
+ setSize((BOX_WIDTH - 1) * mGridColumns + 1,
+ (BOX_HEIGHT - 1) * mGridRows + 1);
}
ItemContainer::~ItemContainer()
@@ -71,185 +93,214 @@ ItemContainer::~ItemContainer()
delete mItemPopup;
}
-void ItemContainer::logic()
-{
- if (!isVisible())
- return;
-
- gcn::Widget::logic();
-
- int i = mInventory->getLastUsedSlot() - (mOffset - 1); // Count from 0, usage from 2
-
- if (i != mMaxItems)
- {
- mMaxItems = i;
- recalculateHeight();
- }
-}
-
void ItemContainer::draw(gcn::Graphics *graphics)
{
- if (!isVisible())
- return;
-
- int columns = getWidth() / gridWidth;
+ Graphics *g = static_cast<Graphics*>(graphics);
- // Have at least 1 column
- if (columns < 1)
- columns = 1;
-
- /*
- * mOffset is used to compensate for some weirdness that eAthena inherited
- * from Ragnarok Online. Inventory slots and cart slots are +2 from their
- * actual index, while storage slots are +1.
- */
- for (int i = mOffset; i < mInventory->getSize(); i++)
+ for (int i = 0; i < mGridColumns; i++)
{
- Item *item = mInventory->getItem(i);
-
- if (!item || item->getQuantity() <= 0)
- continue;
+ for (int j = 0; j < mGridRows; j++)
+ {
+ // Items positions made to overlap on another.
+ int itemX = i * (BOX_WIDTH - 1);
+ int itemY = j * (BOX_HEIGHT - 1);
- int itemX = ((i - mOffset) % columns) * gridWidth;
- int itemY = ((i - mOffset) / columns) * gridHeight;
+ // Set color to black.
+ g->setColor(gcn::Color(0, 0, 0));
+ // Draw box border.
+ g->drawRectangle(
+ gcn::Rectangle(itemX, itemY, BOX_WIDTH, BOX_HEIGHT));
- // Draw selection image below selected item
- if (mSelectedItemIndex == i)
- static_cast<Graphics*>(graphics)->drawImage(mSelImg, itemX, itemY);
+ Item *item = mInventory->getItem((j * mGridColumns) + i);
- // Draw item icon
- Image* image = item->getImage();
+ if (!item || item->getId() == 0)
+ continue;
- if (image)
- static_cast<Graphics*>(graphics)->drawImage(image, itemX, itemY);
+ Image *image = item->getImage();
+ if (image)
+ {
+ if (item == mSelectedItem)
+ {
+ if (mSelectionStatus == SEL_DRAGGING) {
+ // Reposition the coords to that of the cursor.
+ itemX = mDragPosX - (BOX_WIDTH / 2);
+ itemY = mDragPosY - (BOX_HEIGHT / 2);
+ }
+ else {
+ // Draw selected image.
+ g->drawImage(mSelImg, itemX, itemY);
+ }
+ }
+ g->drawImage(image, itemX, itemY);
+ }
+ if (item->getQuantity() > 1) {
+ // Draw item caption
+ g->drawText(
+ toString(item->getQuantity()),
+ itemX + BOX_WIDTH / 2,
+ itemY + BOX_HEIGHT - 14,
+ gcn::Graphics::CENTER);
+ }
- // Draw item caption
- graphics->setFont(getFont());
- graphics->setColor(guiPalette->getColor(Palette::TEXT));
- graphics->drawText(
- (item->isEquipped() ? "Eq." : toString(item->getQuantity())),
- itemX + gridWidth / 2, itemY + gridHeight - 11,
- gcn::Graphics::CENTER);
+ }
}
-}
-void ItemContainer::widgetResized(const gcn::Event &event)
-{
- recalculateHeight();
+ if (isFocused() && mHighlightedItem) {
+ // Items positions made to overlap on another.
+ const int i = mHighlightedItem->getInvIndex();
+ const int itemX = (i % mGridColumns) * (BOX_WIDTH - 1);
+ const int itemY = (i / mGridColumns) * (BOX_HEIGHT - 1);
+ // Set color to orange.
+ g->setColor(gcn::Color(255, 128, 0));
+ // Draw box border.
+ g->drawRectangle(gcn::Rectangle(itemX, itemY, BOX_WIDTH, BOX_HEIGHT));
+ }
}
-void ItemContainer::recalculateHeight()
+void ItemContainer::selectNone()
{
- int cols = getWidth() / gridWidth;
-
- if (cols < 1)
- cols = 1;
-
- const int rows = (mMaxItems / cols) + (mMaxItems % cols > 0 ? 1 : 0);
- const int height = rows * gridHeight + 8;
-
- if (height != getHeight())
- setHeight(height);
+ setSelectedItem(NULL);
}
-Item *ItemContainer::getSelectedItem()
+void ItemContainer::setSelectedItem(Item *item)
{
- refindSelectedItem(); // Make sure that we're still current
-
- if (mSelectedItemIndex == NO_ITEM)
- return NULL;
-
- return mInventory->getItem(mSelectedItemIndex);
+ if (mSelectedItem != item)
+ {
+ mSelectedItem = item;
+ distributeValueChangedEvent();
+ }
}
-void ItemContainer::selectNone()
+void ItemContainer::distributeValueChangedEvent()
{
- setSelectedItemIndex(NO_ITEM);
-}
+ SelectionListenerIterator iter;
-void ItemContainer::refindSelectedItem()
-{
- if (mSelectedItemIndex != NO_ITEM)
+ for (iter = mSelectionListeners.begin(); iter != mSelectionListeners.end();
+ ++iter)
{
-
- if (mInventory->getItem(mSelectedItemIndex) &&
- mInventory->getItem(mSelectedItemIndex)->getId() == mLastSelectedItemId)
- return; // we're already fine
-
- // Otherwise ensure the invariant: we must point to an item of the specified last ID,
- // or nowhere at all.
-
- for (int i = 0; i <= mMaxItems + 1; i++)
- if (mInventory->getItem(i) &&
- mInventory->getItem(i)->getId() == mLastSelectedItemId)
- {
- mSelectedItemIndex = i;
- return;
- }
+ gcn::SelectionEvent event(this);
+ (*iter)->valueChanged(event);
}
-
- mLastSelectedItemId = mSelectedItemIndex = NO_ITEM;
}
-void ItemContainer::setSelectedItemIndex(int index)
+void ItemContainer::keyPressed(gcn::KeyEvent &event)
{
- int newSelectedItemIndex;
-
- /*
- * mOffset is used to compensate for some weirdness that eAthena inherited from
- * Ragnarok Online. Inventory slots and cart slots are +2 from their actual index,
- * while storage slots are +1.
- */
- if (index < 0 || index > mMaxItems + mOffset || mInventory->getItem(index) == NULL)
- newSelectedItemIndex = NO_ITEM;
- else
- newSelectedItemIndex = index;
- if (mSelectedItemIndex != newSelectedItemIndex)
+ switch (event.getKey().getValue())
{
- mSelectedItemIndex = newSelectedItemIndex;
-
- if (mSelectedItemIndex == NO_ITEM)
- mLastSelectedItemId = NO_ITEM;
- else
- mLastSelectedItemId = mInventory->getItem(index)->getId();
-
- distributeValueChangedEvent();
+ case Key::LEFT:
+ moveHighlight(MOVE_SELECTED_LEFT);
+ break;
+ case Key::RIGHT:
+ moveHighlight(MOVE_SELECTED_RIGHT);
+ break;
+ case Key::UP:
+ moveHighlight(MOVE_SELECTED_UP);
+ break;
+ case Key::DOWN:
+ moveHighlight(MOVE_SELECTED_DOWN);
+ break;
+ case Key::SPACE:
+ keyAction();
+ break;
+ case Key::LEFT_ALT:
+ case Key::RIGHT_ALT:
+ mSwapItems = true;
+ break;
+ case Key::RIGHT_CONTROL:
+ mDescItems = true;
+ break;
}
}
-void ItemContainer::distributeValueChangedEvent()
+void ItemContainer::keyReleased(gcn::KeyEvent &event)
{
- gcn::SelectionEvent event(this);
- std::list<gcn::SelectionListener*>::iterator i_end = mListeners.end();
- std::list<gcn::SelectionListener*>::iterator i;
-
- for (i = mListeners.begin(); i != i_end; ++i)
+ switch (event.getKey().getValue())
{
- (*i)->valueChanged(event);
+ case Key::LEFT_ALT:
+ case Key::RIGHT_ALT:
+ mSwapItems = false;
+ break;
+ case Key::RIGHT_CONTROL:
+ mDescItems = false;
+ break;
}
}
void ItemContainer::mousePressed(gcn::MouseEvent &event)
{
const int button = event.getButton();
-
if (button == gcn::MouseEvent::LEFT || button == gcn::MouseEvent::RIGHT)
{
- int columns = getWidth() / gridWidth;
- int mx = event.getX();
- int my = event.getY();
- int index = mx / gridWidth + ((my / gridHeight) * columns) + mOffset;
-
- itemShortcut->setItemSelected(-1);
- setSelectedItemIndex(index);
+ const int index = getSlotIndex(event.getX(), event.getY());
+ if (index == Inventory::NO_SLOT_INDEX) {
+ return;
+ }
Item *item = mInventory->getItem(index);
- if (item)
+ // put item name into chat window
+ if (mDescItems)
+ {
+ chatWindow->addItemText(item->getInfo().getName());
+ }
+
+ if (mSelectedItem && mSelectedItem == item)
+ {
+ mSelectionStatus = SEL_DESELECTING;
+ }
+ else if (item && item->getId())
+ {
+ setSelectedItem(item);
+ mSelectionStatus = SEL_SELECTING;
+
itemShortcut->setItemSelected(item->getId());
+ }
+ else
+ {
+ setSelectedItem(NULL);
+ mSelectionStatus = SEL_NONE;
+ }
+ }
+}
+
+void ItemContainer::mouseDragged(gcn::MouseEvent &event)
+{
+ if (mSelectionStatus != SEL_NONE)
+ {
+ mSelectionStatus = SEL_DRAGGING;
+ mDragPosX = event.getX();
+ mDragPosY = event.getY();
}
}
+void ItemContainer::mouseReleased(gcn::MouseEvent &event)
+{
+ switch (mSelectionStatus)
+ {
+ case SEL_SELECTING:
+ mSelectionStatus = SEL_SELECTED;
+ return;
+ case SEL_DESELECTING:
+ setSelectedItem(NULL);
+ mSelectionStatus = SEL_NONE;
+ return;
+ case SEL_DRAGGING:
+ mSelectionStatus = SEL_SELECTED;
+ break;
+ default:
+ return;
+ };
+
+ int index = getSlotIndex(event.getX(), event.getY());
+ if (index == Inventory::NO_SLOT_INDEX) return;
+ Item *item = mInventory->getItem(index);
+ if (item == mSelectedItem) return;
+ player_node->moveInvItem(mSelectedItem, index);
+ setSelectedItem(NULL);
+ mSelectionStatus = SEL_NONE;
+}
+
+
// Show ItemTooltip
void ItemContainer::mouseMoved(gcn::MouseEvent &event)
{
@@ -276,9 +327,95 @@ void ItemContainer::mouseExited(gcn::MouseEvent &event)
int ItemContainer::getSlotIndex(const int posX, const int posY) const
{
- int columns = getWidth() / gridWidth;
- int index = posX / gridWidth + ((posY / gridHeight) * columns) + mOffset;
+ if (getDimension().isPointInRect(posX, posY))
+ {
+ // Takes into account, boxes are overlapping each other.
+ return (posY / (BOX_HEIGHT - 1)) * mGridColumns + (posX / (BOX_WIDTH - 1));
+ }
+ return Inventory::NO_SLOT_INDEX;
+}
+
+void ItemContainer::keyAction()
+{
+ // If there is no highlight then return.
+ if (!mHighlightedItem)
+ return;
- return (index);
+ // If the highlight is on the selected item, then deselect it.
+ if (mHighlightedItem == mSelectedItem)
+ {
+ setSelectedItem(NULL);
+ mSelectionStatus = SEL_NONE;
+ }
+ // Check and swap items if necessary.
+ else if (mSwapItems &&
+ mSelectedItem &&
+ mHighlightedItem->getId())
+ {
+ player_node->moveInvItem(
+ mSelectedItem, mHighlightedItem->getInvIndex());
+ setSelectedItem(mHighlightedItem);
+ }
+ // If the highlight is on an item then select it.
+ else if (mHighlightedItem->getId())
+ {
+ setSelectedItem(mHighlightedItem);
+ mSelectionStatus = SEL_SELECTED;
+ }
+ // If the highlight is on a blank space then move it.
+ else if (mSelectedItem)
+ {
+ player_node->moveInvItem(
+ mSelectedItem, mHighlightedItem->getInvIndex());
+ setSelectedItem(NULL);
+ mSelectionStatus = SEL_NONE;
+ }
}
+void ItemContainer::moveHighlight(int direction)
+{
+ if (!mHighlightedItem)
+ {
+ if (mSelectedItem) {
+ mHighlightedItem = mSelectedItem;
+ }
+ else {
+ mHighlightedItem = mInventory->getItem(0);
+ }
+ return;
+ }
+
+ switch (direction)
+ {
+ case MOVE_SELECTED_LEFT:
+ if (mHighlightedItem->getInvIndex() % mGridColumns == 0)
+ {
+ mHighlightedItem += mGridColumns;
+ }
+ mHighlightedItem--;
+ break;
+ case MOVE_SELECTED_RIGHT:
+ if ((mHighlightedItem->getInvIndex() % mGridColumns) ==
+ (mGridColumns - 1))
+ {
+ mHighlightedItem -= mGridColumns;
+ }
+ mHighlightedItem++;
+ break;
+ case MOVE_SELECTED_UP:
+ if (mHighlightedItem->getInvIndex() / mGridColumns == 0)
+ {
+ mHighlightedItem += (mGridColumns * mGridRows);
+ }
+ mHighlightedItem -= mGridColumns;
+ break;
+ case MOVE_SELECTED_DOWN:
+ if ((mHighlightedItem->getInvIndex() / mGridColumns) ==
+ (mGridRows - 1))
+ {
+ mHighlightedItem -= (mGridColumns * mGridRows);
+ }
+ mHighlightedItem += mGridColumns;
+ break;
+ }
+}
diff --git a/src/gui/itemcontainer.h b/src/gui/itemcontainer.h
index fba4656f..38eaba01 100644
--- a/src/gui/itemcontainer.h
+++ b/src/gui/itemcontainer.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,9 +24,9 @@
#include <list>
+#include <guichan/keylistener.hpp>
#include <guichan/mouselistener.hpp>
#include <guichan/widget.hpp>
-#include <guichan/widgetlistener.hpp>
class Image;
class Inventory;
@@ -44,14 +43,19 @@ namespace gcn {
* \ingroup GUI
*/
class ItemContainer : public gcn::Widget,
- public gcn::MouseListener,
- public gcn::WidgetListener
+ public gcn::KeyListener,
+ public gcn::MouseListener
{
public:
/**
* Constructor. Initializes the graphic.
+ * @param inventory
+ * @param gridColumns Amount of columns in grid.
+ * @param gridRows Amount of rows in grid.
+ * @param offset Index offset
*/
- ItemContainer(Inventory *inventory, int offset);
+ ItemContainer(Inventory *inventory, int gridColumns, int gridRows,
+ int offset = 0);
/**
* Destructor.
@@ -59,19 +63,19 @@ class ItemContainer : public gcn::Widget,
virtual ~ItemContainer();
/**
- * Handles the logic of the ItemContainer
+ * Draws the items.
*/
- void logic();
+ void draw(gcn::Graphics *graphics);
/**
- * Draws the items.
+ * Handles the key presses.
*/
- void draw(gcn::Graphics *graphics);
+ void keyPressed(gcn::KeyEvent &event);
/**
- * Called whenever the widget changes size.
+ * Handles the key releases.
*/
- void widgetResized(const gcn::Event &event);
+ void keyReleased(gcn::KeyEvent &event);
/**
* Handles mouse click.
@@ -79,9 +83,20 @@ class ItemContainer : public gcn::Widget,
void mousePressed(gcn::MouseEvent &event);
/**
+ * Handles mouse dragged.
+ */
+ void mouseDragged(gcn::MouseEvent &event);
+
+ /**
+ * Handles mouse released.
+ */
+ void mouseReleased(gcn::MouseEvent &event);
+
+ /**
* Returns the selected item.
*/
- Item* getSelectedItem();
+ Item* getSelectedItem() const
+ { return mSelectedItem; }
/**
* Sets selected item to NULL.
@@ -94,7 +109,7 @@ class ItemContainer : public gcn::Widget,
*/
void addSelectionListener(gcn::SelectionListener *listener)
{
- mListeners.push_back(listener);
+ mSelectionListeners.push_back(listener);
}
/**
@@ -103,33 +118,50 @@ class ItemContainer : public gcn::Widget,
*/
void removeSelectionListener(gcn::SelectionListener *listener)
{
- mListeners.remove(listener);
+ mSelectionListeners.remove(listener);
}
+ enum {
+ MOVE_SELECTED_LEFT, // 0
+ MOVE_SELECTED_RIGHT, // 1
+ MOVE_SELECTED_UP, // 2
+ MOVE_SELECTED_DOWN // 3
+ };
private:
+ /**
+ * Execute all the functionality associated with the action key.
+ */
+ void keyAction();
+
void mouseExited(gcn::MouseEvent &event);
void mouseMoved(gcn::MouseEvent &event);
/**
+ * Moves the highlight in the direction specified.
+ *
+ * @param direction The move direction of the highlighter.
+ */
+ void moveHighlight(int direction);
- * Sets the currently selected item. Invalid (e.g., negative) indices set `no item'.
+ /**
+ * Sets the currently selected item.
*/
- void setSelectedItemIndex(int index);
+ void setSelectedItem(Item *item);
/**
* Find the current item index by the most recently used item ID
*/
- void refindSelectedItem(void);
+ void refindSelectedItem();
/**
* Determine and set the height of the container.
*/
- void recalculateHeight(void);
+ void recalculateHeight();
/**
* Sends out selection events to the list of selection listeners.
*/
- void distributeValueChangedEvent(void);
+ void distributeValueChangedEvent();
/**
* Gets the slot index based on the cursor position.
@@ -138,22 +170,24 @@ class ItemContainer : public gcn::Widget,
* @param posY The Y Coordinate position.
* @return The slot index on success, -1 on failure.
*/
- int getSlotIndex(const int posX, const int posY) const;
+ int getSlotIndex(int posX, int posY) const;
Inventory *mInventory;
- Image *mSelImg;
-
- int mSelectedItemIndex;
- int mLastSelectedItemId; // last selected item ID. If we lose the item, find again by ID.
- int mMaxItems;
+ int mGridColumns, mGridRows;
int mOffset;
+ Image *mSelImg;
+ Item *mSelectedItem, *mHighlightedItem;
+ int mSelectionStatus;
+ bool mSwapItems;
+ bool mDescItems;
+ int mDragPosX, mDragPosY;
ItemPopup *mItemPopup;
- std::list<gcn::SelectionListener*> mListeners;
+ typedef std::list<gcn::SelectionListener*> SelectionListenerList;
+ typedef SelectionListenerList::iterator SelectionListenerIterator;
- static const int gridWidth;
- static const int gridHeight;
+ SelectionListenerList mSelectionListeners;
};
#endif
diff --git a/src/gui/itemlinkhandler.cpp b/src/gui/itemlinkhandler.cpp
index e9993c2d..29fa310d 100644
--- a/src/gui/itemlinkhandler.cpp
+++ b/src/gui/itemlinkhandler.cpp
@@ -1,22 +1,21 @@
/*
- * Aethyra
- * Copyright 2009 The Mana World Development Team
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
- * The Mana World is free software; you can redistribute it and/or modify
+ * This program is free software; you can redistribute it and/or modify
* it under the 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,
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
diff --git a/src/gui/itemlinkhandler.h b/src/gui/itemlinkhandler.h
index e4c3ea4a..c04afa9e 100644
--- a/src/gui/itemlinkhandler.h
+++ b/src/gui/itemlinkhandler.h
@@ -1,27 +1,26 @@
/*
- * Aethyra
- * Copyright 2009 The Mana World Development Team
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
- * The Mana World is free software; you can redistribute it and/or modify
+ * This program is free software; you can redistribute it and/or modify
* it under the 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,
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef ITEM_LINK_HANDLER_H_
-#define ITEM_LINK_HANDLER_H_
+#ifndef ITEM_LINK_HANDLER_H
+#define ITEM_LINK_HANDLER_H
#include "linkhandler.h"
diff --git a/src/gui/itempopup.cpp b/src/gui/itempopup.cpp
index f2ac374a..66729605 100644
--- a/src/gui/itempopup.cpp
+++ b/src/gui/itempopup.cpp
@@ -1,10 +1,9 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Legend of Mazzeroth Development Team
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Legend of Mazzeroth.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,6 +32,8 @@
#include "../graphics.h"
+#include "../units.h"
+
#include "../resources/iteminfo.h"
#include "../utils/gettext.h"
@@ -41,15 +42,13 @@
ItemPopup::ItemPopup():
Popup("ItemPopup")
{
- mItemType = "";
-
// Item Name
- mItemName = new gcn::Label("");
+ mItemName = new gcn::Label;
mItemName->setFont(boldFont);
mItemName->setPosition(2, 2);
// Item Description
- mItemDesc = new TextBox();
+ mItemDesc = new TextBox;
mItemDesc->setEditable(false);
mItemDescScroll = new ScrollArea(mItemDesc);
@@ -60,7 +59,7 @@ ItemPopup::ItemPopup():
mItemDescScroll->setPosition(2, getFont()->getHeight());
// Item Effect
- mItemEffect = new TextBox();
+ mItemEffect = new TextBox;
mItemEffect->setEditable(false);
mItemEffectScroll = new ScrollArea(mItemEffect);
@@ -72,7 +71,7 @@ ItemPopup::ItemPopup():
(2 * getPadding()));
// Item Weight
- mItemWeight = new TextBox();
+ mItemWeight = new TextBox;
mItemWeight->setEditable(false);
mItemWeightScroll = new ScrollArea(mItemWeight);
@@ -111,9 +110,11 @@ void ItemPopup::setItem(const ItemInfo &item)
mItemName->setWidth(boldFont->getWidth(item.getName()));
mItemDesc->setTextWrapped(item.getDescription(), 196);
mItemEffect->setTextWrapped(item.getEffect(), 196);
- mItemWeight->setTextWrapped(_("Weight: ") + toString(item.getWeight()) +
- _(" grams"), 196);
+ mItemWeight->setTextWrapped(_("Weight: ") +
+ Units::formatWeight(item.getWeight()), 196);
+#ifdef EATHENA_SUPPORT
mItemType = item.getType();
+#endif
int minWidth = mItemName->getWidth();
@@ -161,11 +162,13 @@ void ItemPopup::setItem(const ItemInfo &item)
void ItemPopup::updateColors()
{
+#ifdef EATHENA_SUPPORT
mItemName->setForegroundColor(getColor(mItemType));
+#endif
graphics->setColor(guiPalette->getColor(Palette::TEXT));
}
-gcn::Color ItemPopup::getColor(const std::string& type)
+gcn::Color ItemPopup::getColor(const std::string &type)
{
gcn::Color color;
@@ -213,9 +216,9 @@ unsigned int ItemPopup::getNumRows()
void ItemPopup::view(int x, int y)
{
if (graphics->getWidth() < (x + getWidth() + 5))
- x = graphics->getWidth() - getWidth();
+ x = graphics->getWidth() - getWidth();
if ((y - getHeight() - 10) < 0)
- y = 0;
+ y = 0;
else
y = y - getHeight() - 10;
setPosition(x, y);
diff --git a/src/gui/itempopup.h b/src/gui/itempopup.h
index 29fd127a..0e386ef7 100644
--- a/src/gui/itempopup.h
+++ b/src/gui/itempopup.h
@@ -1,10 +1,9 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Legend of Mazzeroth Development Team
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Legend of Mazzeroth.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -78,7 +77,7 @@ class ItemPopup : public Popup
ScrollArea *mItemEffectScroll;
ScrollArea *mItemWeightScroll;
- gcn::Color getColor(const std::string& type);
+ static gcn::Color getColor(const std::string &type);
};
#endif // ITEMPOPUP_H
diff --git a/src/gui/itemshortcutcontainer.cpp b/src/gui/itemshortcutcontainer.cpp
index a0697c5d..d4de3477 100644
--- a/src/gui/itemshortcutcontainer.cpp
+++ b/src/gui/itemshortcutcontainer.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,24 +19,26 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "inventorywindow.h"
-#include "itemshortcutcontainer.h"
-#include "itempopup.h"
-#include "palette.h"
-#include "viewport.h"
+#include "gui/itemshortcutcontainer.h"
-#include "../configuration.h"
-#include "../graphics.h"
-#include "../inventory.h"
-#include "../item.h"
-#include "../itemshortcut.h"
-#include "../keyboardconfig.h"
-#include "../localplayer.h"
+#include "gui/inventorywindow.h"
+#include "gui/itempopup.h"
+#include "gui/palette.h"
+#include "gui/viewport.h"
-#include "../resources/image.h"
-#include "../resources/resourcemanager.h"
+#include "configuration.h"
+#include "graphics.h"
+#include "inventory.h"
+#include "item.h"
+#include "itemshortcut.h"
+#include "keyboardconfig.h"
+#include "localplayer.h"
-#include "../utils/stringutils.h"
+#include "resources/image.h"
+#include "resources/iteminfo.h"
+#include "resources/resourcemanager.h"
+
+#include "utils/stringutils.h"
ItemShortcutContainer::ItemShortcutContainer():
ShortcutContainer(),
@@ -47,7 +48,7 @@ ItemShortcutContainer::ItemShortcutContainer():
addMouseListener(this);
addWidgetListener(this);
- mItemPopup = new ItemPopup();
+ mItemPopup = new ItemPopup;
mItemPopup->setOpaque(false);
ResourceManager *resman = ResourceManager::getInstance();
@@ -109,7 +110,10 @@ void ItemShortcutContainer::draw(gcn::Graphics *graphics)
if (image)
{
const std::string label =
- item->isEquipped() ? "Eq." : toString(item->getQuantity());
+#ifdef EATHENA_SUPPORT
+ item->isEquipped() ? "Eq." :
+#endif
+ toString(item->getQuantity());
g->drawImage(image, itemX, itemY);
g->drawText(label, itemX + mBoxWidth / 2,
itemY + mBoxHeight - 14, gcn::Graphics::CENTER);
@@ -233,7 +237,7 @@ void ItemShortcutContainer::mouseMoved(gcn::MouseEvent &event)
Item *item = player_node->getInventory()->findItem(itemId);
- if (item)
+ if (item && inventoryWindow->isVisible())
{
if (item->getInfo().getName() != mItemPopup->getItemName())
mItemPopup->setItem(item->getInfo());
diff --git a/src/gui/itemshortcutcontainer.h b/src/gui/itemshortcutcontainer.h
index 0149754e..9d188bf0 100644
--- a/src/gui/itemshortcutcontainer.h
+++ b/src/gui/itemshortcutcontainer.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/itemshortcutwindow.cpp b/src/gui/itemshortcutwindow.cpp
new file mode 100644
index 00000000..6fe1a10b
--- /dev/null
+++ b/src/gui/itemshortcutwindow.cpp
@@ -0,0 +1,71 @@
+/*
+ * The Mana World
+ * Copyright (C) 2007 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "itemshortcutwindow.h"
+
+#include "itemshortcutcontainer.h"
+#include "scrollarea.h"
+
+static const int SCROLL_PADDING = 0;
+
+ItemShortcutWindow::ItemShortcutWindow()
+{
+ setWindowName("ItemShortcut");
+ // no title presented, title bar is padding so window can be moved.
+ gcn::Window::setTitleBarHeight(gcn::Window::getPadding());
+ setShowTitle(false);
+ setResizable(true);
+ setDefaultSize(758, 174, 42, 426);
+
+ mItems = new ItemShortcutContainer;
+
+ const int border = SCROLL_PADDING * 2 + getPadding() * 2;
+ setMinWidth(mItems->getBoxWidth() + border);
+ setMinHeight(mItems->getBoxHeight() + border);
+ setMaxWidth(mItems->getBoxWidth() * mItems->getMaxItems() + border);
+ setMaxHeight(mItems->getBoxHeight() * mItems->getMaxItems() + border);
+
+ mScrollArea = new ScrollArea(mItems);
+ mScrollArea->setPosition(SCROLL_PADDING, SCROLL_PADDING);
+ mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+ mScrollArea->setOpaque(false);
+
+ add(mScrollArea);
+
+ loadWindowState();
+}
+
+ItemShortcutWindow::~ItemShortcutWindow()
+{
+ delete mItems;
+ delete mScrollArea;
+}
+
+void ItemShortcutWindow::widgetResized(const gcn::Event &event)
+{
+ Window::widgetResized(event);
+
+ const gcn::Rectangle &area = getChildrenArea();
+
+ mScrollArea->setSize(
+ area.width - SCROLL_PADDING,
+ area.height - SCROLL_PADDING);
+}
diff --git a/src/gui/itemshortcutwindow.h b/src/gui/itemshortcutwindow.h
new file mode 100644
index 00000000..baa34b13
--- /dev/null
+++ b/src/gui/itemshortcutwindow.h
@@ -0,0 +1,61 @@
+/*
+ * The Mana World
+ * Copyright (C) 2007 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef ITEMSHORTCUTWINDOW_H
+#define ITEMSHORTCUTWINDOW_H
+
+#include "window.h"
+
+class ItemShortcutContainer;
+class ScrollArea;
+
+/**
+ * A window around the ItemShortcutContainer.
+ *
+ * \ingroup Interface
+ */
+class ItemShortcutWindow : public Window
+{
+ public:
+ /**
+ * Constructor.
+ */
+ ItemShortcutWindow();
+
+ /**
+ * Destructor.
+ */
+ ~ItemShortcutWindow();
+
+ /**
+ * Called whenever the widget changes size.
+ */
+ void widgetResized(const gcn::Event &event);
+
+ private:
+ ItemShortcutContainer *mItems;
+
+ ScrollArea *mScrollArea;
+};
+
+extern ItemShortcutWindow *itemShortcutWindow;
+
+#endif
diff --git a/src/gui/label.cpp b/src/gui/label.cpp
index f3e7bd04..d2fba12b 100644
--- a/src/gui/label.cpp
+++ b/src/gui/label.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (c) 2009 Aethyra Development Team
*
- * This file is part of Aethyra based on original code
- * from GUIChan.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
#include "label.h"
#include "palette.h"
@@ -27,12 +27,12 @@ Label::Label() :
{
}
-Label::Label(const std::string& caption) :
+Label::Label(const std::string &caption) :
gcn::Label(caption)
{
}
-void Label::draw(gcn::Graphics* graphics)
+void Label::draw(gcn::Graphics *graphics)
{
setForegroundColor(guiPalette->getColor(Palette::TEXT));
gcn::Label::draw(static_cast<gcn::Graphics*>(graphics));
diff --git a/src/gui/label.h b/src/gui/label.h
index 4a9bb805..dcda8e9d 100644
--- a/src/gui/label.h
+++ b/src/gui/label.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (c) 2009 Aethyra Development Team
*
- * This file is part of Aethyra based on original code
- * from GUIChan.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -43,12 +42,12 @@ class Label : public gcn::Label
* Constructor. This version of the constructor sets the label with an
* inintialization string.
*/
- Label(const std::string& caption);
+ Label(const std::string &caption);
/**
* Draws the label.
*/
- void draw(gcn::Graphics* graphics);
+ void draw(gcn::Graphics *graphics);
};
#endif
diff --git a/src/gui/linkhandler.h b/src/gui/linkhandler.h
index ea1b25c8..30267f87 100644
--- a/src/gui/linkhandler.h
+++ b/src/gui/linkhandler.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,6 +24,8 @@
#include <string>
+#include <string>
+
/**
* A simple interface to windows that need to handle links from BrowserBox
* widget.
@@ -34,7 +35,7 @@ class LinkHandler
public:
virtual ~LinkHandler() { }
- virtual void handleLink(const std::string& link) = 0;
+ virtual void handleLink(const std::string &link) = 0;
};
#endif
diff --git a/src/gui/listbox.cpp b/src/gui/listbox.cpp
index 71e92eaf..7ba84ee7 100644
--- a/src/gui/listbox.cpp
+++ b/src/gui/listbox.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/listbox.h b/src/gui/listbox.h
index 09f00cdf..cfb58f15 100644
--- a/src/gui/listbox.h
+++ b/src/gui/listbox.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/login.cpp b/src/gui/login.cpp
index 7b9829fb..281a25a2 100644
--- a/src/gui/login.cpp
+++ b/src/gui/login.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -50,70 +49,81 @@ LoginDialog::LoginDialog(LoginData *loginData):
{
gcn::Label *userLabel = new Label(_("Name:"));
gcn::Label *passLabel = new Label(_("Password:"));
+#ifdef EATHENA_SUPPORT
gcn::Label *serverLabel = new Label(_("Server:"));
gcn::Label *portLabel = new Label(_("Port:"));
gcn::Label *dropdownLabel = new Label(_("Recent:"));
std::vector<std::string> dfltServer;
- dfltServer.push_back("www.aethyra.org");
- dfltServer.push_back("www.aethyra.org");
- dfltServer.push_back("209.168.213.109");
+ dfltServer.push_back("server.themanaworld.org");
std::vector<std::string> dfltPort;
- dfltPort.push_back("21001");
- dfltPort.push_back("22001");
- dfltPort.push_back("21001");
+ dfltPort.push_back("6901");
mServerList = new DropDownList("MostRecent00", dfltServer, dfltPort,
MAX_SERVER_LIST_SIZE);
mServerListBox = new ListBox(mServerList);
- mServerScrollArea = new ScrollArea();
+ mServerScrollArea = new ScrollArea;
+#endif
mUserField = new TextField(mLoginData->username);
mPassField = new PasswordField(mLoginData->password);
+#ifdef EATHENA_SUPPORT
mServerField = new TextField(mServerList->getServerAt(0));
mPortField = new TextField(mServerList->getPortAt(0));
mServerDropDown = new DropDown(mServerList,
mServerScrollArea,
mServerListBox);
mServerDropDown->setOpaque(false);
+#endif
- mKeepCheck = new CheckBox(_("Keep"), mLoginData->remember);
+ mKeepCheck = new CheckBox(_("Remember Username"), mLoginData->remember);
mOkButton = new Button(_("OK"), "ok", this);
mCancelButton = new Button(_("Cancel"), "cancel", this);
mRegisterButton = new Button(_("Register"), "register", this);
mUserField->setActionEventId("ok");
mPassField->setActionEventId("ok");
+#ifdef EATHENA_SUPPORT
mServerField->setActionEventId("ok");
+ mPortField->setActionEventId("ok");
mServerDropDown->setActionEventId("changeSelection");
+#endif
mUserField->addKeyListener(this);
mPassField->addKeyListener(this);
+#ifdef EATHENA_SUPPORT
mServerField->addKeyListener(this);
mPortField->addKeyListener(this);
mServerDropDown->addKeyListener(this);
+#endif
mUserField->addActionListener(this);
mPassField->addActionListener(this);
+#ifdef EATHENA_SUPPORT
mServerField->addActionListener(this);
mPortField->addActionListener(this);
mServerDropDown->addActionListener(this);
mKeepCheck->addActionListener(this);
+#endif
place(0, 0, userLabel);
place(0, 1, passLabel);
+#ifdef EATHENA_SUPPORT
place(0, 2, serverLabel);
place(0, 3, portLabel);
place(0, 4, dropdownLabel);
+#endif
place(1, 0, mUserField, 3).setPadding(1);
place(1, 1, mPassField, 3).setPadding(1);
+#ifdef EATHENA_SUPPORT
place(1, 2, mServerField, 3).setPadding(1);
place(1, 3, mPortField, 3).setPadding(1);
place(1, 4, mServerDropDown, 3).setPadding(1);
+#endif
place(0, 5, mKeepCheck, 4);
place(0, 6, mRegisterButton).setHAlign(LayoutCell::LEFT);
place(2, 6, mCancelButton);
place(3, 6, mOkButton);
reflowLayout(250, 0);
- setLocationRelativeTo(getParent());
+ center();
setVisible(true);
if (mUserField->getText().empty())
@@ -128,8 +138,10 @@ void LoginDialog::action(const gcn::ActionEvent &event)
{
if (event.getId() == "ok" && canSubmit())
{
+#ifdef EATHENA_SUPPORT
mLoginData->hostname = mServerField->getText();
mLoginData->port = getUShort(mPortField->getText());
+#endif
mLoginData->username = mUserField->getText();
mLoginData->password = mPassField->getText();
mLoginData->remember = mKeepCheck->isSelected();
@@ -137,21 +149,32 @@ void LoginDialog::action(const gcn::ActionEvent &event)
mOkButton->setEnabled(false);
mRegisterButton->setEnabled(false);
+#ifdef EATHENA_SUPPORT
mServerList->save(mServerField->getText(), mPortField->getText());
- state = ACCOUNT_STATE;
+ state = STATE_ACCOUNT;
+#else
+ state = STATE_LOGIN_ATTEMPT;
+#endif
}
+#ifdef EATHENA_SUPPORT
else if (event.getId() == "changeSelection")
{
int selected = mServerListBox->getSelected();
mServerField->setText(mServerList->getServerAt(selected));
mPortField->setText(mServerList->getPortAt(selected));
}
+#endif
else if (event.getId() == "cancel")
{
- state = EXIT_STATE;
+#ifdef TMWSERV_SUPPORT
+ state = STATE_SWITCH_ACCOUNTSERVER;
+#else
+ state = STATE_EXIT;
+#endif
}
else if (event.getId() == "register")
{
+#ifdef EATHENA_SUPPORT
// Transfer these fields on to the register dialog
mLoginData->hostname = mServerField->getText();
@@ -159,11 +182,12 @@ void LoginDialog::action(const gcn::ActionEvent &event)
mLoginData->port = getUShort(mPortField->getText());
else
mLoginData->port = 6901;
+#endif
mLoginData->username = mUserField->getText();
mLoginData->password = mPassField->getText();
- state = REGISTER_STATE;
+ state = STATE_REGISTER;
}
}
@@ -176,11 +200,14 @@ bool LoginDialog::canSubmit()
{
return !mUserField->getText().empty() &&
!mPassField->getText().empty() &&
+#ifdef EATHENA_SUPPORT
!mServerField->getText().empty() &&
isUShort(mPortField->getText()) &&
- state == LOGIN_STATE;
+#endif
+ state == STATE_LOGIN;
}
+#ifdef EATHENA_SUPPORT
bool LoginDialog::isUShort(const std::string &str)
{
if (str.empty())
@@ -305,3 +332,4 @@ std::string LoginDialog::DropDownList::getPortAt(int i)
return mPorts.at(i);
}
+#endif
diff --git a/src/gui/login.h b/src/gui/login.h
index 4d63ec63..9a97cd4d 100644
--- a/src/gui/login.h
+++ b/src/gui/login.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,13 +27,17 @@
#include <guichan/actionlistener.hpp>
#include <guichan/keylistener.hpp>
+#ifdef EATHENA_SUPPORT
#include <guichan/listmodel.hpp>
+#endif
#include "window.h"
-class DropDown;
class LoginData;
+#ifdef EATHENA_SUPPORT
+class DropDown;
class ScrollArea;
+#endif
/**
* The login dialog.
@@ -69,6 +72,7 @@ class LoginDialog : public Window, public gcn::ActionListener,
*/
bool canSubmit();
+#ifdef EATHENA_SUPPORT
/**
* Function to decide whether string is an unsigned short or not
*
@@ -87,11 +91,14 @@ class LoginDialog : public Window, public gcn::ActionListener,
*/
static unsigned short getUShort(const std::string &str);
- DropDown *mServerDropDown;
+#endif
gcn::TextField *mUserField;
gcn::TextField *mPassField;
+#ifdef EATHENA_SUPPORT
gcn::TextField *mServerField;
gcn::TextField *mPortField;
+ DropDown *mServerDropDown;
+#endif
gcn::CheckBox *mKeepCheck;
gcn::Button *mOkButton;
gcn::Button *mCancelButton;
@@ -99,6 +106,7 @@ class LoginDialog : public Window, public gcn::ActionListener,
LoginData *mLoginData;
+#ifdef EATHENA_SUPPORT
/**
* Helper class to keep a list of all the recent entries for the
* dropdown
@@ -126,6 +134,7 @@ class LoginDialog : public Window, public gcn::ActionListener,
DropDownList *mServerList;
gcn::ListBox *mServerListBox;
gcn::ScrollArea *mServerScrollArea;
+#endif
};
#endif
diff --git a/src/gui/magic.cpp b/src/gui/magic.cpp
new file mode 100644
index 00000000..117c1f14
--- /dev/null
+++ b/src/gui/magic.cpp
@@ -0,0 +1,92 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <guichan/widgets/label.hpp>
+#include <guichan/widgets/container.hpp>
+
+#include "magic.h"
+
+#include "button.h"
+
+#include "../localplayer.h"
+
+#include "../utils/dtor.h"
+#include "../utils/gettext.h"
+
+MagicDialog::MagicDialog():
+ Window(_("Magic"))
+{
+ setWindowName("Magic");
+ setCloseButton(true);
+ setDefaultSize(255, 30, 175, 225);
+
+ gcn::Button *spellButton1 = new Button(_("Cast Test Spell 1"), "spell_1", this);
+ gcn::Button *spellButton2 = new Button(_("Cast Test Spell 2"), "spell_2", this);
+ gcn::Button *spellButton3 = new Button(_("Cast Test Spell 3"), "spell_3", this);
+
+ spellButton1->setPosition(10, 30);
+ spellButton2->setPosition(10, 60);
+ spellButton3->setPosition(10, 90);
+
+ add(spellButton1);
+ add(spellButton2);
+ add(spellButton3);
+
+ update();
+
+ setLocationRelativeTo(getParent());
+ loadWindowState();
+}
+
+MagicDialog::~MagicDialog()
+{
+}
+
+void MagicDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "spell_1")
+ {
+ player_node->useSpecial(1);
+ }
+ if (event.getId() == "spell_2")
+ {
+ player_node->useSpecial(2);
+ }
+ if (event.getId() == "spell_3")
+ {
+ player_node->useSpecial(3);
+ }
+ else if (event.getId() == "close")
+ {
+ setVisible(false);
+ }
+}
+
+void MagicDialog::draw(gcn::Graphics *g)
+{
+ update();
+
+ Window::draw(g);
+}
+
+void MagicDialog::update()
+{
+}
diff --git a/src/gui/magic.h b/src/gui/magic.h
new file mode 100644
index 00000000..74529396
--- /dev/null
+++ b/src/gui/magic.h
@@ -0,0 +1,75 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef MAGIC_H
+#define MAGIC_H
+
+#include <guichan/actionlistener.hpp>
+
+#include "window.h"
+#include "gccontainer.h"
+
+#include "../guichanfwd.h"
+
+
+/**
+ * The skill dialog.
+ *
+ * \ingroup Interface
+ */
+class MagicDialog : public Window, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ MagicDialog();
+
+ /**
+ * Destructor.
+ */
+ ~MagicDialog();
+
+ /**
+ * Called when receiving actions from widget.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Update the tabs in this dialog
+ */
+ void update();
+
+ /**
+ * Draw this window.
+ */
+ void draw(gcn::Graphics *g);
+
+ private:
+
+};
+
+
+
+
+extern MagicDialog *magicDialog;
+
+#endif
diff --git a/src/gui/menuwindow.cpp b/src/gui/menuwindow.cpp
index e1be908b..e6ae2d3b 100644
--- a/src/gui/menuwindow.cpp
+++ b/src/gui/menuwindow.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -40,6 +39,11 @@ extern Window *emoteWindow;
extern Window *setupWindow;
extern Window *skillDialog;
extern Window *statusWindow;
+#ifdef TMWSERV_SUPPORT
+extern Window *buddyWindow;
+extern Window *guildWindow;
+extern Window *magicDialog;
+#endif
namespace {
struct MenuWindowListener : public gcn::ActionListener
@@ -57,14 +61,19 @@ MenuWindow::MenuWindow():
// Buttons
static const char *buttonNames[] =
{
- _("Chat"),
- _("Status"),
- _("Equipment"),
- _("Inventory"),
- _("Skills"),
- _("Shortcut"),
- _("Emote"),
- _("Setup"),
+ N_("Chat"),
+ N_("Status"),
+ N_("Equipment"),
+ N_("Inventory"),
+ N_("Skills"),
+#ifdef TMWSERV_SUPPORT
+ N_("Magic"),
+ N_("Guilds"),
+ N_("Buddys"),
+#endif
+ N_("Shortcut"),
+ N_("Emote"),
+ N_("Setup"),
0
};
int x = 0, h = 0;
@@ -91,35 +100,49 @@ void MenuWindowListener::action(const gcn::ActionEvent &event)
{
Window *window = NULL;
- if (event.getId() == _("Chat"))
+ if (event.getId() == "Chat")
{
window = chatWindow;
}
- else if (event.getId() == _("Status"))
+ else if (event.getId() == "Status")
{
window = statusWindow;
}
- else if (event.getId() == _("Equipment"))
+ else if (event.getId() == "Equipment")
{
window = equipmentWindow;
}
- else if (event.getId() == _("Inventory"))
+ else if (event.getId() == "Inventory")
{
window = inventoryWindow;
}
- else if (event.getId() == _("Skills"))
+ else if (event.getId() == "Skills")
{
window = skillDialog;
}
- else if (event.getId() == _("Shortcut"))
+#ifdef TMWSERV_SUPPORT
+ else if (event.getId() == "Magic")
+ {
+ window = magicDialog;
+ }
+ else if (event.getId() == "Guilds")
+ {
+ window = guildWindow;
+ }
+ else if (event.getId() == "Buddys")
+ {
+ window = buddyWindow;
+ }
+#endif
+ else if (event.getId() == "Shortcut")
{
window = itemShortcutWindow;
}
- else if (event.getId() == _("Emote"))
+ else if (event.getId() == "Emote")
{
window = emoteWindow;
}
- else if (event.getId() == _("Setup"))
+ else if (event.getId() == "Setup")
{
window = setupWindow;
}
diff --git a/src/gui/menuwindow.h b/src/gui/menuwindow.h
index e8dc0b2e..c3d5673e 100644
--- a/src/gui/menuwindow.h
+++ b/src/gui/menuwindow.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp
index f3da52c6..93a55688 100644
--- a/src/gui/minimap.cpp
+++ b/src/gui/minimap.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004-2005 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,7 +40,7 @@ Minimap::Minimap():
mMapImage(NULL),
mProportion(0.5)
{
- setWindowName(_("MiniMap"));
+ setWindowName("MiniMap");
mShow = config.getValue(getWindowName() + "Show", true);
setDefaultSize(5, 25, 100, 100);
setResizable(true);
@@ -120,8 +119,14 @@ void Minimap::draw(gcn::Graphics *graphics)
if (mMapImage->getWidth() > a.width ||
mMapImage->getHeight() > a.height)
{
+#ifdef TMWSERV_SUPPORT
+ const Vector &p = player_node->getPosition();
+ mapOriginX = (int) (((a.width) / 2) - (int) (p.x * mProportion) / 32);
+ mapOriginY = (int) (((a.height) / 2) - (int) (p.y * mProportion) / 32);
+#else
mapOriginX = (int) (((a.width) / 2) - (player_node->mX * mProportion));
mapOriginY = (int) (((a.height) / 2) - (player_node->mY * mProportion));
+#endif
const int minOriginX = a.width - mMapImage->getWidth();
const int minOriginY = a.height - mMapImage->getHeight();
@@ -172,10 +177,11 @@ void Minimap::draw(gcn::Graphics *graphics)
}
const int offset = (int) ((dotSize - 1) * mProportion);
+ const Vector &pos = being->getPosition();
graphics->fillRectangle(gcn::Rectangle(
- (int) (being->mX * mProportion) + mapOriginX - offset,
- (int) (being->mY * mProportion) + mapOriginY - offset,
+ (int) (pos.x * mProportion) / 32 + mapOriginX - offset,
+ (int) (pos.x * mProportion) / 32 + mapOriginY - offset,
dotSize, dotSize));
}
diff --git a/src/gui/minimap.h b/src/gui/minimap.h
index 6e88f821..3ce0aacd 100644
--- a/src/gui/minimap.h
+++ b/src/gui/minimap.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004-2005 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/ministatus.cpp b/src/gui/ministatus.cpp
index 18b9d714..95577e69 100644
--- a/src/gui/ministatus.cpp
+++ b/src/gui/ministatus.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,7 +22,9 @@
#include "gui.h"
#include "ministatus.h"
#include "progressbar.h"
+#include "status.h"
+#include "../animatedsprite.h"
#include "../configuration.h"
#include "../graphics.h"
#include "../localplayer.h"
@@ -34,47 +35,56 @@ MiniStatusWindow::MiniStatusWindow():
Popup("MiniStatus")
{
mHpBar = new ProgressBar(1.0f, 100, 20, 0, 171, 34);
+#ifdef EATHENA_SUPPORT
mMpBar = new ProgressBar(1.0f, 100, 20, 26, 102, 230);
mXpBar = new ProgressBar(1.0f, 100, 20, 143, 192, 211);
+#endif
mHpBar->setPosition(0, 3);
+#ifdef EATHENA_SUPPORT
mMpBar->setPosition(mHpBar->getWidth() + 3, 3);
mXpBar->setPosition(mMpBar->getX() + mMpBar->getWidth() + 3, 3);
+#endif
add(mHpBar);
+#ifdef EATHENA_SUPPORT
add(mMpBar);
add(mXpBar);
+#endif
+#ifdef EATHENA_SUPPORT
setContentSize(mXpBar->getX() + mXpBar->getWidth(),
mXpBar->getY() + mXpBar->getHeight());
+#else
+ setContentSize(mHpBar->getX() + mHpBar->getWidth(),
+ mHpBar->getY() + mHpBar->getHeight());
+#endif
}
-void MiniStatusWindow::update()
+void MiniStatusWindow::setIcon(int index, AnimatedSprite *sprite)
{
- // HP Bar coloration
- if (player_node->mHp < int(player_node->mMaxHp / 3))
- mHpBar->setColor(223, 32, 32); // Red
- else if (player_node->mHp < int((player_node->mMaxHp / 3) * 2))
- mHpBar->setColor(230, 171, 34); // Orange
- else
- mHpBar->setColor(0, 171, 34); // Green
+ if (index >= (int) mIcons.size())
+ mIcons.resize(index + 1, NULL);
- float xp = (float) player_node->getXp() / player_node->mXpForNextLevel;
+ if (mIcons[index])
+ delete mIcons[index];
- if (xp != xp) xp = 0.0f; // check for NaN
- if (xp < 0.0f) xp = 0.0f; // make sure the experience isn't negative (uninitialized pointer most likely)
- if (xp > 1.0f) xp = 1.0f;
+ mIcons[index] = sprite;
+}
- mHpBar->setProgress((float) player_node->mHp / player_node->mMaxHp);
- mMpBar->setProgress((float) player_node->mMp / player_node->mMaxMp);
- mXpBar->setProgress(xp);
+void MiniStatusWindow::eraseIcon(int index)
+{
+ mIcons.erase(mIcons.begin() + index);
+}
- // Update labels
- mHpBar->setText(toString(player_node->mHp));
- mMpBar->setText(toString(player_node->mMp));
+extern volatile int tick_time;
- std::stringstream updatedText;
- updatedText << (float) ((int) (xp * 10000.0f)) / 100.0f << "%";
+void MiniStatusWindow::update()
+{
+ StatusWindow::updateHPBar(mHpBar);
+#ifdef EATHENA_SUPPORT
+ StatusWindow::updateMPBar(mMpBar);
+ StatusWindow::updateXPBar(mXpBar);
// Displays the number of monsters to next lvl
// (disabled for now but interesting idea)
@@ -88,8 +98,11 @@ void MiniStatusWindow::update()
<< config.getValue("xpBarMonsterCounterName", "Monsters") <<" left...";
}
*/
+#endif
- mXpBar->setText(updatedText.str());
+ for (unsigned int i = 0; i < mIcons.size(); i++)
+ if (mIcons[i])
+ mIcons[i]->update(tick_time * 10);
}
void MiniStatusWindow::draw(gcn::Graphics *graphics)
@@ -97,3 +110,19 @@ void MiniStatusWindow::draw(gcn::Graphics *graphics)
update();
drawChildren(graphics);
}
+
+void MiniStatusWindow::drawIcons(Graphics *graphics)
+{
+ // Draw icons
+#ifdef TMWSERV_SUPPORT
+ int icon_x = mHpBar->getX() + mHpBar->getWidth() + 4;
+#else
+ int icon_x = mXpBar->getX() + mXpBar->getWidth() + 4;
+#endif
+ for (unsigned int i = 0; i < mIcons.size(); i++) {
+ if (mIcons[i]) {
+ mIcons[i]->draw(graphics, icon_x, 3);
+ icon_x += 2 + mIcons[i]->getWidth();
+ }
+ }
+}
diff --git a/src/gui/ministatus.h b/src/gui/ministatus.h
index b3fc58fc..fd5a4e53 100644
--- a/src/gui/ministatus.h
+++ b/src/gui/ministatus.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,6 +24,10 @@
#include "popup.h"
+#include <vector>
+
+class AnimatedSprite;
+class Graphics;
class ProgressBar;
/**
@@ -45,6 +48,15 @@ class MiniStatusWindow : public Popup
*/
void draw(gcn::Graphics *graphics);
+ /**
+ * Sets one of the icons.
+ */
+ void setIcon(int index, AnimatedSprite *sprite);
+
+ void eraseIcon(int index);
+
+ void drawIcons(Graphics *graphics);
+
private:
/**
* Updates this dialog with values from player_node.
@@ -55,8 +67,12 @@ class MiniStatusWindow : public Popup
* Mini Status Bars
*/
ProgressBar *mHpBar;
+#ifdef EATHENA_SUPPORT
ProgressBar *mMpBar;
ProgressBar *mXpBar;
+#endif
+
+ std::vector<AnimatedSprite *> mIcons;
};
#endif
diff --git a/src/gui/npc_text.cpp b/src/gui/npc_text.cpp
index f524f8ea..5158e966 100644
--- a/src/gui/npc_text.cpp
+++ b/src/gui/npc_text.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,14 +29,26 @@
#include "../npc.h"
#include "../net/messageout.h"
-#include "../net/protocol.h"
+#ifdef TMWSERV_SUPPORT
+#include "../net/tmwserv/gameserver/player.h"
+#else
+#include "../net/ea/protocol.h"
+#endif
#include "../utils/gettext.h"
-NpcTextDialog::NpcTextDialog(Network *network):
- Window("NPC"), mNetwork(network)
+#ifdef TMWSERV_SUPPORT
+NpcTextDialog::NpcTextDialog()
+#else
+NpcTextDialog::NpcTextDialog(Network *network)
+#endif
+ : Window(_("NPC"))
+#ifdef EATHENA_SUPPORT
+ , mNetwork(network)
+#endif
+ , mState(NPC_TEXT_STATE_WAITING)
{
- setWindowName(_("NPC"));
+ setWindowName("NPCText");
setResizable(true);
setMinWidth(200);
@@ -50,8 +61,7 @@ NpcTextDialog::NpcTextDialog(Network *network):
mTextBox->setOpaque(false);
mScrollArea = new ScrollArea(mTextBox);
- mButton = new Button(_("OK"), "", this);
- mButton->setActionEventId("ok");
+ mButton = new Button(_("Waiting for server"), "ok", this);
mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
mScrollArea->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS);
@@ -62,9 +72,16 @@ NpcTextDialog::NpcTextDialog(Network *network):
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
+ center();
loadWindowState();
}
+void NpcTextDialog::clearText()
+{
+ NPC::isTalking = false;
+ setText("");
+}
+
void NpcTextDialog::setText(const std::string &text)
{
mText = text;
@@ -74,41 +91,64 @@ void NpcTextDialog::setText(const std::string &text)
void NpcTextDialog::addText(const std::string &text)
{
setText(mText + text + "\n");
+ mScrollArea->setVerticalScrollAmount(mScrollArea->getVerticalMaxScroll());
}
-void NpcTextDialog::clearText()
+void NpcTextDialog::showNextButton()
{
- NPC::mTalking = false;
- setText("");
+ mButton->setCaption(_("Next"));
+ mState = NPC_TEXT_STATE_NEXT;
+ mButton->setEnabled(true);
+}
+
+void NpcTextDialog::showCloseButton()
+{
+ mButton->setCaption(_("Close"));
+ mState = NPC_TEXT_STATE_CLOSE;
+ mButton->setEnabled(true);
}
void NpcTextDialog::action(const gcn::ActionEvent &event)
{
if (event.getId() == "ok")
{
- clearText();
- setVisible(false);
- saveWindowState();
-
- if (current_npc)
+ if (mState == NPC_TEXT_STATE_NEXT && current_npc) {
nextDialog();
-
- current_npc = 0;
+ addText("\n> Next\n");
+ } else if (mState == NPC_TEXT_STATE_CLOSE ||
+ (mState == NPC_TEXT_STATE_NEXT && !current_npc)) {
+ setText("");
+ if (current_npc) nextDialog();
+ setVisible(false);
+ current_npc = 0;
+ NPC::isTalking = false;
+ } else return;
}
+ else return;
+
+ mButton->setEnabled(false);
+ mButton->setCaption(_("Waiting for server"));
+ mState = NPC_TEXT_STATE_WAITING;
}
void NpcTextDialog::nextDialog(int npcID)
{
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::talkToNPC(npcID, false);
+#else
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_NPC_NEXT_REQUEST);
outMsg.writeInt32(npcID);
+#endif
}
void NpcTextDialog::closeDialog(int npcID)
{
+#ifdef EATHENA_SUPPORT
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_NPC_CLOSE);
outMsg.writeInt32(npcID);
+#endif
}
void NpcTextDialog::widgetResized(const gcn::Event &event)
@@ -123,4 +163,3 @@ void NpcTextDialog::requestFocus()
loadWindowState();
setVisible(true);
}
-
diff --git a/src/gui/npc_text.h b/src/gui/npc_text.h
index f01e3602..4c0c31e3 100644
--- a/src/gui/npc_text.h
+++ b/src/gui/npc_text.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,7 +30,9 @@
#include "../npc.h"
+#ifdef EATHENA_SUPPORT
class Network;
+#endif
class TextBox;
/**
@@ -47,7 +48,11 @@ class NpcTextDialog : public Window, public gcn::ActionListener
*
* @see Window::Window
*/
+#ifdef TMWSERV_SUPPORT
+ NpcTextDialog();
+#else
NpcTextDialog(Network *network);
+#endif
/**
* Called when receiving actions from the widgets.
@@ -74,6 +79,10 @@ class NpcTextDialog : public Window, public gcn::ActionListener
*/
void addText(const std::string &string);
+ void showNextButton();
+
+ void showCloseButton();
+
/**
* Notifies the server that the client has performed a next action.
*/
@@ -99,12 +108,21 @@ class NpcTextDialog : public Window, public gcn::ActionListener
void widgetResized(const gcn::Event &event);
private:
+#ifdef EATHENA_SUPPORT
Network *mNetwork;
+#endif
gcn::ScrollArea *mScrollArea;
TextBox *mTextBox;
gcn::Button *mButton;
std::string mText;
+
+ enum NPCTextState {
+ NPC_TEXT_STATE_WAITING,
+ NPC_TEXT_STATE_NEXT,
+ NPC_TEXT_STATE_CLOSE
+ };
+ NPCTextState mState;
};
extern NpcTextDialog *npcTextDialog;
diff --git a/src/gui/npcintegerdialog.cpp b/src/gui/npcintegerdialog.cpp
index 27721f0c..a7ae2748 100644
--- a/src/gui/npcintegerdialog.cpp
+++ b/src/gui/npcintegerdialog.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,6 +21,7 @@
#include "button.h"
#include "inttextfield.h"
+#include "npc_text.h"
#include "npcintegerdialog.h"
#include "widgets/layout.h"
@@ -29,23 +29,33 @@
#include "../npc.h"
#include "../net/messageout.h"
-#include "../net/protocol.h"
+#ifdef EATHENA_SUPPORT
+#include "../net/ea/protocol.h"
+#endif
#include "../utils/gettext.h"
-
-NpcIntegerDialog::NpcIntegerDialog(Network *network):
- Window(_("NPC Number Request")), mNetwork(network)
+#include "../utils/strprintf.h"
+
+#ifdef TMWSERV_SUPPORT
+NpcIntegerDialog::NpcIntegerDialog()
+#else
+NpcIntegerDialog::NpcIntegerDialog(Network *network)
+#endif
+ : Window(_("NPC Number Request"))
+#ifdef EATHENA_SUPPORT
+ , mNetwork(network)
+#endif
{
- mValueField = new IntTextField();
- setWindowName("NPCInput");
+ setWindowName("NPCInteger");
+ mValueField = new IntTextField;
setDefaultSize(175, 75, ImageRect::CENTER);
mDecButton = new Button("-", "decvalue", this);
mIncButton = new Button("+", "incvalue", this);
- okButton = new Button(_("OK"), "ok", this);
- cancelButton = new Button(_("Cancel"), "cancel", this);
- resetButton = new Button(_("Reset"), "reset", this);
+ gcn::Button *okButton = new Button(_("OK"), "ok", this);
+ gcn::Button *cancelButton = new Button(_("Cancel"), "cancel", this);
+ gcn::Button *resetButton = new Button(_("Reset"), "reset", this);
mDecButton->adjustSize();
mDecButton->setWidth(mIncButton->getWidth());
@@ -61,12 +71,14 @@ NpcIntegerDialog::NpcIntegerDialog(Network *network):
place(0, 0, resetButton);
place(2, 0, cancelButton);
place(3, 0, okButton);
- //reflowLayout(175, 0);
+ reflowLayout(175, 0);
+ center();
+ setDefaultSize();
loadWindowState();
}
-void NpcIntegerDialog::setRange(const int min, const int max)
+void NpcIntegerDialog::setRange(int min, int max)
{
mValueField->setRange(min, max);
}
@@ -88,11 +100,13 @@ void NpcIntegerDialog::action(const gcn::ActionEvent &event)
if (event.getId() == "ok")
{
finish = true;
+ npcTextDialog->addText(strprintf("\n> %d\n", mValueField->getValue()));
}
else if (event.getId() == "cancel")
{
finish = true;
mValueField->reset();
+ npcTextDialog->addText(_("\n> Cancel\n"));
}
else if (event.getId() == "decvalue")
{
@@ -110,18 +124,24 @@ void NpcIntegerDialog::action(const gcn::ActionEvent &event)
if (finish)
{
setVisible(false);
- NPC::mTalking = false;
+ NPC::isTalking = false;
+#ifdef EATHENA_SUPPORT
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_NPC_INT_RESPONSE);
outMsg.writeInt32(current_npc);
outMsg.writeInt32(mValueField->getValue());
+#endif
- current_npc = 0;
mValueField->reset();
}
}
+void NpcIntegerDialog::setDefaultValue(int value)
+{
+ mValueField->setDefaultValue(value);
+}
+
bool NpcIntegerDialog::isInputFocused()
{
return mValueField->isFocused();
@@ -131,3 +151,13 @@ void NpcIntegerDialog::requestFocus()
{
mValueField->requestFocus();
}
+
+void NpcIntegerDialog::setVisible(bool visible)
+{
+ if (visible) {
+ npcTextDialog->setVisible(true);
+ requestFocus();
+ }
+
+ Window::setVisible(visible);
+}
diff --git a/src/gui/npcintegerdialog.h b/src/gui/npcintegerdialog.h
index 15bdee48..df74c904 100644
--- a/src/gui/npcintegerdialog.h
+++ b/src/gui/npcintegerdialog.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,7 +26,9 @@
#include "window.h"
+#ifdef EATHENA_SUPPORT
class Network;
+#endif
class IntTextField;
/**
@@ -43,7 +44,11 @@ class NpcIntegerDialog : public Window, public gcn::ActionListener
*
* @see Window::Window
*/
+#ifdef TMWSERV_SUPPORT
+ NpcIntegerDialog();
+#else
NpcIntegerDialog(Network *network);
+#endif
/**
* Called when receiving actions from the widgets.
@@ -66,7 +71,14 @@ class NpcIntegerDialog : public Window, public gcn::ActionListener
* @param min The minimum value to allow
* @param max The maximum value to allow
*/
- void setRange(const int min, const int max);
+ void setRange(int min, int max);
+
+ /**
+ * Sets the default value.
+ *
+ * @param value The new default value
+ */
+ void setDefaultValue(int value);
/**
* Checks whether NpcStringDialog is Focused or not.
@@ -78,14 +90,15 @@ class NpcIntegerDialog : public Window, public gcn::ActionListener
*/
void requestFocus();
+ void setVisible(bool visible);
+
private:
+#ifdef EATHENA_SUPPORT
Network *mNetwork;
+#endif
gcn::Button *mDecButton;
gcn::Button *mIncButton;
IntTextField *mValueField;
- gcn::Button *okButton;
- gcn::Button *cancelButton;
- gcn::Button *resetButton;
};
extern NpcIntegerDialog *npcIntegerDialog;
diff --git a/src/gui/npclistdialog.cpp b/src/gui/npclistdialog.cpp
index 505912ac..968e2514 100644
--- a/src/gui/npclistdialog.cpp
+++ b/src/gui/npclistdialog.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,6 +23,7 @@
#include "button.h"
#include "listbox.h"
+#include "npc_text.h"
#include "npclistdialog.h"
#include "scrollarea.h"
@@ -32,14 +32,26 @@
#include "../npc.h"
#include "../net/messageout.h"
-#include "../net/protocol.h"
+#ifdef TMWSERV_SUPPORT
+#include "../net/tmwserv/gameserver/player.h"
+#else
+#include "../net/ea/protocol.h"
+#endif
#include "../utils/gettext.h"
-
-NpcListDialog::NpcListDialog(Network *network):
- Window("NPC"), mNetwork(network)
+#include "../utils/strprintf.h"
+
+#ifdef TMWSERV_SUPPORT
+NpcListDialog::NpcListDialog()
+#else
+NpcListDialog::NpcListDialog(Network *network)
+#endif
+ : Window("NPC")
+#ifdef EATHENA_SUPPORT
+ , mNetwork(network)
+#endif
{
- setWindowName(_("NPC"));
+ setWindowName("NPCList");
setResizable(true);
setMinWidth(200);
@@ -50,10 +62,10 @@ NpcListDialog::NpcListDialog(Network *network):
mItemList = new ListBox(this);
mItemList->setWrappingEnabled(true);
- scrollArea = new ScrollArea(mItemList);
+ gcn::ScrollArea *scrollArea = new ScrollArea(mItemList);
- okButton = new Button(_("OK"), "ok", this);
- cancelButton = new Button(_("Cancel"), "cancel", this);
+ gcn::Button *okButton = new Button(_("OK"), "ok", this);
+ gcn::Button *cancelButton = new Button(_("Cancel"), "cancel", this);
setContentSize(260, 175);
scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
@@ -65,6 +77,7 @@ NpcListDialog::NpcListDialog(Network *network):
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
+ center();
loadWindowState();
}
@@ -78,6 +91,11 @@ std::string NpcListDialog::getElementAt(int i)
return mItems[i];
}
+void NpcListDialog::addItem(const std::string &item)
+{
+ mItems.push_back(item);
+}
+
void NpcListDialog::parseItems(const std::string &itemString)
{
std::istringstream iss(itemString);
@@ -89,7 +107,7 @@ void NpcListDialog::parseItems(const std::string &itemString)
void NpcListDialog::reset()
{
- NPC::mTalking = false;
+ NPC::isTalking = false;
mItemList->setSelected(-1);
mItems.clear();
}
@@ -97,18 +115,23 @@ void NpcListDialog::reset()
void NpcListDialog::action(const gcn::ActionEvent &event)
{
int choice = 0;
-
if (event.getId() == "ok")
{
// Send the selected index back to the server
int selectedIndex = mItemList->getSelected();
if (selectedIndex > -1)
+ {
choice = selectedIndex + 1;
+ npcTextDialog->addText(strprintf("\n> \"%s\"\n",
+ mItems[selectedIndex].c_str()));
+ }
}
else if (event.getId() == "cancel")
{
choice = 0xff; // 0xff means cancel
+ npcTextDialog->addText(_("\n> Cancel\n"));
+ npcTextDialog->showCloseButton();
}
if (choice)
@@ -117,13 +140,25 @@ void NpcListDialog::action(const gcn::ActionEvent &event)
saveWindowState();
reset();
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::selectFromNPC(current_npc, choice);
+#else
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_NPC_LIST_CHOICE);
outMsg.writeInt32(current_npc);
outMsg.writeInt8(choice);
+#endif
+ }
+}
- current_npc = 0;
+void NpcListDialog::setVisible(bool visible)
+{
+ if (visible) {
+ npcTextDialog->setVisible(true);
+ requestFocus();
}
+
+ Window::setVisible(visible);
}
void NpcListDialog::requestFocus()
diff --git a/src/gui/npclistdialog.h b/src/gui/npclistdialog.h
index e3cf375b..6c1e02e3 100644
--- a/src/gui/npclistdialog.h
+++ b/src/gui/npclistdialog.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,14 +22,16 @@
#ifndef GUI_NPCLISTDIALOG_H
#define GUI_NPCLISTDIALOG_H
-#include <vector>
+#include "window.h"
#include <guichan/actionlistener.hpp>
#include <guichan/listmodel.hpp>
-#include "window.h"
+#include <vector>
+#ifdef EATHENA_SUPPORT
class Network;
+#endif
/**
* The npc list dialog.
@@ -46,7 +47,11 @@ class NpcListDialog : public Window, public gcn::ActionListener,
*
* @see Window::Window
*/
+#ifdef TMWSERV_SUPPORT
+ NpcListDialog();
+#else
NpcListDialog(Network *network);
+#endif
/**
* Called when receiving actions from the widgets.
@@ -64,6 +69,11 @@ class NpcListDialog : public Window, public gcn::ActionListener,
std::string getElementAt(int i);
/**
+ * Adds an item to the option list.
+ */
+ void addItem(const std::string &);
+
+ /**
* Fills the options list for an NPC dialog.
*
* @param itemString A string with the options separated with colons.
@@ -75,6 +85,8 @@ class NpcListDialog : public Window, public gcn::ActionListener,
*/
void reset();
+ void setVisible(bool visible);
+
/**
* Requests the listbox to take focus for input and sets window width
* to the last known setting.
@@ -82,11 +94,10 @@ class NpcListDialog : public Window, public gcn::ActionListener,
void requestFocus();
private:
+#ifdef EATHENA_SUPPORT
Network *mNetwork;
+#endif
gcn::ListBox *mItemList;
- gcn::ScrollArea *scrollArea;
- gcn::Button *okButton;
- gcn::Button *cancelButton;
std::vector<std::string> mItems;
};
diff --git a/src/gui/npcpostdialog.cpp b/src/gui/npcpostdialog.cpp
new file mode 100644
index 00000000..278bc397
--- /dev/null
+++ b/src/gui/npcpostdialog.cpp
@@ -0,0 +1,101 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "npcpostdialog.h"
+#include "textbox.h"
+#include "textfield.h"
+#include "button.h"
+#include "scrollarea.h"
+#include "chat.h"
+
+#include "../net/tmwserv/gameserver/player.h"
+#include "../utils/gettext.h"
+
+#include <guichan/widgets/label.hpp>
+
+NpcPostDialog::NpcPostDialog():
+ Window(_("NPC"))
+{
+ setContentSize(400, 180);
+
+ // create text field for receiver
+ gcn::Label *senderText = new gcn::Label("To:");
+ senderText->setPosition(5, 5);
+ mSender = new TextField();
+ mSender->setPosition(senderText->getWidth() + 5, 5);
+ mSender->setWidth(65);
+
+ // create button for sending
+ Button *sendButton = new Button(_("Send"), "send", this);
+ sendButton->setPosition(400-sendButton->getWidth(),
+ 170-sendButton->getHeight());
+ Button *cancelButton = new Button(_("Cancel"), "cancel", this);
+ cancelButton->setPosition(sendButton->getX() - (cancelButton->getWidth() + 2),
+ sendButton->getY());
+
+ // create textfield for letter
+ mText = new TextBox();
+ mText->setHeight(400 - (mSender->getHeight() + sendButton->getHeight()));
+ mText->setEditable(true);
+
+ // create scroll box for letter text
+ ScrollArea *scrollArea = new ScrollArea(mText);
+ scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+ scrollArea->setDimension(gcn::Rectangle(
+ 5, mSender->getHeight() + 5,
+ 380, 140 - (mSender->getHeight() + sendButton->getHeight())));
+
+ add(senderText);
+ add(mSender);
+ add(scrollArea);
+ add(sendButton);
+ add(cancelButton);
+
+ setLocationRelativeTo(getParent());
+}
+
+void NpcPostDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "send")
+ {
+ if (mSender->getText().empty() || mText->getText().empty())
+ {
+ localChatTab->chatLog("Failed to send as sender or letter invalid");
+ }
+ else
+ {
+ Net::GameServer::Player::sendLetter(mSender->getText(), mText->getText());
+ }
+ setVisible(false);
+ clear();
+ }
+ else if (event.getId() == "cancel")
+ {
+ setVisible(false);
+ clear();
+ }
+}
+
+void NpcPostDialog::clear()
+{
+ mSender->setText("");
+ mText->setText("");
+}
diff --git a/src/gui/npcpostdialog.h b/src/gui/npcpostdialog.h
new file mode 100644
index 00000000..b970f5cf
--- /dev/null
+++ b/src/gui/npcpostdialog.h
@@ -0,0 +1,57 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef GUI_NPCPOSTDIALOG_H
+#define GUI_NPCPOSTDIALOG_H
+
+#include <guichan/actionlistener.hpp>
+
+#include "window.h"
+
+class TextBox;
+class TextField;
+
+class NpcPostDialog : public Window, public gcn::ActionListener
+{
+public:
+ /**
+ * Constructor
+ */
+ NpcPostDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Clear the contents of the dialog
+ */
+ void clear();
+
+private:
+ TextBox *mText;
+ TextField *mSender;
+};
+
+extern NpcPostDialog *npcPostDialog;
+
+#endif
diff --git a/src/gui/npcstringdialog.cpp b/src/gui/npcstringdialog.cpp
index 43d0722f..c84de015 100644
--- a/src/gui/npcstringdialog.cpp
+++ b/src/gui/npcstringdialog.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,6 +20,7 @@
*/
#include "button.h"
+#include "npc_text.h"
#include "npcstringdialog.h"
#include "textfield.h"
@@ -29,25 +29,38 @@
#include "../npc.h"
#include "../net/messageout.h"
-#include "../net/protocol.h"
+#ifdef EATHENA_SUPPORT
+#include "../net/ea/protocol.h"
+#endif
#include "../utils/gettext.h"
-
-NpcStringDialog::NpcStringDialog(Network *network):
- Window(_("NPC Text Request")), mNetwork(network)
+#include "../utils/strprintf.h"
+
+#ifdef TMWSERV_SUPPORT
+NpcStringDialog::NpcStringDialog()
+#else
+NpcStringDialog::NpcStringDialog(Network *network)
+#endif
+ : Window(_("NPC Text Request"))
+#ifdef EATHENA_SUPPORT
+ , mNetwork(network)
+#endif
{
- setWindowName("NPCInput");
+ setWindowName("NPCString");
mValueField = new TextField("");
setDefaultSize(175, 75, ImageRect::CENTER);
- okButton = new Button(_("OK"), "ok", this);
- cancelButton = new Button(_("Cancel"), "cancel", this);
+ gcn::Button *okButton = new Button(_("OK"), "ok", this);
+ gcn::Button *cancelButton = new Button(_("Cancel"), "cancel", this);
place(0, 0, mValueField, 3);
place(1, 1, cancelButton);
place(2, 1, okButton);
+ reflowLayout(175, 0);
+ center();
+ setDefaultSize();
loadWindowState();
}
@@ -59,27 +72,36 @@ std::string NpcStringDialog::getValue()
void NpcStringDialog::setValue(const std::string &value)
{
mValueField->setText(value);
+ mDefault = value;
}
void NpcStringDialog::action(const gcn::ActionEvent &event)
{
if (event.getId() == "cancel")
- mValueField->setText("");
+ {
+ mValueField->setText(mDefault);
+ npcTextDialog->addText(_("\n> Cancel\n"));
+ }
+ else
+ {
+ npcTextDialog->addText(strprintf("\n> \"%s\"\n",
+ mValueField->getText().c_str()));
+ }
setVisible(false);
- NPC::mTalking = false;
+ NPC::isTalking = false;
std::string text = mValueField->getText();
mValueField->setText("");
+#ifdef EATHENA_SUPPORT
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_NPC_STR_RESPONSE);
outMsg.writeInt16(text.length() + 9);
outMsg.writeInt32(current_npc);
outMsg.writeString(text, text.length());
outMsg.writeInt8(0);
-
- current_npc = 0;
+#endif
}
bool NpcStringDialog::isInputFocused()
@@ -91,3 +113,13 @@ void NpcStringDialog::requestFocus()
{
mValueField->requestFocus();
}
+
+void NpcStringDialog::setVisible(bool visible)
+{
+ if (visible) {
+ npcTextDialog->setVisible(true);
+ requestFocus();
+ }
+
+ Window::setVisible(visible);
+}
diff --git a/src/gui/npcstringdialog.h b/src/gui/npcstringdialog.h
index ee620daf..94cd59b2 100644
--- a/src/gui/npcstringdialog.h
+++ b/src/gui/npcstringdialog.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,11 +22,13 @@
#ifndef GUI_NPCSTRINGDIALOG_H
#define GUI_NPCSTRINGDIALOG_H
-#include <guichan/actionlistener.hpp>
-
#include "window.h"
+#include <guichan/actionlistener.hpp>
+
+#ifdef EATHENA_SUPPORT
class Network;
+#endif
/**
* The npc integer input dialog.
@@ -42,7 +43,11 @@ class NpcStringDialog : public Window, public gcn::ActionListener
*
* @see Window::Window
*/
+#ifdef TMWSERV_SUPPORT
+ NpcStringDialog();
+#else
NpcStringDialog(Network *network);
+#endif
/**
* Called when receiving actions from the widgets.
@@ -71,11 +76,14 @@ class NpcStringDialog : public Window, public gcn::ActionListener
*/
void requestFocus();
+ void setVisible(bool visible);
+
private:
+#ifdef EATHENA_SUPPORT
Network *mNetwork;
+#endif
gcn::TextField *mValueField;
- gcn::Button *okButton;
- gcn::Button *cancelButton;
+ std::string mDefault;
};
extern NpcStringDialog *npcStringDialog;
diff --git a/src/gui/ok_dialog.cpp b/src/gui/ok_dialog.cpp
index 84fa20ea..24ffa80c 100644
--- a/src/gui/ok_dialog.cpp
+++ b/src/gui/ok_dialog.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,12 +33,12 @@ OkDialog::OkDialog(const std::string &title, const std::string &msg,
Window *parent):
Window(title, true, parent)
{
- mTextBox = new TextBox();
+ mTextBox = new TextBox;
mTextBox->setEditable(false);
mTextBox->setOpaque(false);
mTextArea = new ScrollArea(mTextBox);
- okButton = new Button(_("Ok"), "ok", this);
+ gcn::Button *okButton = new Button(_("Ok"), "ok", this);
mTextArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
mTextArea->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
@@ -69,7 +68,7 @@ OkDialog::OkDialog(const std::string &title, const std::string &msg,
add(mTextArea);
add(okButton);
- setLocationRelativeTo(getParent());
+ center();
setVisible(true);
okButton->requestFocus();
}
diff --git a/src/gui/ok_dialog.h b/src/gui/ok_dialog.h
index 6cfe0798..46dd4db0 100644
--- a/src/gui/ok_dialog.h
+++ b/src/gui/ok_dialog.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,13 +19,13 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _OK_DIALOG_H
-#define _OK_DIALOG_H
-
-#include <guichan/actionlistener.hpp>
+#ifndef OK_DIALOG_H
+#define OK_DIALOG_H
#include "window.h"
+#include <guichan/actionlistener.hpp>
+
class ScrollArea;
class TextBox;
@@ -56,7 +55,6 @@ class OkDialog : public Window, public gcn::ActionListener
private:
TextBox *mTextBox;
ScrollArea *mTextArea;
- gcn::Button *okButton;
};
#endif
diff --git a/src/gui/palette.cpp b/src/gui/palette.cpp
index 2efc60be..b176fcff 100644
--- a/src/gui/palette.cpp
+++ b/src/gui/palette.cpp
@@ -3,7 +3,7 @@
* Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net>
* Copyright (C) 2009 The Mana World Development Team
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -76,8 +76,7 @@ const int Palette::GRADIENT_DELAY = 40;
Palette::Palette() :
mRainbowTime(tick_time),
- mColVector(ColVector(TYPE_COUNT)),
- mGradVector()
+ mColVector(ColVector(TYPE_COUNT))
{
std::string indent = " ";
addColor(TEXT, 0x000000, STATIC, _("Text"));
@@ -346,4 +345,3 @@ void Palette::advanceGradient ()
mRainbowTime = tick_time;
}
}
-
diff --git a/src/gui/palette.h b/src/gui/palette.h
index e894ba74..b2994351 100644
--- a/src/gui/palette.h
+++ b/src/gui/palette.h
@@ -3,7 +3,7 @@
* Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net>
* Copyright (C) 2009 The Mana World Development Team
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -124,7 +124,7 @@ class Palette : public gcn::ListModel
*
* @return the requested color or Palette::BLACK
*/
- const gcn::Color& getColor(char c, bool &valid);
+ const gcn::Color &getColor(char c, bool &valid);
/**
* Gets the color associated with the type. Sets the alpha channel
@@ -135,7 +135,7 @@ class Palette : public gcn::ListModel
*
* @return the requested color
*/
- inline const gcn::Color& getColor(ColorType type, int alpha = 255)
+ inline const gcn::Color &getColor(ColorType type, int alpha = 255)
{
gcn::Color* col = &mColVector[type].color;
col->a = alpha;
@@ -149,8 +149,10 @@ class Palette : public gcn::ListModel
*
* @return the requested committed color
*/
- inline const gcn::Color& getCommittedColor(ColorType type)
- { return mColVector[type].committedColor; }
+ inline const gcn::Color &getCommittedColor(ColorType type)
+ {
+ return mColVector[type].committedColor;
+ }
/**
* Gets the test color associated with the specified type.
@@ -159,8 +161,10 @@ class Palette : public gcn::ListModel
*
* @return the requested test color
*/
- inline const gcn::Color& getTestColor(ColorType type)
- { return mColVector[type].testColor; }
+ inline const gcn::Color &getTestColor(ColorType type)
+ {
+ return mColVector[type].testColor;
+ }
/**
* Sets the test color associated with the specified type.
@@ -169,7 +173,9 @@ class Palette : public gcn::ListModel
* @param color the color that should be tested
*/
inline void setTestColor(ColorType type, gcn::Color color)
- { mColVector[type].testColor = color; }
+ {
+ mColVector[type].testColor = color;
+ }
/**
* Gets the GradientType associated with the specified type.
@@ -179,7 +185,9 @@ class Palette : public gcn::ListModel
* @return the gradient type of the color with the given index
*/
inline GradientType getGradientType(ColorType type)
- { return mColVector[type].grad; }
+ {
+ return mColVector[type].grad;
+ }
/**
* Get the character used by the specified color.
@@ -188,7 +196,10 @@ class Palette : public gcn::ListModel
*
* @return the color char of the color with the given index
*/
- inline char getColorChar(ColorType type) { return mColVector[type].ch; }
+ inline char getColorChar(ColorType type)
+ {
+ return mColVector[type].ch;
+ }
/**
* Sets the color for the specified type.
@@ -236,7 +247,10 @@ class Palette : public gcn::ListModel
/**
* Commit the colors
*/
- inline void commit() { commit(false); }
+ inline void commit()
+ {
+ commit(false);
+ }
/**
* Rollback the colors
@@ -331,7 +345,7 @@ class Palette : public gcn::ListModel
*
* @return the transformed string
*/
- static std::string getConfigName(const std::string& typeName);
+ static std::string getConfigName(const std::string &typeName);
};
extern Palette *guiPalette;
diff --git a/src/gui/partywindow.cpp b/src/gui/partywindow.cpp
new file mode 100644
index 00000000..3f857b5c
--- /dev/null
+++ b/src/gui/partywindow.cpp
@@ -0,0 +1,145 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "partywindow.h"
+#include "chat.h"
+
+#include "widgets/avatar.h"
+
+#include "../utils/gettext.h"
+#include "../net/tmwserv/chatserver/party.h"
+
+PartyWindow::PartyWindow() : Window(_("Party"))
+{
+ setWindowName("Party");
+ setVisible(false);
+ setResizable(false);
+ setCaption(_("Party"));
+ setCloseButton(true);
+ setMinWidth(110);
+ setMinHeight(200);
+ setDefaultSize(620, 300, 110, 200);
+
+ loadWindowState();
+}
+
+PartyWindow::~PartyWindow()
+{
+ mPartyMembers.clear();
+}
+
+void PartyWindow::draw(gcn::Graphics *graphics)
+{
+ Window::draw(graphics);
+}
+
+void PartyWindow::addPartyMember(const std::string &memberName)
+{
+ // check to see if player is already in the party
+ PartyList::iterator itr = mPartyMembers.begin(),
+ itr_end = mPartyMembers.end();
+
+ while (itr != itr_end)
+ {
+ if ((*itr).name == memberName)
+ {
+ // already in the party, dont add
+ return;
+ }
+ ++itr;
+ }
+
+ // create new party member
+ PartyMember player;
+ player.name = memberName;
+ mPartyMembers.push_back(player);
+
+ // add avatar of the new member to window
+ Avatar *avatar = new Avatar(memberName);
+ add(avatar, 0, (mPartyMembers.size() - 1)*14);
+
+ // show the window
+ if (mPartyMembers.size() > 0)
+ {
+ setVisible(true);
+ }
+}
+
+void PartyWindow::removePartyMember(const std::string &memberName)
+{
+ // remove the party member
+ PartyList::iterator itr = mPartyMembers.begin(),
+ itr_end = mPartyMembers.end();
+
+ while (itr != itr_end)
+ {
+ if ((*itr).name == memberName)
+ {
+ mPartyMembers.erase(itr);
+ break;
+ }
+ ++itr;
+ }
+
+ // if no-one left, remove the party window
+ if (mPartyMembers.size() < 1)
+ {
+ setVisible(false);
+ }
+}
+
+void PartyWindow::showPartyInvite(const std::string &inviter)
+{
+ // check there isnt already an invite showing
+ if (mPartyInviter != "")
+ {
+ localChatTab->chatLog("Received party request, but one already exists",
+ BY_SERVER);
+ return;
+ }
+
+ // log invite
+ std::string msg = inviter + " has invited you to join their party";
+ localChatTab->chatLog(msg, BY_SERVER);
+
+ // show invite
+ acceptDialog = new ConfirmDialog("Accept Party Invite", msg, this);
+ acceptDialog->addActionListener(this);
+
+ mPartyInviter = inviter;
+}
+
+void PartyWindow::action(const gcn::ActionEvent &event)
+{
+ const std::string &eventId = event.getId();
+
+ // check if they accepted the invite
+ if (eventId == "yes")
+ {
+ localChatTab->chatLog("Accepted invite from " + mPartyInviter);
+ Net::ChatServer::Party::acceptInvite(mPartyInviter);
+ mPartyInviter = "";
+ }
+ else if (eventId == "no")
+ {
+ mPartyInviter = "";
+ }
+}
diff --git a/src/gui/partywindow.h b/src/gui/partywindow.h
new file mode 100644
index 00000000..b587cc42
--- /dev/null
+++ b/src/gui/partywindow.h
@@ -0,0 +1,96 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PARTYWINDOW_H
+#define PARTYWINDOW_H
+
+#include "window.h"
+#include "confirm_dialog.h"
+
+#include <string>
+#include <vector>
+
+#include <guichan/actionevent.hpp>
+#include <guichan/actionlistener.hpp>
+
+/**
+ * Party Member
+ * Used for storing players in the party
+ */
+struct PartyMember
+{
+ std::string name;
+ int vitality;
+};
+
+/**
+ * Party Window.
+ *
+ * \ingroup Interface
+ */
+class PartyWindow : public Window, gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ PartyWindow();
+
+ /**
+ * Release all the players created
+ */
+ ~PartyWindow();
+
+ /**
+ * Draws the party window
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Add party member
+ */
+ void addPartyMember(const std::string &memberName);
+
+ /**
+ * Remove party member
+ */
+ void removePartyMember(const std::string &memberName);
+
+ /**
+ * Show party invite
+ */
+ void showPartyInvite(const std::string &inviter);
+
+ /**
+ * Handle events
+ */
+ void action(const gcn::ActionEvent &event);
+
+ private:
+ typedef std::vector<PartyMember> PartyList;
+ PartyList mPartyMembers;
+ std::string mPartyInviter;
+ ConfirmDialog *acceptDialog;
+};
+
+extern PartyWindow *partyWindow;
+
+#endif
diff --git a/src/gui/passwordfield.cpp b/src/gui/passwordfield.cpp
index 073f5e36..fd8ebe22 100644
--- a/src/gui/passwordfield.cpp
+++ b/src/gui/passwordfield.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,7 +21,7 @@
#include "passwordfield.h"
-PasswordField::PasswordField(const std::string& text):
+PasswordField::PasswordField(const std::string &text):
TextField(text)
{
}
diff --git a/src/gui/passwordfield.h b/src/gui/passwordfield.h
index adad54fe..3b0b5dab 100644
--- a/src/gui/passwordfield.h
+++ b/src/gui/passwordfield.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,8 +22,6 @@
#ifndef PASSWORDFIELD_H
#define PASSWORDFIELD_H
-#include <string>
-
#include "textfield.h"
/**
@@ -38,7 +35,7 @@ class PasswordField : public TextField
/**
* Constructor, initializes the password field with the given string.
*/
- PasswordField(const std::string& text = "");
+ PasswordField(const std::string &text = "");
/**
* Draws the password field.
diff --git a/src/gui/playerbox.cpp b/src/gui/playerbox.cpp
index 2a6cdb20..b7e553dc 100644
--- a/src/gui/playerbox.cpp
+++ b/src/gui/playerbox.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -85,10 +84,14 @@ void PlayerBox::draw(gcn::Graphics *graphics)
if (mPlayer)
{
// Draw character
- int x, y, bs;
- bs = getFrameSize();
- x = getWidth() / 2 - 16 + bs;
- y = getHeight() / 2 + bs;
+ const int bs = getFrameSize();
+#ifdef TMWSERV_SUPPORT
+ const int x = getWidth() / 2 + bs;
+ const int y = getHeight() - bs - 8;
+ mPlayer->draw(static_cast<Graphics*>(graphics), x, y);
+#else
+ const int x = getWidth() / 2 - 16 + bs;
+ const int y = getHeight() / 2 + bs;
for (int i = 0; i < Being::VECTOREND_SPRITE; i++)
{
if (mPlayer->getSprite(i))
@@ -96,6 +99,7 @@ void PlayerBox::draw(gcn::Graphics *graphics)
mPlayer->getSprite(i)->draw(static_cast<Graphics*>(graphics), x, y);
}
}
+#endif
}
if (config.getValue("guialpha", 0.8) != mAlpha)
diff --git a/src/gui/playerbox.h b/src/gui/playerbox.h
index ee25520a..7c08defd 100644
--- a/src/gui/playerbox.h
+++ b/src/gui/playerbox.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/popup.cpp b/src/gui/popup.cpp
index f4c7d4a3..648a9d6a 100644
--- a/src/gui/popup.cpp
+++ b/src/gui/popup.cpp
@@ -1,9 +1,9 @@
/*
- * Aethyra
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
* Copyright (C) 2009 Aethyra Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,7 +32,7 @@
#include "../resources/image.h"
-Popup::Popup(const std::string& name, const std::string& skin):
+Popup::Popup(const std::string &name, const std::string &skin):
mPopupName(name),
mDefaultSkinPath(skin),
mMinWidth(100),
diff --git a/src/gui/popup.h b/src/gui/popup.h
index c68c2098..6fbe796c 100644
--- a/src/gui/popup.h
+++ b/src/gui/popup.h
@@ -1,9 +1,9 @@
/*
- * Aethyra
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
* Copyright (C) 2009 Aethyra Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -52,7 +52,7 @@ class Popup : public gcn::Container
* debugging purposes.
* @param skin The location where the Popup's skin XML can be found.
*/
- Popup(const std::string& name = "",
+ Popup(const std::string &name = "",
const std::string &skin = "graphics/gui/gui.xml");
/**
@@ -97,39 +97,27 @@ class Popup : public gcn::Container
*/
void setMinWidth(int width);
+ int getMinWidth() const { return mMinWidth; }
+
/**
* Sets the minimum height of the popup.
*/
void setMinHeight(int height);
+ int getMinHeight() const { return mMinHeight; }
+
/**
* Sets the maximum width of the popup.
*/
void setMaxWidth(int width);
+ int getMaxWidth() const { return mMaxWidth; }
+
/**
* Sets the minimum height of the popup.
*/
void setMaxHeight(int height);
- /**
- * Gets the minimum width of the popup.
- */
- int getMinWidth() const { return mMinWidth; }
-
- /**
- * Gets the minimum height of the popup.
- */
- int getMinHeight() const { return mMinHeight; }
-
- /**
- * Gets the maximum width of the popup.
- */
- int getMaxWidth() const { return mMaxWidth; }
-
- /**
- * Gets the minimum height of the popup.
- */
int getMaxHeight() const { return mMaxHeight; }
/**
@@ -141,24 +129,16 @@ class Popup : public gcn::Container
*/
int getPadding() const { return mPadding; }
- /**
- * Sets the padding of the popup. The padding is the distance between the
- * popup border and the content.
- *
- * @param padding The padding of the popup.
- * @see getPadding
- */
void setPadding(int padding) { mPadding = padding; }
/**
* Sets the name of the popup. This is only useful for debug purposes.
*/
- void setPopupName(const std::string &name) { mPopupName = name; }
+ void setPopupName(const std::string &name)
+ { mPopupName = name; }
- /**
- * Returns the name of the popup. This is only useful for debug purposes.
- */
- const std::string& getPopupName() { return mPopupName; }
+ const std::string &getPopupName() const
+ { return mPopupName; }
/**
* Schedule this popup for deletion. It will be deleted at the start
@@ -179,7 +159,7 @@ class Popup : public gcn::Container
int mMaxHeight; /**< Maximum popup height */
int mPadding; /**< Holds the padding of the popup. */
- Skin* mSkin; /**< Skin in use by this popup */
+ Skin *mSkin; /**< Skin in use by this popup */
};
#endif
diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp
index 13adf827..0b019fef 100644
--- a/src/gui/popupmenu.cpp
+++ b/src/gui/popupmenu.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,30 +19,34 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <cassert>
+#include "gui/popupmenu.h"
+
+#include "gui/browserbox.h"
+#include "gui/chat.h"
+#include "gui/inventorywindow.h"
+#include "gui/item_amount.h"
-#include "browserbox.h"
-#include "chat.h"
-#include "inventorywindow.h"
-#include "item_amount.h"
-#include "popupmenu.h"
+#include "being.h"
+#include "beingmanager.h"
+#include "floor_item.h"
+#include "graphics.h"
+#include "item.h"
+#include "localplayer.h"
+#include "npc.h"
+#include "player_relations.h"
-#include "../being.h"
-#include "../beingmanager.h"
-#include "../floor_item.h"
-#include "../graphics.h"
-#include "../item.h"
-#include "../localplayer.h"
-#include "../npc.h"
-#include "../player_relations.h"
+#ifdef EATHENA_SUPPORT
+#include "net/messageout.h"
+#include "net/ea/protocol.h"
+#endif
-#include "../net/messageout.h"
-#include "../net/protocol.h"
+#include "resources/itemdb.h"
+#include "resources/iteminfo.h"
-#include "../resources/itemdb.h"
+#include "utils/gettext.h"
+#include "utils/strprintf.h"
-#include "../utils/gettext.h"
-#include "../utils/strprintf.h"
+#include <cassert>
extern std::string tradePartnerName;
@@ -57,7 +60,7 @@ PopupMenu::PopupMenu():
setTitleBarHeight(0);
setShowTitle(false);
- mBrowserBox = new BrowserBox();
+ mBrowserBox = new BrowserBox;
mBrowserBox->setPosition(4, 4);
mBrowserBox->setHighlightMode(BrowserBox::BACKGROUND);
mBrowserBox->setOpaque(false);
@@ -85,26 +88,28 @@ void PopupMenu::showPopup(int x, int y, Being *being)
mBrowserBox->addRow("##3---");
switch (player_relations.getRelation(name)) {
- case PlayerRelation::NEUTRAL:
- mBrowserBox->addRow(strprintf(_("@@friend|Befriend %s@@"), name.c_str()));
-
- case PlayerRelation::FRIEND:
- mBrowserBox->addRow(strprintf(_("@@disregard|Disregard %s@@"), name.c_str()));
- mBrowserBox->addRow(strprintf(_("@@ignore|Ignore %s@@"), name.c_str()));
- break;
-
- case PlayerRelation::DISREGARDED:
- mBrowserBox->addRow(strprintf(_("@@unignore|Un-Ignore %s@@"), name.c_str()));
- mBrowserBox->addRow(strprintf(_("@@ignore|Completely ignore %s@@"), name.c_str()));
- break;
-
- case PlayerRelation::IGNORED:
- mBrowserBox->addRow(strprintf(_("@@unignore|Un-Ignore %s@@"), name.c_str()));
- break;
+ case PlayerRelation::NEUTRAL:
+ mBrowserBox->addRow(strprintf(_("@@friend|Befriend %s@@"), name.c_str()));
+
+ case PlayerRelation::FRIEND:
+ mBrowserBox->addRow(strprintf(_("@@disregard|Disregard %s@@"), name.c_str()));
+ mBrowserBox->addRow(strprintf(_("@@ignore|Ignore %s@@"), name.c_str()));
+ break;
+
+ case PlayerRelation::DISREGARDED:
+ mBrowserBox->addRow(strprintf(_("@@unignore|Un-Ignore %s@@"), name.c_str()));
+ mBrowserBox->addRow(strprintf(_("@@ignore|Completely ignore %s@@"), name.c_str()));
+ break;
+
+ case PlayerRelation::IGNORED:
+ mBrowserBox->addRow(strprintf(_("@@unignore|Un-Ignore %s@@"), name.c_str()));
+ break;
}
//mBrowserBox->addRow(_("@@follow|Follow ") + name + "@@");
//mBrowserBox->addRow(_("@@buddy|Add ") + name + " to Buddy List@@");
+ mBrowserBox->addRow(strprintf(_("@@guild|Invite %s@@"), name.c_str()));
+ mBrowserBox->addRow(strprintf(_("@@party|Invite %s to join your party@@"), name.c_str()));
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf(_("@@party-invite|Invite %s to party@@"), name.c_str()));
@@ -145,51 +150,78 @@ void PopupMenu::showPopup(int x, int y, FloorItem *floorItem)
showPopup(x, y);
}
-void PopupMenu::handleLink(const std::string& link)
+void PopupMenu::handleLink(const std::string &link)
{
Being *being = beingManager->findBeing(mBeingId);
// Talk To action
- if (link == "talk" && being && being->getType() == Being::NPC &&
+ if (link == "talk" &&
+ being &&
+ being->getType() == Being::NPC &&
current_npc == 0)
{
dynamic_cast<NPC*>(being)->talk();
}
// Trade action
- else if (link == "trade" && being && being->getType() == Being::PLAYER)
+ else if (link == "trade" &&
+ being &&
+ being->getType() == Being::PLAYER)
{
player_node->trade(being);
tradePartnerName = being->getName();
}
-
+#ifdef EATHENA_SUPPORT
// Attack action
- else if (link == "attack" && being && being->getType() == Being::PLAYER)
+ else if (link == "attack" &&
+ being &&
+ being->getType() == Being::PLAYER)
{
player_node->attack(being, true);
}
-
- else if (link == "unignore" && being && being->getType() == Being::PLAYER)
+#endif
+ else if (link == "unignore" &&
+ being &&
+ being->getType() == Being::PLAYER)
{
player_relations.setRelation(being->getName(), PlayerRelation::NEUTRAL);
}
- else if (link == "ignore" && being && being->getType() == Being::PLAYER)
+ else if (link == "ignore" &&
+ being &&
+ being->getType() == Being::PLAYER)
{
player_relations.setRelation(being->getName(), PlayerRelation::IGNORED);
}
- else if (link == "disregard" && being &&
+ else if (link == "disregard" &&
+ being &&
being->getType() == Being::PLAYER)
{
player_relations.setRelation(being->getName(), PlayerRelation::DISREGARDED);
}
- else if (link == "friend" && being && being->getType() == Being::PLAYER)
+ else if (link == "friend" &&
+ being &&
+ being->getType() == Being::PLAYER)
{
player_relations.setRelation(being->getName(), PlayerRelation::FRIEND);
}
+#ifdef TMWSERV_SUPPORT
+ // Guild action
+ else if (link == "guild" &&
+ being != NULL &&
+ being->getType() == Being::PLAYER)
+ {
+ player_node->inviteToGuild(being);
+ }
+ // Add player to your party
+ else if (link == "party")
+ {
+ player_node->inviteToParty(being->getName());
+ }
+#endif
/*
// Follow Player action
else if (link == "follow")
@@ -222,6 +254,9 @@ void PopupMenu::handleLink(const std::string& link)
assert(mItem);
if (mItem->isEquipment())
{
+#ifdef TMWSERV_SUPPORT
+ player_node->equipItem(mItem);
+#else
if (mItem->isEquipped())
{
player_node->unequipItem(mItem);
@@ -230,10 +265,15 @@ void PopupMenu::handleLink(const std::string& link)
{
player_node->equipItem(mItem);
}
+#endif
}
else
{
+#ifdef TMWSERV_SUPPORT
+ player_node->useItem(mItem->getInvIndex());
+#else
player_node->useItem(mItem);
+#endif
}
}
@@ -242,17 +282,24 @@ void PopupMenu::handleLink(const std::string& link)
chatWindow->addItemText(mItem->getInfo().getName());
}
+ else if (link == "split")
+ {
+ new ItemAmountWindow(AMOUNT_ITEM_SPLIT, inventoryWindow, mItem);
+ }
else if (link == "drop")
{
new ItemAmountWindow(AMOUNT_ITEM_DROP, inventoryWindow, mItem);
}
- else if (link == "party-invite" && being &&
+#ifdef EATHENA_SUPPORT
+ else if (link == "party-invite" &&
+ being &&
being->getType() == Being::PLAYER)
{
MessageOut outMsg(player_node->getNetwork());
outMsg.writeInt16(CMSG_PARTY_INVITE);
outMsg.writeInt32(being->getId());
}
+#endif
// Unknown actions
else
@@ -275,15 +322,23 @@ void PopupMenu::showPopup(int x, int y, Item *item)
if (item->isEquipment())
{
+#ifdef TMWSERV_SUPPORT
+ mBrowserBox->addRow(_("@@use|Equip@@"));
+#else
if (item->isEquipped())
mBrowserBox->addRow(_("@@use|Unequip@@"));
else
mBrowserBox->addRow(_("@@use|Equip@@"));
+#endif
}
else
mBrowserBox->addRow(_("@@use|Use@@"));
mBrowserBox->addRow(_("@@drop|Drop@@"));
+#ifdef TMWSERV_SUPPORT
+ if (!item->isEquipment())
+ mBrowserBox->addRow(_("@@split|Split@@"));
+#endif
mBrowserBox->addRow(_("@@chat|Add to Chat@@"));
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(_("@@cancel|Cancel@@"));
diff --git a/src/gui/popupmenu.h b/src/gui/popupmenu.h
index 89152751..d9fb4777 100644
--- a/src/gui/popupmenu.h
+++ b/src/gui/popupmenu.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -62,7 +61,7 @@ class PopupMenu : public Window, public LinkHandler
/**
* Handles link action.
*/
- void handleLink(const std::string& link);
+ void handleLink(const std::string &link);
private:
BrowserBox* mBrowserBox;
diff --git a/src/gui/progressbar.cpp b/src/gui/progressbar.cpp
index 1f21df79..02ddab16 100644
--- a/src/gui/progressbar.cpp
+++ b/src/gui/progressbar.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -44,6 +43,9 @@ ProgressBar::ProgressBar(float progress,
mRed(red), mGreen(green), mBlue(blue),
mRedToGo(red), mGreenToGo(green), mBlueToGo(blue)
{
+ mProgressToGo = mProgress = 0.0f;
+ mSmoothProgress = mSmoothColorChange = true;
+
setProgress(progress);
setWidth(width);
setHeight(height);
@@ -93,13 +95,31 @@ ProgressBar::~ProgressBar()
void ProgressBar::logic()
{
- // Smoothly changing the color for a nicer effect.
- if (mRedToGo > mRed) mRed++;
- if (mRedToGo < mRed) mRed--;
- if (mGreenToGo > mGreen) mGreen++;
- if (mGreenToGo < mGreen) mGreen--;
- if (mBlueToGo > mBlue) mBlue++;
- if (mBlueToGo < mBlue) mBlue--;
+ if (mSmoothColorChange)
+ {
+ // Smoothly changing the color for a nicer effect.
+ if (mRedToGo > mRed) mRed++;
+ if (mRedToGo < mRed) mRed--;
+ if (mGreenToGo > mGreen) mGreen++;
+ if (mGreenToGo < mGreen) mGreen--;
+ if (mBlueToGo > mBlue) mBlue++;
+ if (mBlueToGo < mBlue) mBlue--;
+ }
+ else
+ {
+ mRed = mRedToGo;
+ mGreen = mGreenToGo;
+ mBlue = mBlueToGo;
+ }
+
+ if (mSmoothProgress)
+ {
+ // Smoothly showing the progressbar changes.
+ if (mProgressToGo > mProgress) mProgress = mProgress + 0.005f;
+ if (mProgressToGo < mProgress) mProgress = mProgress - 0.005f;
+ }
+ else
+ mProgress = mProgressToGo;
}
void ProgressBar::draw(gcn::Graphics *graphics)
@@ -142,9 +162,9 @@ void ProgressBar::draw(gcn::Graphics *graphics)
void ProgressBar::setProgress(float progress)
{
- if (progress < 0.0f) mProgress = 0.0;
- else if (progress > 1.0f) mProgress = 1.0;
- else mProgress = progress;
+ if (progress < 0.0f) mProgressToGo = 0.0;
+ else if (progress > 1.0f) mProgressToGo = 1.0;
+ else mProgressToGo = progress;
}
void ProgressBar::setColor(Uint8 red, Uint8 green, Uint8 blue)
diff --git a/src/gui/progressbar.h b/src/gui/progressbar.h
index 3c88f3a3..e75b1d44 100644
--- a/src/gui/progressbar.h
+++ b/src/gui/progressbar.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -103,16 +102,35 @@ class ProgressBar : public gcn::Widget
const std::string &text() const
{ return mText; }
+ /**
+ * Set wether the progress is moved smoothly.
+ */
+ void setSmoothProgress(bool smoothProgress)
+ { mSmoothProgress = smoothProgress; }
+
+ /**
+ * Set wether the color changing is made smoothly.
+ */
+ void setSmoothColorChange(bool smoothColorChange)
+ { mSmoothColorChange = smoothColorChange; }
+
+
private:
- float mProgress;
+ float mProgress, mProgressToGo;
+ bool mSmoothProgress;
+
Uint8 mRed, mGreen, mBlue;
Uint8 mRedToGo, mGreenToGo, mBlueToGo;
+ bool mSmoothColorChange;
+
std::string mText;
bool mUpdated;
static ImageRect mBorder;
static int mInstances;
static float mAlpha;
+
+ static const gcn::Color TEXT_COLOR;
};
#endif
diff --git a/src/gui/quitdialog.cpp b/src/gui/quitdialog.cpp
new file mode 100644
index 00000000..83794ffe
--- /dev/null
+++ b/src/gui/quitdialog.cpp
@@ -0,0 +1,135 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "quitdialog.h"
+#include <iostream>
+#include <string>
+
+#include <guichan/widgets/label.hpp>
+
+#include "../main.h"
+
+#include "button.h"
+#include "radiobutton.h"
+
+#include "../utils/gettext.h"
+
+QuitDialog::QuitDialog(bool* quitGame, QuitDialog** pointerToMe):
+ Window(_("Quit"), true, NULL), mQuitGame(quitGame), mMyPointer(pointerToMe)
+{
+
+ mLogoutQuit = new RadioButton(_("Quit"), "quitdialog");
+ mForceQuit = new RadioButton(_("Quit"), "quitdialog");
+ mSwitchAccountServer = new RadioButton(_("Switch server"), "quitdialog");
+ mSwitchCharacter = new RadioButton(_("Switch character"), "quitdialog");
+ mOkButton = new Button(_("Ok"), "ok", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+
+ setContentSize(200, 91);
+
+ mLogoutQuit->setPosition(5, 5);
+ mForceQuit->setPosition(5, 5);
+ mSwitchAccountServer->setPosition(5, 14 + mLogoutQuit->getHeight());
+ mSwitchCharacter->setPosition(5,
+ 23 + mLogoutQuit->getHeight() + mSwitchAccountServer->getHeight());
+ mCancelButton->setPosition(
+ 200 - mCancelButton->getWidth() - 5,
+ 91 - mCancelButton->getHeight() - 5);
+ mOkButton->setPosition(
+ mCancelButton->getX() - mOkButton->getWidth() - 5,
+ 91 - mOkButton->getHeight() - 5);
+
+ //All states, when we're not logged in to someone.
+ if (state == STATE_CHOOSE_SERVER ||
+ state == STATE_CONNECT_ACCOUNT ||
+ state == STATE_LOGIN ||
+ state == STATE_LOGIN_ATTEMPT ||
+ state == STATE_UPDATE)
+ {
+ mForceQuit->setSelected(true);
+ add(mForceQuit);
+ }
+ else
+ {
+ // Only added if we are connected to an accountserver or gameserver
+ mLogoutQuit->setSelected(true);
+ add(mLogoutQuit);
+ add(mSwitchAccountServer);
+
+ // Only added if we are connected to a gameserver
+ if (state == STATE_GAME) add(mSwitchCharacter);
+ }
+
+ add(mOkButton);
+ add(mCancelButton);
+
+ setLocationRelativeTo(getParent());
+ setVisible(true);
+
+ mOkButton->requestFocus();
+
+}
+
+QuitDialog::~QuitDialog()
+{
+ if (mMyPointer) *mMyPointer = NULL;
+ // Optional widgets, so delete them by hand.
+ delete mForceQuit;
+ delete mLogoutQuit;
+ delete mSwitchAccountServer;
+ delete mSwitchCharacter;
+}
+
+void
+QuitDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "ok")
+ {
+ if (mForceQuit->isSelected())
+ {
+ state = STATE_FORCE_QUIT;
+ }
+ else if (mLogoutQuit->isSelected())
+ {
+ if ((state == STATE_GAME) && (mQuitGame))
+ {
+ *mQuitGame = true;
+ }
+ state = STATE_EXIT;
+ }
+ else if (mSwitchAccountServer->isSelected())
+ {
+ if ((state == STATE_GAME) && (mQuitGame))
+ {
+ *mQuitGame = true;
+ }
+ state = STATE_SWITCH_ACCOUNTSERVER_ATTEMPT;
+ }
+ else if (mSwitchCharacter->isSelected())
+ {
+ if (mQuitGame) *mQuitGame = true;
+
+ state = STATE_SWITCH_CHARACTER;
+ }
+
+ }
+ scheduleDelete();
+}
diff --git a/src/gui/quitdialog.h b/src/gui/quitdialog.h
new file mode 100644
index 00000000..aee671db
--- /dev/null
+++ b/src/gui/quitdialog.h
@@ -0,0 +1,70 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef QUITDIALOG_H
+#define QUITDIALOG_H
+
+#include <iosfwd>
+#include <guichan/actionlistener.hpp>
+
+#include "window.h"
+#include "../guichanfwd.h"
+#include "../main.h"
+
+/**
+ * The quit dialog.
+ *
+ * \ingroup Interface
+ */
+class QuitDialog : public Window, public gcn::ActionListener {
+ public:
+ /**
+ * Constructor
+ *
+ * @quitGame; to be used for getting out of the while loop in Game
+ * @pointerToMe; will be set to NULL when the QuitDialog is destroyed
+ */
+ QuitDialog(bool* quitGame, QuitDialog** pointerToMe);
+
+ /**
+ * Destructor
+ */
+ ~QuitDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ private:
+ gcn::RadioButton *mLogoutQuit;
+ gcn::RadioButton *mForceQuit;
+ gcn::RadioButton *mSwitchAccountServer;
+ gcn::RadioButton *mSwitchCharacter;
+ gcn::Button *mOkButton;
+ gcn::Button *mCancelButton;
+
+ bool* mQuitGame;
+ QuitDialog** mMyPointer;
+
+};
+
+#endif
diff --git a/src/gui/radiobutton.cpp b/src/gui/radiobutton.cpp
index c839238b..b05e37e6 100644
--- a/src/gui/radiobutton.cpp
+++ b/src/gui/radiobutton.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,7 +34,7 @@ Image *RadioButton::radioChecked;
Image *RadioButton::radioDisabled;
Image *RadioButton::radioDisabledChecked;
-RadioButton::RadioButton(const std::string& caption, const std::string& group,
+RadioButton::RadioButton(const std::string &caption, const std::string &group,
bool marked):
gcn::RadioButton(caption, group, marked)
{
diff --git a/src/gui/radiobutton.h b/src/gui/radiobutton.h
index cd501126..9aec3add 100644
--- a/src/gui/radiobutton.h
+++ b/src/gui/radiobutton.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,7 +35,7 @@ class RadioButton : public gcn::RadioButton
/*
* Constructor.
*/
- RadioButton(const std::string& caption,const std::string& group,
+ RadioButton(const std::string &caption,const std::string &group,
bool marked = false);
/**
diff --git a/src/gui/recorder.cpp b/src/gui/recorder.cpp
index 9320e020..4f919bef 100644
--- a/src/gui/recorder.cpp
+++ b/src/gui/recorder.cpp
@@ -2,7 +2,7 @@
* A chat recorder
* Copyright (C) 2008 Lloyd Bryant <lloyd_bryant@netzero.net>
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@
#include "recorder.h"
#include "windowcontainer.h"
+#include "widgets/chattab.h"
#include "widgets/layout.h"
#include "../utils/stringutils.h"
@@ -34,7 +35,7 @@ Recorder::Recorder(ChatWindow *chat, const std::string &title,
const std::string &buttonTxt) :
Window(title)
{
- setWindowName(_("Recorder"));
+ setWindowName("Recorder");
const int offsetX = 2 * getPadding() + 10;
const int offsetY = getTitleBarHeight() + getPadding() + 10;
@@ -66,7 +67,7 @@ void Recorder::record(const std::string &msg)
}
}
-void Recorder::changeRecordingStatus(const std::string &msg)
+void Recorder::setRecordingFile(const std::string &msg)
{
std::string msgCopy = msg;
trim(msgCopy);
@@ -82,16 +83,16 @@ void Recorder::changeRecordingStatus(const std::string &msg)
* Message should go after mStream is closed so that it isn't
* recorded.
*/
- mChat->chatLog(_("Finishing recording."), BY_SERVER);
+ localChatTab->chatLog(_("Finishing recording."), BY_SERVER);
}
else
{
- mChat->chatLog(_("Not currently recording."), BY_SERVER);
+ localChatTab->chatLog(_("Not currently recording."), BY_SERVER);
}
}
else if (mStream.is_open())
{
- mChat->chatLog(_("Already recording."), BY_SERVER);
+ localChatTab->chatLog(_("Already recording."), BY_SERVER);
}
else
{
@@ -99,19 +100,20 @@ void Recorder::changeRecordingStatus(const std::string &msg)
* Message should go before mStream is opened so that it isn't
* recorded.
*/
- mChat->chatLog(_("Starting to record..."), BY_SERVER);
- std::string file = std::string(PHYSFS_getUserDir()) + "/.aethyra/" + msgCopy;
+ localChatTab->chatLog(_("Starting to record..."), BY_SERVER);
+ const std::string file =
+ std::string(PHYSFS_getUserDir()) + "/.tmw/" + msgCopy;
mStream.open(file.c_str(), std::ios_base::trunc);
if (mStream.is_open())
setVisible(true);
else
- mChat->chatLog(_("Failed to start recording."), BY_SERVER);
+ localChatTab->chatLog(_("Failed to start recording."), BY_SERVER);
}
}
void Recorder::action(const gcn::ActionEvent &event)
{
- changeRecordingStatus("");
+ setRecordingFile("");
}
diff --git a/src/gui/recorder.h b/src/gui/recorder.h
index 4f41ff42..39d00c2c 100644
--- a/src/gui/recorder.h
+++ b/src/gui/recorder.h
@@ -2,7 +2,7 @@
* A chat recorder
* Copyright (C) 2008 Lloyd Bryant <lloyd_bryant@netzero.net>
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,26 +41,26 @@ class Recorder : public Window, public gcn::ActionListener
virtual ~Recorder();
- /*
+ /**
* Outputs the message to the recorder file
*
* @param msg the line to write to the recorded file.
*/
void record(const std::string &msg);
- /*
- * Outputs the message to the recorder file
+ /**
+ * Sets the file being recorded to
*
* @param msg The file to write out to. If null, then stop recording.
*/
- void changeRecordingStatus(const std::string &msg);
+ void setRecordingFile(const std::string &msg);
- /*
+ /**
* Whether or not the recorder is in use.
*/
- bool isRecording() {return (bool) mStream.is_open();}
+ bool isRecording() { return (bool) mStream.is_open(); }
- /*
+ /**
* called when the button is pressed
*
* @param event is the event that is generated
diff --git a/src/gui/register.cpp b/src/gui/register.cpp
index 63a0d29c..5fb8b579 100644
--- a/src/gui/register.cpp
+++ b/src/gui/register.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,20 +40,6 @@
#include "../utils/strprintf.h"
#include "../utils/stringutils.h"
-/**
- * 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;
-};
-
void WrongDataNoticeListener::setTarget(gcn::TextField *textField)
{
mTarget = textField;
@@ -74,15 +59,19 @@ RegisterDialog::RegisterDialog(LoginData *loginData):
gcn::Label *userLabel = new Label(_("Name:"));
gcn::Label *passwordLabel = new Label(_("Password:"));
gcn::Label *confirmLabel = new Label(_("Confirm:"));
+#ifdef EATHENA_SUPPORT
gcn::Label *serverLabel = new Label(_("Server:"));
gcn::Label *portLabel = new Label(_("Port:"));
+#endif
mUserField = new TextField(loginData->username);
mPasswordField = new PasswordField(loginData->password);
mConfirmField = new PasswordField;
+#ifdef EATHENA_SUPPORT
mServerField = new TextField(loginData->hostname);
mPortField = new TextField(toString(loginData->port));
mMaleButton = new RadioButton(_("Male"), "sex", true);
mFemaleButton = new RadioButton(_("Female"), "sex", false);
+#endif
mRegisterButton = new Button(_("Register"), "register", this);
mCancelButton = new Button(_("Cancel"), "cancel", this);
@@ -91,15 +80,19 @@ RegisterDialog::RegisterDialog(LoginData *loginData):
place(0, 0, userLabel);
place(0, 1, passwordLabel);
place(0, 2, confirmLabel);
+#ifdef EATHENA_SUPPORT
place(1, 3, mMaleButton);
place(2, 3, mFemaleButton);
place(0, 4, serverLabel);
place(0, 5, portLabel);
+#endif
place(1, 0, mUserField, 3).setPadding(2);
place(1, 1, mPasswordField, 3).setPadding(2);
place(1, 2, mConfirmField, 3).setPadding(2);
+#ifdef EATHENA_SUPPORT
place(1, 4, mServerField, 3).setPadding(2);
place(1, 5, mPortField, 3).setPadding(2);
+#endif
place = getPlacer(0, 2);
place(1, 0, mRegisterButton);
place(2, 0, mCancelButton);
@@ -108,8 +101,10 @@ RegisterDialog::RegisterDialog(LoginData *loginData):
mUserField->addKeyListener(this);
mPasswordField->addKeyListener(this);
mConfirmField->addKeyListener(this);
+#ifdef EATHENA_SUPPORT
mServerField->addKeyListener(this);
mPortField->addKeyListener(this);
+#endif
/* TODO:
* This is a quick and dirty way to respond to the ENTER key, regardless of
@@ -119,16 +114,20 @@ RegisterDialog::RegisterDialog(LoginData *loginData):
mUserField->setActionEventId("register");
mPasswordField->setActionEventId("register");
mConfirmField->setActionEventId("register");
- mServerField->setActionEventId("register");
- mPortField->setActionEventId("register");
mUserField->addActionListener(this);
mPasswordField->addActionListener(this);
mConfirmField->addActionListener(this);
+
+#ifdef EATHENA_SUPPORT
+ mServerField->setActionEventId("register");
+ mPortField->setActionEventId("register");
+
mServerField->addActionListener(this);
mPortField->addActionListener(this);
+#endif
- setLocationRelativeTo(getParent());
+ center();
setVisible(true);
mUserField->requestFocus();
mUserField->setCaretPosition(mUserField->getText().length());
@@ -145,7 +144,7 @@ void RegisterDialog::action(const gcn::ActionEvent &event)
{
if (event.getId() == "cancel")
{
- state = LOGIN_STATE;
+ state = STATE_LOGIN;
}
else if (event.getId() == "register" && canSubmit())
{
@@ -194,6 +193,8 @@ void RegisterDialog::action(const gcn::ActionEvent &event)
error = 2;
}
+ // TODO: Check if a valid email address was given
+
if (error > 0)
{
if (error == 1)
@@ -209,23 +210,30 @@ void RegisterDialog::action(const gcn::ActionEvent &event)
mWrongDataNoticeListener->setTarget(this->mPasswordField);
}
- OkDialog *mWrongRegisterNotice =
- new OkDialog(_("Error"), errorMsg);
- mWrongRegisterNotice->addActionListener(mWrongDataNoticeListener);
+ OkDialog *dlg = new OkDialog(_("Error"), errorMsg);
+ dlg->addActionListener(mWrongDataNoticeListener);
}
else
{
// No errors detected, register the new user.
mRegisterButton->setEnabled(false);
- mLoginData->hostname = mServerField->getText();
- mLoginData->port = getUShort(mPortField->getText());
mLoginData->username = mUserField->getText();
mLoginData->password = mPasswordField->getText();
+#ifdef EATHENA_SUPPORT
+ mLoginData->hostname = mServerField->getText();
+ mLoginData->port = getUShort(mPortField->getText());
mLoginData->username += mFemaleButton->isSelected() ? "_F" : "_M";
+#else
+ mLoginData->email = mEmailField->getText();
+#endif
mLoginData->registerLogin = true;
- state = ACCOUNT_STATE;
+#ifdef TMWSERV_SUPPORT
+ state = STATE_REGISTER_ATTEMPT;
+#else
+ state = STATE_ACCOUNT;
+#endif
}
}
}
@@ -240,11 +248,14 @@ bool RegisterDialog::canSubmit() const
return !mUserField->getText().empty() &&
!mPasswordField->getText().empty() &&
!mConfirmField->getText().empty() &&
+#ifdef EATHENA_SUPPORT
!mServerField->getText().empty() &&
isUShort(mPortField->getText()) &&
- state == REGISTER_STATE;
+#endif
+ state == STATE_REGISTER;
}
+#ifdef EATHENA_SUPPORT
bool RegisterDialog::isUShort(const std::string &str)
{
if (str.empty())
@@ -278,3 +289,4 @@ unsigned short RegisterDialog::getUShort(const std::string &str)
}
return static_cast<unsigned short>(l);
}
+#endif
diff --git a/src/gui/register.h b/src/gui/register.h
index 922320db..c37305e4 100644
--- a/src/gui/register.h
+++ b/src/gui/register.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,7 +31,20 @@
class LoginData;
class OkDialog;
-class WrongDataNoticeListener;
+
+/**
+ * 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.
@@ -73,6 +85,7 @@ class RegisterDialog : public Window, public gcn::ActionListener,
*/
bool canSubmit() const;
+#ifdef EATHENA_SUPPORT
/**
* Function to decide whether string is an unsigned short or not
*
@@ -90,17 +103,24 @@ class RegisterDialog : public Window, public gcn::ActionListener,
* @return the value str represents
*/
static unsigned short getUShort(const std::string &str);
+#endif
gcn::TextField *mUserField;
gcn::TextField *mPasswordField;
gcn::TextField *mConfirmField;
+#ifdef EATHENA_SUPPORT
gcn::TextField *mServerField;
gcn::TextField *mPortField;
+#else
+ gcn::TextField *mEmailField;
+#endif
gcn::Button *mRegisterButton;
gcn::Button *mCancelButton;
+#ifdef EATHENA_SUPPORT
gcn::RadioButton *mMaleButton;
gcn::RadioButton *mFemaleButton;
+#endif
WrongDataNoticeListener *mWrongDataNoticeListener;
diff --git a/src/gui/scrollarea.cpp b/src/gui/scrollarea.cpp
index 156ff054..92bb94b8 100644
--- a/src/gui/scrollarea.cpp
+++ b/src/gui/scrollarea.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,18 +35,16 @@ ImageRect ScrollArea::background;
ImageRect ScrollArea::vMarker;
Image *ScrollArea::buttons[4][2];
-ScrollArea::ScrollArea(bool gc, bool opaque):
+ScrollArea::ScrollArea():
gcn::ScrollArea(),
- mOpaque(opaque),
- mGC(gc)
+ mOpaque(true)
{
init();
}
-ScrollArea::ScrollArea(gcn::Widget *widget, bool gc, bool opaque):
+ScrollArea::ScrollArea(gcn::Widget *widget):
gcn::ScrollArea(widget),
- mOpaque(opaque),
- mGC(gc)
+ mOpaque(true)
{
init();
}
@@ -55,8 +52,7 @@ ScrollArea::ScrollArea(gcn::Widget *widget, bool gc, bool opaque):
ScrollArea::~ScrollArea()
{
// Garbage collection
- if (mGC)
- delete getContent();
+ delete getContent();
instances--;
@@ -224,14 +220,13 @@ void ScrollArea::drawFrame(gcn::Graphics *graphics)
const int h = getHeight() + bs * 2;
static_cast<Graphics*>(graphics)->
- drawImageRect(0, 0, w, h, background);
+ drawImageRect(0, 0, w, h, background);
}
}
void ScrollArea::setOpaque(bool opaque)
{
mOpaque = opaque;
-
setFrameSize(mOpaque ? 2 : 0);
}
diff --git a/src/gui/scrollarea.h b/src/gui/scrollarea.h
index 080b851c..e9aa5ed2 100644
--- a/src/gui/scrollarea.h
+++ b/src/gui/scrollarea.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,6 +30,10 @@ class ImageRect;
/**
* A scroll area.
*
+ * Contrary to Guichan's scroll area, this scroll area takes ownership over its
+ * content. However, it won't delete a previously set content widget when
+ * setContent is called!
+ *
* \ingroup GUI
*/
class ScrollArea : public gcn::ScrollArea
@@ -39,12 +42,12 @@ class ScrollArea : public gcn::ScrollArea
/**
* Constructor.
*/
- ScrollArea(bool gc = true, bool opaque = true);
+ ScrollArea();
/**
* Constructor.
*/
- ScrollArea(gcn::Widget *content, bool gc = true, bool opaque = true);
+ ScrollArea(gcn::Widget *content);
/**
* Destructor.
@@ -107,7 +110,6 @@ class ScrollArea : public gcn::ScrollArea
static Image *buttons[4][2];
bool mOpaque;
- bool mGC;
};
#endif
diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp
index 591cf97b..e7671110 100644
--- a/src/gui/sell.cpp
+++ b/src/gui/sell.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,30 +19,44 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "button.h"
-#include "label.h"
-#include "scrollarea.h"
-#include "sell.h"
-#include "shop.h"
-#include "shoplistbox.h"
-#include "slider.h"
+#include "gui/sell.h"
-#include "widgets/layout.h"
+#include "gui/button.h"
+#include "gui/label.h"
+#include "gui/scrollarea.h"
+#include "gui/shop.h"
+#include "gui/shoplistbox.h"
+#include "gui/slider.h"
-#include "../npc.h"
+#include "gui/widgets/layout.h"
-#include "../net/messageout.h"
-#include "../net/protocol.h"
+#include "npc.h"
+#include "shopitem.h"
+#include "units.h"
-#include "../utils/gettext.h"
-#include "../utils/strprintf.h"
+#include "net/messageout.h"
+#ifdef TMWSERV_SUPPORT
+#include "net/tmwserv/gameserver/player.h"
+#else
+#include "net/ea/protocol.h"
+#endif
+#include "resources/iteminfo.h"
+
+#include "utils/gettext.h"
+#include "utils/strprintf.h"
+
+#ifdef TMWSERV_SUPPORT
+SellDialog::SellDialog():
+ Window(_("Sell")),
+#else
SellDialog::SellDialog(Network *network):
- Window("Sell"),
+ Window(_("Sell")),
mNetwork(network),
+#endif
mMaxItems(0), mAmountItems(0)
{
- setWindowName(_("Sell"));
+ setWindowName("Sell");
setResizable(true);
setCloseButton(true);
setMinWidth(260);
@@ -61,8 +74,8 @@ SellDialog::SellDialog(Network *network):
mQuantityLabel = new Label(strprintf("%d / %d", mAmountItems, mMaxItems));
mQuantityLabel->setAlignment(gcn::Graphics::CENTER);
- mMoneyLabel = new Label(
- strprintf(_("Price: %d GP / Total: %d GP"), 0, 0));
+ mMoneyLabel = new Label(strprintf(_("Price: %s / Total: %s"),
+ "", ""));
mIncreaseButton = new Button("+", "+", this);
mDecreaseButton = new Button("-", "-", this);
@@ -103,6 +116,7 @@ SellDialog::SellDialog(Network *network):
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
+ center();
loadWindowState();
}
@@ -122,6 +136,16 @@ void SellDialog::reset()
updateButtonsAndLabels();
}
+#ifdef TMWSERV_SUPPORT
+
+void SellDialog::addItem(int item, int amount, int price)
+{
+ mShopItems->addItem(item, amount, price);
+ mShopItemList->adjustSize();
+}
+
+#else
+
void SellDialog::addItem(const Item *item, int price)
{
if (!item)
@@ -133,6 +157,8 @@ void SellDialog::addItem(const Item *item, int price)
mShopItemList->adjustSize();
}
+#endif
+
void SellDialog::action(const gcn::ActionEvent &event)
{
if (event.getId() == "quit")
@@ -176,10 +202,14 @@ void SellDialog::action(const gcn::ActionEvent &event)
else if (event.getId() == "sell" && mAmountItems > 0
&& mAmountItems <= mMaxItems)
{
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::tradeWithNPC
+ (mShopItems->at(selectedItem)->getId(), mAmountItems);
+#else
// Attempt sell
MessageOut outMsg(mNetwork);
- ShopItem* item = mShopItems->at(selectedItem);
+ ShopItem *item = mShopItems->at(selectedItem);
int sellCount;
mPlayerMoney +=
mAmountItems * mShopItems->at(selectedItem)->getPrice();
@@ -194,6 +224,7 @@ void SellDialog::action(const gcn::ActionEvent &event)
mAmountItems -= sellCount;
outMsg.writeInt16(sellCount);
}
+#endif
mPlayerMoney +=
mAmountItems * mShopItems->at(selectedItem)->getPrice();
@@ -275,9 +306,16 @@ void SellDialog::updateButtonsAndLabels()
// Update the quantity and money labels
mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems));
- mMoneyLabel->setCaption
- (strprintf(_("Price: %d GP / Total: %d GP"),
- income, mPlayerMoney + income));
+ mMoneyLabel->setCaption(strprintf(_("Price: %s / Total: %s"),
+ Units::formatCurrency(income).c_str(),
+ Units::formatCurrency(mPlayerMoney + income).c_str()));
+}
+
+void SellDialog::logic()
+{
+ Window::logic();
+
+ if (!current_npc) setVisible(false);
}
void SellDialog::setVisible(bool visible)
diff --git a/src/gui/sell.h b/src/gui/sell.h
index 930f8bc1..b6388a1f 100644
--- a/src/gui/sell.h
+++ b/src/gui/sell.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,7 +30,9 @@
#include "window.h"
class Item;
+#ifdef EATHENA_SUPPORT
class Network;
+#endif
class ShopItems;
class ShopListBox;
@@ -48,7 +49,11 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener
*
* @see Window::Window
*/
+#ifdef TMWSERV_SUPPORT
+ SellDialog();
+#else
SellDialog(Network *network);
+#endif
/**
* Destructor
@@ -63,7 +68,11 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener
/**
* Adds an item to the inventory.
*/
+#ifdef TMWSERV_SUPPORT
+ void addItem(int item, int amount, int price);
+#else
void addItem(const Item *item, int price);
+#endif
/**
* Called when receiving actions from the widgets.
@@ -83,6 +92,11 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener
void setMoney(int amount);
/**
+ * Check for current NPC
+ */
+ void logic();
+
+ /**
* Sets the visibility of this window.
*/
void setVisible(bool visible);
@@ -97,7 +111,9 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener
*/
void updateButtonsAndLabels();
+#ifdef EATHENA_SUPPORT
Network *mNetwork;
+#endif
gcn::Button *mSellButton;
gcn::Button *mQuitButton;
gcn::Button *mAddMaxButton;
diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp
new file mode 100644
index 00000000..a57be06c
--- /dev/null
+++ b/src/gui/serverdialog.cpp
@@ -0,0 +1,214 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <cstdlib>
+#include <iostream>
+#include <string>
+
+#include <guichan/widgets/label.hpp>
+
+#include "serverdialog.h"
+
+#include "button.h"
+#include "listbox.h"
+#include "ok_dialog.h"
+#include "scrollarea.h"
+#include "textfield.h"
+
+#include "widgets/layout.h"
+
+#include "../configuration.h"
+#include "../log.h"
+#include "../logindata.h"
+#include "../main.h"
+
+#include "../utils/gettext.h"
+#include "../utils/stringutils.h"
+
+const short MAX_SERVERLIST = 5;
+
+int ServersListModel::getNumberOfElements()
+{
+ return servers.size();
+}
+
+std::string ServersListModel::getElementAt(int elementIndex)
+{
+ std::string myServer = "";
+ myServer = servers.at(elementIndex).serverName;
+ myServer += ":";
+ myServer += toString(servers.at(elementIndex).port);
+ return myServer;
+}
+
+void ServersListModel::addFirstElement(Server server)
+{
+ // Equivalent to push_front
+ std::vector<Server>::iterator MyIterator = servers.begin();
+ servers.insert(MyIterator, 1, server);
+}
+
+void ServersListModel::addElement(Server server)
+{
+ servers.push_back(server);
+}
+
+ServerDialog::ServerDialog(LoginData *loginData):
+ Window(_("Choose your server")), mLoginData(loginData)
+{
+ gcn::Label *serverLabel = new gcn::Label(_("Server:"));
+ gcn::Label *portLabel = new gcn::Label(_("Port:"));
+ mServerNameField = new TextField(mLoginData->hostname);
+ mPortField = new TextField(toString(mLoginData->port));
+
+ // Add the most used servers from config
+ mMostUsedServersListModel = new ServersListModel();
+ Server currentServer;
+ std::string currentConfig = "";
+ for (int i=0; i<=MAX_SERVERLIST; i++)
+ {
+ currentServer.serverName = "";
+ currentServer.port = 0;
+
+ currentConfig = "MostUsedServerName" + toString(i);
+ currentServer.serverName = config.getValue(currentConfig, "");
+
+ currentConfig = "MostUsedServerPort" + toString(i);
+ currentServer.port = (short)atoi(config.getValue(currentConfig, "").c_str());
+ if (!currentServer.serverName.empty() || currentServer.port != 0)
+ {
+ mMostUsedServersListModel->addElement(currentServer);
+ }
+ }
+
+ mMostUsedServersListBox = new ListBox(NULL);
+ mMostUsedServersListBox->setListModel(mMostUsedServersListModel);
+ mMostUsedServersScrollArea = new ScrollArea();
+ mMostUsedServersDropDown = new DropDown(mMostUsedServersListModel,
+ mMostUsedServersScrollArea, mMostUsedServersListBox);
+
+ mOkButton = new Button(_("Ok"), "connect", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+
+ mServerNameField->setActionEventId("connect");
+ mPortField->setActionEventId("connect");
+ mMostUsedServersDropDown->setActionEventId("changeSelection");
+
+ mServerNameField->addActionListener(this);
+ mPortField->addActionListener(this);
+ mMostUsedServersDropDown->addActionListener(this);
+
+ place(0, 0, serverLabel);
+ place(0, 1, portLabel);
+ place(1, 0, mServerNameField, 3).setPadding(2);
+ place(1, 1, mPortField, 3).setPadding(2);
+ place(0, 2, mMostUsedServersDropDown, 4).setPadding(2);
+ place(2, 3, mOkButton);
+ place(3, 3, mCancelButton);
+ reflowLayout(250, 0);
+
+ setLocationRelativeTo(getParent());
+ setVisible(true);
+
+ if (mServerNameField->getText().empty()) {
+ mServerNameField->requestFocus();
+ } else {
+ if (mPortField->getText().empty()) {
+ mPortField->requestFocus();
+ } else {
+ mOkButton->requestFocus();
+ }
+ }
+}
+
+ServerDialog::~ServerDialog()
+{
+ delete mMostUsedServersListModel;
+ delete mMostUsedServersScrollArea;
+}
+
+void
+ServerDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "ok")
+ {
+ // Give focus back to the server dialog.
+ mServerNameField->requestFocus();
+ }
+ else if (event.getId() == "changeSelection")
+ {
+ // Change the textField Values according to new selection
+ Server myServer = mMostUsedServersListModel->getServer
+ (mMostUsedServersListBox->getSelected());
+ mServerNameField->setText(myServer.serverName);
+ mPortField->setText(toString(myServer.port));
+ }
+ else if (event.getId() == "connect")
+ {
+ // Check login
+ if (mServerNameField->getText().empty() || mPortField->getText().empty())
+ {
+ OkDialog *dlg = new OkDialog(_("Error"),
+ _("Please type both the address and the port of a server."));
+ dlg->addActionListener(this);
+ }
+ else
+ {
+ mLoginData->hostname = mServerNameField->getText();
+ mLoginData->port = (short) atoi(mPortField->getText().c_str());
+ mOkButton->setEnabled(false);
+ mCancelButton->setEnabled(false);
+
+ // First, look if the entry is a new one.
+ Server currentServer;
+ bool newEntry = true;
+ for (int i = 0; i < mMostUsedServersListModel->getNumberOfElements(); i++)
+ {
+ currentServer = mMostUsedServersListModel->getServer(i);
+ if (currentServer.serverName == mLoginData->hostname &&
+ currentServer.port == mLoginData->port)
+ newEntry = false;
+ }
+ // Then, add it to config if it's really new
+ currentServer.serverName = mLoginData->hostname;
+ currentServer.port = mLoginData->port;
+ if (newEntry)
+ mMostUsedServersListModel->addFirstElement(currentServer);
+ // Write the entry in config
+ std::string currentConfig = "";
+ for (int i = 0; i < mMostUsedServersListModel->getNumberOfElements(); i++)
+ {
+ currentServer = mMostUsedServersListModel->getServer(i);
+
+ currentConfig = "MostUsedServerName" + toString(i);
+ config.setValue(currentConfig, currentServer.serverName);
+
+ currentConfig = "MostUsedServerPort" + toString(i);
+ config.setValue(currentConfig, toString(currentServer.port));
+ }
+ state = STATE_CONNECT_ACCOUNT;
+ }
+ }
+ else if (event.getId() == "cancel")
+ {
+ state = STATE_FORCE_QUIT;
+ }
+}
diff --git a/src/gui/serverdialog.h b/src/gui/serverdialog.h
new file mode 100644
index 00000000..492f5a2b
--- /dev/null
+++ b/src/gui/serverdialog.h
@@ -0,0 +1,123 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef SERVERDIALOG_H
+#define SERVERDIALOG_H
+
+#include <iosfwd>
+#include <vector>
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/listmodel.hpp>
+#include "./widgets/dropdown.h"
+
+#include "login.h"
+#include "window.h"
+
+#include "../guichanfwd.h"
+
+#include "../net/tmwserv/network.h"
+
+class LoginData;
+
+/**
+ * A server structure to keep pairs of servers and ports.
+ */
+struct Server {
+ Server():
+ port(0)
+ {}
+
+ std::string serverName;
+ short port;
+};
+
+/**
+ * Server and Port List Model
+ */
+class ServersListModel : public gcn::ListModel
+{
+ public:
+ /**
+ * Used to get number of line in the list
+ */
+ int getNumberOfElements();
+ /**
+ * Used to get an element from the list
+ */
+ std::string getElementAt(int elementIndex);
+ /**
+ * Used to get the corresponding Server struct
+ */
+ Server getServer(int elementIndex) { return servers[elementIndex]; };
+ /**
+ * Add an Element at the end of the server list
+ */
+ void addElement(Server server);
+ /**
+ * Add an Element at the beginning of the server list
+ */
+ void addFirstElement(Server server);
+
+ private:
+ std::vector<Server> servers;
+};
+
+/**
+ * The server choice dialog.
+ *
+ * \ingroup Interface
+ */
+class ServerDialog : public Window, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor
+ *
+ * @see Window::Window
+ */
+ ServerDialog(LoginData *loginData);
+
+ /**
+ * Destructor
+ */
+ ~ServerDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ private:
+ gcn::TextField *mServerNameField;
+ gcn::TextField *mPortField;
+ gcn::Button *mOkButton;
+ gcn::Button *mCancelButton;
+
+ DropDown *mMostUsedServersDropDown;
+ gcn::ListBox *mMostUsedServersListBox;
+ gcn::ScrollArea *mMostUsedServersScrollArea;
+ ServersListModel *mMostUsedServersListModel;
+
+ LoginData *mLoginData;
+};
+
+#endif
diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp
index ca6b4010..72dfbce5 100644
--- a/src/gui/setup.cpp
+++ b/src/gui/setup.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -51,7 +50,12 @@ extern Window *helpWindow;
extern Window *debugWindow;
extern Window *itemShortcutWindow;
extern Window *emoteShortcutWindow;
+#ifdef TMWSERV_SUPPORT
+extern Window *magicDialog;
+extern Window *guildWindow;
+#else
extern Window *storageWindow;
+#endif
Setup::Setup():
Window(_("Setup"))
@@ -108,7 +112,7 @@ Setup::Setup():
add(panel);
- setLocationRelativeTo(getParent());
+ center();
setInGame(false);
}
@@ -141,7 +145,9 @@ void Setup::action(const gcn::ActionEvent &event)
statusWindow->resetToDefaultSize();
buyDialog->resetToDefaultSize();
sellDialog->resetToDefaultSize();
+#ifdef EATHENA_SUPPORT
buySellDialog->resetToDefaultSize();
+#endif
inventoryWindow->resetToDefaultSize();
emoteWindow->resetToDefaultSize();
npcTextDialog->resetToDefaultSize();
@@ -154,7 +160,12 @@ void Setup::action(const gcn::ActionEvent &event)
debugWindow->resetToDefaultSize();
itemShortcutWindow->resetToDefaultSize();
emoteShortcutWindow->resetToDefaultSize();
+#ifdef TMWSERV_SUPPORT
+ magicDialog->resetToDefaultSize();
+ guildWindow->resetToDefaultSize();
+#else
storageWindow->resetToDefaultSize();
+#endif
}
}
diff --git a/src/gui/setup.h b/src/gui/setup.h
index 663bdfcb..4c387d34 100644
--- a/src/gui/setup.h
+++ b/src/gui/setup.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -63,7 +62,7 @@ class Setup : public Window, public gcn::ActionListener
private:
std::list<SetupTab*> mTabs;
- gcn::Button* mResetWindows;
+ gcn::Button *mResetWindows;
};
extern Setup* setupWindow;
diff --git a/src/gui/setup_audio.cpp b/src/gui/setup_audio.cpp
index 08eda848..28a80b3d 100644
--- a/src/gui/setup_audio.cpp
+++ b/src/gui/setup_audio.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -43,6 +42,7 @@ Setup_Audio::Setup_Audio():
mMusicSlider(new Slider(0, 128))
{
setOpaque(false);
+ setDimension(gcn::Rectangle(0, 0, 250, 200));
gcn::Label *sfxLabel = new Label(_("Sfx volume"));
gcn::Label *musicLabel = new Label(_("Music volume"));
diff --git a/src/gui/setup_audio.h b/src/gui/setup_audio.h
index aad16617..9e951895 100644
--- a/src/gui/setup_audio.h
+++ b/src/gui/setup_audio.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/setup_colors.cpp b/src/gui/setup_colors.cpp
index 108067f5..073bbc1a 100644
--- a/src/gui/setup_colors.cpp
+++ b/src/gui/setup_colors.cpp
@@ -2,7 +2,7 @@
* Configurable text colors
* Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net>
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -57,7 +57,7 @@ Setup_Colors::Setup_Colors() :
mScroll = new ScrollArea(mColorBox);
mScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
- mTextPreview = new TextPreview(&rawmsg);
+ mTextPreview = new TextPreview(rawmsg);
mPreview = new BrowserBox(BrowserBox::AUTO_WRAP);
mPreview->setOpaque(false);
@@ -83,7 +83,7 @@ Setup_Colors::Setup_Colors() :
mRedLabel = new Label(_("Red: "));
- mRedText = new TextField();
+ mRedText = new TextField;
mRedText->setWidth(40);
mRedText->setRange(0, 255);
mRedText->setNumeric(true);
@@ -99,7 +99,7 @@ Setup_Colors::Setup_Colors() :
mGreenLabel = new Label(_("Green: "));
- mGreenText = new TextField();
+ mGreenText = new TextField;
mGreenText->setWidth(40);
mGreenText->setRange(0, 255);
mGreenText->setNumeric(true);
@@ -115,7 +115,7 @@ Setup_Colors::Setup_Colors() :
mBlueLabel = new Label(_("Blue: "));
- mBlueText = new TextField();
+ mBlueText = new TextField;
mBlueText->setWidth(40);
mBlueText->setRange(0, 255);
mBlueText->setNumeric(true);
diff --git a/src/gui/setup_colors.h b/src/gui/setup_colors.h
index 00f77d57..52d3f727 100644
--- a/src/gui/setup_colors.h
+++ b/src/gui/setup_colors.h
@@ -2,7 +2,7 @@
* Configurable text colors
* Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net>
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/setup_joystick.cpp b/src/gui/setup_joystick.cpp
index 4d80e0dd..59a882c7 100644
--- a/src/gui/setup_joystick.cpp
+++ b/src/gui/setup_joystick.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/setup_joystick.h b/src/gui/setup_joystick.h
index ae888206..eba8a2cc 100644
--- a/src/gui/setup_joystick.h
+++ b/src/gui/setup_joystick.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/setup_keyboard.cpp b/src/gui/setup_keyboard.cpp
index 0f79e3c6..aba8cf35 100644
--- a/src/gui/setup_keyboard.cpp
+++ b/src/gui/setup_keyboard.cpp
@@ -1,9 +1,9 @@
/*
- * Aethyra
- * Copyright (C) 2007 The Mana World Development Team
+ * Custom keyboard shortcuts configuration
+ * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au>
+ * Copyright (C) 2009 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -69,7 +69,7 @@ class KeyListModel : public gcn::ListModel
};
Setup_Keyboard::Setup_Keyboard():
- mKeyListModel(new KeyListModel()),
+ mKeyListModel(new KeyListModel),
mKeyList(new ListBox(mKeyListModel)),
mKeySetting(false)
{
diff --git a/src/gui/setup_keyboard.h b/src/gui/setup_keyboard.h
index 5fa961ae..dee12135 100644
--- a/src/gui/setup_keyboard.h
+++ b/src/gui/setup_keyboard.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
- * Copyright (C) 2007 The Mana World Development Team
+ * Custom keyboard shortcuts configuration
+ * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au>
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/setup_players.cpp b/src/gui/setup_players.cpp
index 05748000..1451e71e 100644
--- a/src/gui/setup_players.cpp
+++ b/src/gui/setup_players.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -69,9 +68,9 @@ static const char *RELATION_NAMES[PlayerRelation::RELATIONS_NR] =
class PlayerRelationListModel : public gcn::ListModel
{
public:
- virtual ~PlayerRelationListModel(void) { }
+ virtual ~PlayerRelationListModel() { }
- virtual int getNumberOfElements(void)
+ virtual int getNumberOfElements()
{
return PlayerRelation::RELATIONS_NR;
}
@@ -87,30 +86,30 @@ public:
class PlayerTableModel : public TableModel
{
public:
- PlayerTableModel(void) :
+ PlayerTableModel() :
mPlayers(NULL)
{
playerRelationsUpdated();
}
- virtual ~PlayerTableModel(void)
+ virtual ~PlayerTableModel()
{
freeWidgets();
if (mPlayers)
delete mPlayers;
}
- virtual int getRows(void)
+ virtual int getRows()
{
return mPlayers->size();
}
- virtual int getColumns(void)
+ virtual int getColumns()
{
return COLUMNS_NR;
}
- virtual int getRowHeight(void)
+ virtual int getRowHeight()
{
return ROW_HEIGHT;
}
@@ -123,7 +122,7 @@ public:
return RELATION_CHOICE_COLUMN_WIDTH;
}
- virtual void playerRelationsUpdated(void)
+ virtual void playerRelationsUpdated()
{
signalBeforeUpdate();
@@ -139,10 +138,10 @@ public:
std::string name = (*player_names)[r];
gcn::Widget *widget = new Label(name);
mWidgets.push_back(widget);
- gcn::ListModel *playerRelation = new PlayerRelationListModel();
+ gcn::ListModel *playerRelation = new PlayerRelationListModel;
gcn::DropDown *choicebox = new DropDown(playerRelation,
- new ScrollArea(),
+ new ScrollArea,
new ListBox(playerRelation),
false);
choicebox->setSelected(player_relations.getRelation(name));
@@ -167,7 +166,7 @@ public:
return mWidgets[WIDGET_AT(row, column)];
}
- virtual void freeWidgets(void)
+ virtual void freeWidgets()
{
if (mPlayers)
delete mPlayers;
@@ -198,9 +197,9 @@ protected:
class IgnoreChoicesListModel : public gcn::ListModel
{
public:
- virtual ~IgnoreChoicesListModel(void) { }
+ virtual ~IgnoreChoicesListModel() { }
- virtual int getNumberOfElements(void)
+ virtual int getNumberOfElements()
{
return player_relations.getPlayerIgnoreStrategies()->size();
}
@@ -220,7 +219,7 @@ public:
Setup_Players::Setup_Players():
mPlayerTableTitleModel(new StaticTableModel(1, COLUMNS_NR)),
- mPlayerTableModel(new PlayerTableModel()),
+ mPlayerTableModel(new PlayerTableModel),
mPlayerTable(new GuiTable(mPlayerTableModel)),
mPlayerTitleTable(new GuiTable(mPlayerTableTitleModel)),
mPlayerScrollArea(new ScrollArea(mPlayerTable)),
@@ -240,8 +239,8 @@ Setup_Players::Setup_Players():
RELATION_CHOICE_COLUMN_WIDTH);
mPlayerTitleTable->setBackgroundColor(gcn::Color(0xbf, 0xbf, 0xbf));
- gcn::ListModel *ignoreChoices = new IgnoreChoicesListModel();
- mIgnoreActionChoicesBox = new DropDown(ignoreChoices, new ScrollArea(),
+ gcn::ListModel *ignoreChoices = new IgnoreChoicesListModel;
+ mIgnoreActionChoicesBox = new DropDown(ignoreChoices, new ScrollArea,
new ListBox(ignoreChoices), false);
for (int i = 0; i < COLUMNS_NR; i++)
@@ -294,7 +293,7 @@ Setup_Players::Setup_Players():
setDimension(gcn::Rectangle(0, 0, 325, 280));
}
-Setup_Players::~Setup_Players(void)
+Setup_Players::~Setup_Players()
{
player_relations.removeListener(this);
}
diff --git a/src/gui/setup_players.h b/src/gui/setup_players.h
index 23a994a0..72d81f71 100644
--- a/src/gui/setup_players.h
+++ b/src/gui/setup_players.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp
index e181f744..07f073db 100644
--- a/src/gui/setup_video.cpp
+++ b/src/gui/setup_video.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -109,6 +108,7 @@ Setup_Video::Setup_Video():
mFullScreenEnabled(config.getValue("screen", false)),
mOpenGLEnabled(config.getValue("opengl", false)),
mCustomCursorEnabled(config.getValue("customcursor", true)),
+ mVisibleNamesEnabled(config.getValue("visiblenames", 1)),
mParticleEffectsEnabled(config.getValue("particleeffects", true)),
mNameEnabled(config.getValue("showownname", false)),
mPickupChatEnabled(config.getValue("showpickupchat", true)),
@@ -121,8 +121,13 @@ Setup_Video::Setup_Video():
mFsCheckBox(new CheckBox(_("Full screen"), mFullScreenEnabled)),
mOpenGLCheckBox(new CheckBox(_("OpenGL"), mOpenGLEnabled)),
mCustomCursorCheckBox(new CheckBox(_("Custom cursor"), mCustomCursorEnabled)),
+ mVisibleNamesCheckBox(new CheckBox(_("Visible names"), mVisibleNamesEnabled)),
mParticleEffectsCheckBox(new CheckBox(_("Particle effects"), mParticleEffectsEnabled)),
mNameCheckBox(new CheckBox(_("Show name"), mNameEnabled)),
+ mPickupNotifyLabel(new Label(_("Show pickup notification"))),
+ mPickupChatCheckBox(new CheckBox(_("in chat"), mPickupChatEnabled)),
+ mPickupParticleCheckBox(new CheckBox(_("as particle"),
+ mPickupParticleEnabled)),
mSpeechSlider(new Slider(0, 3)),
mSpeechLabel(new Label("")),
mAlphaSlider(new Slider(0.2, 1.0)),
@@ -140,11 +145,7 @@ Setup_Video::Setup_Video():
mOverlayDetailField(new Label("")),
mParticleDetail(3 - (int) config.getValue("particleEmitterSkip", 1)),
mParticleDetailSlider(new Slider(0, 3)),
- mParticleDetailField(new Label("")),
- mPickupNotifyLabel(new Label(_("Show pickup notification"))),
- mPickupChatCheckBox(new CheckBox(_("in chat"), mPickupChatEnabled)),
- mPickupParticleCheckBox(new CheckBox(_("as particle"),
- mPickupParticleEnabled))
+ mParticleDetailField(new Label(""))
{
setOpaque(false);
@@ -176,6 +177,7 @@ Setup_Video::Setup_Video():
mModeList->setActionEventId("videomode");
mCustomCursorCheckBox->setActionEventId("customcursor");
+ mVisibleNamesCheckBox->setActionEventId("visiblenames");
mParticleEffectsCheckBox->setActionEventId("particleeffects");
mPickupChatCheckBox->setActionEventId("pickupchat");
mPickupParticleCheckBox->setActionEventId("pickupparticle");
@@ -195,6 +197,7 @@ Setup_Video::Setup_Video():
mModeList->addActionListener(this);
mCustomCursorCheckBox->addActionListener(this);
+ mVisibleNamesCheckBox->addActionListener(this);
mParticleEffectsCheckBox->addActionListener(this);
mPickupChatCheckBox->addActionListener(this);
mPickupParticleCheckBox->addActionListener(this);
@@ -275,7 +278,8 @@ Setup_Video::Setup_Video():
place(1, 0, mFsCheckBox, 2);
place(3, 0, mOpenGLCheckBox, 1);
place(1, 1, mCustomCursorCheckBox, 3);
- place(1, 2, mNameCheckBox, 3);
+ place(1, 2, mVisibleNamesCheckBox, 3);
+ place(3, 2, mNameCheckBox, 1);
place(1, 3, mParticleEffectsCheckBox, 3);
place(1, 4, mPickupNotifyLabel, 3);
place(1, 5, mPickupChatCheckBox, 1);
@@ -320,7 +324,7 @@ void Setup_Video::apply()
* See http://libsdl.org/cgi/docwiki.cgi/SDL_SetVideoMode
*/
-#ifdef WIN32
+#if defined(WIN32) || defined(__APPLE__)
// checks for opengl usage
if (!(config.getValue("opengl", false) == 1))
{
@@ -338,7 +342,7 @@ void Setup_Video::apply()
logger->error(error.str());
}
}
-#ifdef WIN32
+#if defined(WIN32) || defined(__APPLE__)
}
else
{
@@ -365,6 +369,7 @@ void Setup_Video::apply()
// We sync old and new values at apply time
mFullScreenEnabled = config.getValue("screen", false);
mCustomCursorEnabled = config.getValue("customcursor", true);
+ mVisibleNamesEnabled = config.getValue("visiblenames", 1);
mParticleEffectsEnabled = config.getValue("particleeffects", true);
mNameEnabled = config.getValue("showownname", false);
mSpeechMode = (int) config.getValue("speech", 3);
@@ -400,6 +405,7 @@ void Setup_Video::cancel()
mFsCheckBox->setSelected(mFullScreenEnabled);
mOpenGLCheckBox->setSelected(mOpenGLEnabled);
mCustomCursorCheckBox->setSelected(mCustomCursorEnabled);
+ mVisibleNamesCheckBox->setSelected(mVisibleNamesEnabled);
mParticleEffectsCheckBox->setSelected(mParticleEffectsEnabled);
mSpeechSlider->setValue(mSpeechMode);
mNameCheckBox->setSelected(mNameEnabled);
@@ -414,6 +420,7 @@ void Setup_Video::cancel()
config.setValue("screen", mFullScreenEnabled ? true : false);
config.setValue("customcursor", mCustomCursorEnabled ? true : false);
+ config.setValue("visiblenames", mVisibleNamesEnabled ? 1 : 0);
config.setValue("particleeffects", mParticleEffectsEnabled ? true : false);
config.setValue("speech", mSpeechMode);
config.setValue("showownname", mNameEnabled ? true : false);
@@ -450,6 +457,11 @@ void Setup_Video::action(const gcn::ActionEvent &event)
config.setValue("customcursor",
mCustomCursorCheckBox->isSelected() ? true : false);
}
+ else if (event.getId() == "visiblenames")
+ {
+ config.setValue("visiblenames",
+ mVisibleNamesCheckBox->isSelected() ? 1 : 0);
+ }
else if (event.getId() == "particleeffects")
{
config.setValue("particleeffects",
diff --git a/src/gui/setup_video.h b/src/gui/setup_video.h
index b491cf23..62b46646 100644
--- a/src/gui/setup_video.h
+++ b/src/gui/setup_video.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -43,14 +42,13 @@ class Setup_Video : public SetupTab, public gcn::ActionListener,
void keyPressed(gcn::KeyEvent &event);
private:
- void updateSliders(bool originalValues);
-
int updateSlider(gcn::Slider *slider, gcn::TextField *field,
const std::string &configName);
bool mFullScreenEnabled;
bool mOpenGLEnabled;
bool mCustomCursorEnabled;
+ bool mVisibleNamesEnabled;
bool mParticleEffectsEnabled;
bool mNameEnabled;
bool mPickupChatEnabled;
@@ -72,9 +70,14 @@ class Setup_Video : public SetupTab, public gcn::ActionListener,
gcn::CheckBox *mFsCheckBox;
gcn::CheckBox *mOpenGLCheckBox;
gcn::CheckBox *mCustomCursorCheckBox;
+ gcn::CheckBox *mVisibleNamesCheckBox;
gcn::CheckBox *mParticleEffectsCheckBox;
gcn::CheckBox *mNameCheckBox;
+ gcn::Label *mPickupNotifyLabel;
+ gcn::CheckBox *mPickupChatCheckBox;
+ gcn::CheckBox *mPickupParticleCheckBox;
+
gcn::Slider *mSpeechSlider;
gcn::Label *mSpeechLabel;
gcn::Slider *mAlphaSlider;
@@ -97,10 +100,6 @@ class Setup_Video : public SetupTab, public gcn::ActionListener,
int mParticleDetail;
gcn::Slider *mParticleDetailSlider;
gcn::Label *mParticleDetailField;
-
- gcn::Label *mPickupNotifyLabel;
- gcn::CheckBox *mPickupChatCheckBox;
- gcn::CheckBox *mPickupParticleCheckBox;
};
#endif
diff --git a/src/gui/setuptab.h b/src/gui/setuptab.h
index 7e1bc36f..3e0c51e2 100644
--- a/src/gui/setuptab.h
+++ b/src/gui/setuptab.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/shop.cpp b/src/gui/shop.cpp
index bd676bc0..4799ea42 100644
--- a/src/gui/shop.cpp
+++ b/src/gui/shop.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,9 +19,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "shop.h"
+#include "gui/shop.h"
-#include "../utils/dtor.h"
+#include "shopitem.h"
+
+#include "utils/dtor.h"
ShopItems::ShopItems(bool mergeDuplicates) :
mMergeDuplicates(mergeDuplicates)
@@ -44,9 +45,15 @@ std::string ShopItems::getElementAt(int i)
return mShopItems.at(i)->getDisplayName();
}
+void ShopItems::addItem(int id, int amount, int price)
+{
+ mShopItems.push_back(new ShopItem(-1, id, amount, price));
+}
+
+#ifdef EATHENA_SUPPORT
void ShopItems::addItem(int inventoryIndex, int id, int quantity, int price)
{
- ShopItem* item = 0;
+ ShopItem *item = 0;
if (mMergeDuplicates)
{
item = findItem(id);
@@ -62,13 +69,9 @@ void ShopItems::addItem(int inventoryIndex, int id, int quantity, int price)
mShopItems.push_back(item);
}
}
+#endif
-void ShopItems::addItem(int id, int price)
-{
- addItem(-1, id, 0, price);
-}
-
-ShopItem* ShopItems::at(int i) const
+ShopItem *ShopItems::at(int i) const
{
return mShopItems.at(i);
}
@@ -84,7 +87,7 @@ void ShopItems::clear()
mShopItems.clear();
}
-ShopItem* ShopItems::findItem(int id)
+ShopItem *ShopItems::findItem(int id)
{
ShopItem *item;
diff --git a/src/gui/shop.h b/src/gui/shop.h
index 118847f9..190ef655 100644
--- a/src/gui/shop.h
+++ b/src/gui/shop.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,15 +19,13 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _SHOP_H
-#define _SHOP_H
-
-#include <string>
-#include <vector>
+#ifndef SHOP_H
+#define SHOP_H
#include <guichan/listmodel.hpp>
-#include "../shopitem.h"
+#include <string>
+#include <vector>
class ShopItem;
@@ -45,18 +42,21 @@ class ShopItems : public gcn::ListModel
{
public:
/**
- * Constructor. Creates a new ShopItems instance.
+ * Constructor.
*
* @param mergeDuplicates lets the Shop look for duplicate entries and
* merges them to one item.
*/
ShopItems(bool mergeDuplicates = false);
+ ~ShopItems();
+
/**
- * Destructor.
+ * Adds an item to the list.
*/
- ~ShopItems();
+ void addItem(int id, int amount, int price);
+#ifdef EATHENA_SUPPORT
/**
* Adds an item to the list (used by sell dialog). Looks for
* duplicate entries, if mergeDuplicates was turned on.
@@ -67,20 +67,10 @@ class ShopItems : public gcn::ListModel
* @param price price of the item
*/
void addItem(int inventoryIndex, int id, int amount, int price);
-
- /**
- * Adds an item to the list (used by buy dialog). Looks for
- * duplicate entries, if mergeDuplicates was turned on.
- *
- * @param id the id of the item
- * @param price price of the item
- */
- void addItem(int id, int price);
+#endif
/**
* Returns the number of items in the shop.
- *
- * @return the number of items in the shop
*/
int getNumberOfElements();
@@ -94,7 +84,7 @@ class ShopItems : public gcn::ListModel
/**
* Returns the item number i in the shop.
*/
- ShopItem* at(int i) const;
+ ShopItem *at(int i) const;
/**
* Removes an element from the shop.
@@ -104,7 +94,7 @@ class ShopItems : public gcn::ListModel
void erase(int i);
/**
- * Clear the vector.
+ * Clears the list of items in the shop.
*/
void clear();
@@ -115,13 +105,13 @@ class ShopItems : public gcn::ListModel
*
* @return the item found or 0
*/
- ShopItem* findItem(int id);
+ ShopItem *findItem(int id);
- /** the shop storage */
+ /** The list of items in the shop. */
std::vector<ShopItem*> mShopItems;
- /** Look for duplicate entries on addition */
+ /** Look for duplicate entries on addition. */
bool mMergeDuplicates;
};
-#endif
+#endif // SHOP_H
diff --git a/src/gui/shoplistbox.cpp b/src/gui/shoplistbox.cpp
index 5c55069f..db39e82d 100644
--- a/src/gui/shoplistbox.cpp
+++ b/src/gui/shoplistbox.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,15 +19,16 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <guichan/font.hpp>
-#include <guichan/listmodel.hpp>
+#include "gui/palette.h"
+#include "gui/shop.h"
+#include "gui/shoplistbox.h"
-#include "palette.h"
-#include "shop.h"
-#include "shoplistbox.h"
+#include "configuration.h"
+#include "graphics.h"
+#include "shopitem.h"
-#include "../configuration.h"
-#include "../graphics.h"
+#include <guichan/font.hpp>
+#include <guichan/listmodel.hpp>
const int ITEM_ICON_SIZE = 32;
diff --git a/src/gui/shoplistbox.h b/src/gui/shoplistbox.h
index bed9902b..0b28b2f1 100644
--- a/src/gui/shoplistbox.h
+++ b/src/gui/shoplistbox.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -89,4 +88,4 @@ class ShopListBox : public ListBox
bool mPriceCheck;
};
-#endif
+#endif // SHOPLISTBOX_H
diff --git a/src/gui/shortcutcontainer.cpp b/src/gui/shortcutcontainer.cpp
index fcb33279..901095e5 100644
--- a/src/gui/shortcutcontainer.cpp
+++ b/src/gui/shortcutcontainer.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
- * Copyright 2007 The Mana World Development Team
+ * The Mana World
+ * Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/shortcutcontainer.h b/src/gui/shortcutcontainer.h
index 3f2e1c60..7b09fb96 100644
--- a/src/gui/shortcutcontainer.h
+++ b/src/gui/shortcutcontainer.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
- * Copyright 2007 The Mana World Development Team
+ * The Mana World
+ * Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,8 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef SHORTCUTCONTAINER_H__
-#define SHORTCUTCONTAINER_H__
+#ifndef SHORTCUTCONTAINER_H
+#define SHORTCUTCONTAINER_H
#include <guichan/mouselistener.hpp>
#include <guichan/widget.hpp>
diff --git a/src/gui/shortcutwindow.cpp b/src/gui/shortcutwindow.cpp
index 8342465a..dcc7f72e 100644
--- a/src/gui/shortcutwindow.cpp
+++ b/src/gui/shortcutwindow.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
- * Copyright 2007 The Mana World Development Team
+ * The Mana World
+ * Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/shortcutwindow.h b/src/gui/shortcutwindow.h
index d79fffd2..eae881ba 100644
--- a/src/gui/shortcutwindow.h
+++ b/src/gui/shortcutwindow.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
- * Copyright 2007 The Mana World Development Team
+ * The Mana World
+ * Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/skill.cpp b/src/gui/skill.cpp
index 9fbae7a6..39ccbb06 100644
--- a/src/gui/skill.cpp
+++ b/src/gui/skill.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -46,11 +45,14 @@ struct SkillInfo
bool modifiable;
};
-static const SkillInfo fakeSkillInfo = { _("???"), false };
+static const SkillInfo fakeSkillInfo = {
+ _("Mystery Skill"),
+ false
+};
std::vector<SkillInfo> skill_db;
-static void initSkillinfo(void);
+static void initSkillinfo();
class SkillGuiTableModel : public StaticTableModel
{
@@ -76,12 +78,12 @@ public:
return 35;
}
- virtual int getRowHeight(void)
+ virtual int getRowHeight()
{
return 12;
}
- virtual void update(void)
+ virtual void update()
{
mEntriesNr = mDialog->getSkills().size();
resize();
@@ -113,7 +115,6 @@ public:
}
}
-
private:
SkillDialog *mDialog;
int mEntriesNr;
@@ -132,7 +133,7 @@ SkillDialog::SkillDialog():
mTable->setActionEventId("skill");
mTable->addActionListener(this);
- setWindowName(_("Skills"));
+ setWindowName("Skills");
setCloseButton(true);
setDefaultSize(255, 260, ImageRect::CENTER);
@@ -155,7 +156,7 @@ SkillDialog::SkillDialog():
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
- setLocationRelativeTo(getParent());
+ center();
loadWindowState();
}
@@ -234,7 +235,7 @@ bool SkillDialog::hasSkill(int id)
void SkillDialog::addSkill(int id, int lvl, int mp)
{
- SKILL *tmp = new SKILL();
+ SKILL *tmp = new SKILL;
tmp->id = id;
tmp->lv = lvl;
tmp->sp = mp;
@@ -255,11 +256,11 @@ void SkillDialog::setSkill(int id, int lvl, int mp)
void SkillDialog::cleanList()
{
- for_each(mSkillList.begin(), mSkillList.end(), make_dtor(mSkillList));
+ delete_all(mSkillList);
mSkillList.clear();
}
-static void initSkillinfo(void)
+static void initSkillinfo()
{
SkillInfo emptySkillInfo = { "", false };
diff --git a/src/gui/skill.h b/src/gui/skill.h
index bcdd515c..0600d106 100644
--- a/src/gui/skill.h
+++ b/src/gui/skill.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -66,7 +65,7 @@ class SkillDialog : public Window, public gcn::ActionListener
void setSkill(int id, int lv, int sp);
void cleanList();
- const std::vector<SKILL*>& getSkills(void) const { return mSkillList; }
+ const std::vector<SKILL*>& getSkills() const { return mSkillList; }
private:
GuiTable *mTable;
diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp
new file mode 100644
index 00000000..e30299d4
--- /dev/null
+++ b/src/gui/skilldialog.cpp
@@ -0,0 +1,318 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <guichan/widgets/label.hpp>
+#include <guichan/widgets/container.hpp>
+#include <guichan/widgets/icon.hpp>
+
+#include "skilldialog.h"
+
+#include "icon.h"
+#include "button.h"
+#include "listbox.h"
+#include "scrollarea.h"
+#include "windowcontainer.h"
+#include "progressbar.h"
+
+#include "widgets/tabbedarea.h"
+
+#include "../localplayer.h"
+
+#include "../utils/dtor.h"
+#include "../utils/gettext.h"
+#include "../utils/stringutils.h"
+
+class Skill_Tab : public GCContainer, public gcn::ActionListener
+{
+ public:
+ /**
+ * The type of this skill tab
+ */
+ const std::string type;
+
+ /**
+ * Constructor
+ */
+ Skill_Tab(const std::string &type);
+
+ /**
+ * Update this tab
+ */
+ void update();
+
+ /**
+ * Called when receiving actions from widget.
+ */
+ void action(const gcn::ActionEvent &event) {}
+
+ private:
+ /**
+ * Update the information of a skill at
+ * the given index
+ */
+ void updateSkill(int index);
+
+ /**
+ * Gets the number of skills in this particular
+ * type of tab.
+ */
+ int getSkillNum();
+
+ /**
+ * Get the first enumeration of this skill tab's
+ * skill type.
+ */
+ int getSkillBegin();
+
+ /**
+ * Get the icon associated with the given index
+ */
+ Icon* getIcon(int index);
+
+ std::vector<Icon *> mSkillIcons;
+ std::vector<gcn::Label *> mSkillNameLabels;
+ std::vector<gcn::Label *> mSkillLevelLabels;
+ std::vector<gcn::Label *> mSkillExpLabels;
+ std::vector<ProgressBar *> mSkillProgress;
+};
+
+
+SkillDialog::SkillDialog():
+ Window(_("Skills"))
+{
+ setWindowName("Skills");
+ setCloseButton(true);
+ setDefaultSize(windowContainer->getWidth() - 280, 30, 275, 425);
+
+ TabbedArea *panel = new TabbedArea();
+ panel->setDimension(gcn::Rectangle(5, 5, 270, 420));
+
+ Skill_Tab *tab;
+
+ // Add each type of skill tab to the panel
+ tab = new Skill_Tab("Weapon");
+ panel->addTab(_("Weapons"), tab);
+ mTabs.push_back(tab);
+
+ tab = new Skill_Tab("Magic");
+ panel->addTab(_("Magic"), tab);
+ mTabs.push_back(tab);
+
+ tab = new Skill_Tab("Craft");
+ panel->addTab(_("Crafts"), tab);
+ mTabs.push_back(tab);
+
+ add(panel);
+
+ update();
+
+ setLocationRelativeTo(getParent());
+ loadWindowState();
+}
+
+SkillDialog::~SkillDialog()
+{
+ delete_all(mTabs);
+}
+
+void SkillDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "skill")
+ {
+ }
+ else if (event.getId() == "close")
+ {
+ setVisible(false);
+ }
+}
+
+void SkillDialog::draw(gcn::Graphics *g)
+{
+ update();
+
+ Window::draw(g);
+}
+
+void SkillDialog::update()
+{
+ for(std::list<Skill_Tab*>::const_iterator i = mTabs.begin();
+ i != mTabs.end(); ++i)
+ {
+ (*i)->update();
+ }
+}
+
+Skill_Tab::Skill_Tab(const std::string &type): type(type)
+{
+ setOpaque(false);
+ setDimension(gcn::Rectangle(0, 0, 270, 420));
+ int skillNum = getSkillNum();
+
+ mSkillIcons.resize(skillNum);
+ mSkillNameLabels.resize(skillNum);
+ mSkillLevelLabels.resize(skillNum);
+ mSkillExpLabels.resize(skillNum);
+ mSkillProgress.resize(skillNum);
+
+ // Set the initial positions of the skill information
+ for (int a=0; a < skillNum; a++)
+ {
+ mSkillIcons.at(a) = getIcon(a);
+ mSkillIcons.at(a)->setPosition(1, a*32);
+ add(mSkillIcons.at(a));
+
+ mSkillNameLabels.at(a) = new gcn::Label("");
+ mSkillNameLabels.at(a)->setPosition(35, a*32 );
+ add(mSkillNameLabels.at(a));
+
+ mSkillProgress.at(a) = new ProgressBar(0.0f, 200, 20, 150, 150, 150);
+ mSkillProgress.at(a)->setPosition(35, a*32 + 13);
+ add(mSkillProgress.at(a));
+
+ mSkillExpLabels.at(a) = new gcn::Label("");
+ mSkillExpLabels.at(a)->setPosition(45, a*32 + 16);
+ add(mSkillExpLabels.at(a));
+
+ mSkillLevelLabels.at(a) = new gcn::Label("");
+ mSkillLevelLabels.at(a)->setPosition(165, a*32);
+ add(mSkillLevelLabels.at(a));
+ }
+
+ update();
+
+}
+
+int Skill_Tab::getSkillNum()
+{
+ int skillNum = 0;
+
+ if (type == "Weapon")
+ {
+ skillNum = CHAR_SKILL_WEAPON_NB;
+ return skillNum;
+ }
+ else if (type == "Magic")
+ {
+ skillNum = CHAR_SKILL_MAGIC_NB;
+ return skillNum;
+ }
+ else if (type == "Craft")
+ {
+ skillNum = CHAR_SKILL_CRAFT_NB;
+ return skillNum;
+ }
+ else return skillNum;
+}
+
+int Skill_Tab::getSkillBegin()
+{
+ int skillBegin = 0;
+
+ if (type == "Weapon")
+ {
+ skillBegin = CHAR_SKILL_WEAPON_BEGIN - CHAR_SKILL_BEGIN;
+ return skillBegin;
+ }
+ else if (type == "Magic")
+ {
+ skillBegin = CHAR_SKILL_MAGIC_BEGIN - CHAR_SKILL_BEGIN;
+ return skillBegin;
+ }
+ else if (type == "Craft")
+ {
+ skillBegin = CHAR_SKILL_CRAFT_BEGIN - CHAR_SKILL_BEGIN;
+ return skillBegin;
+ }
+ else return skillBegin;
+}
+
+Icon* Skill_Tab::getIcon(int index)
+{
+ int skillBegin = getSkillBegin();
+ std::string icon = LocalPlayer::getSkillInfo(index + skillBegin).icon;
+ return new Icon(icon);
+}
+
+void Skill_Tab::updateSkill(int index)
+{
+ int skillBegin = getSkillBegin();
+
+ int baseLevel = player_node->getAttributeBase(index +
+ skillBegin +
+ CHAR_SKILL_BEGIN);
+
+ int effLevel = player_node->getAttributeEffective(index +
+ skillBegin +
+ CHAR_SKILL_BEGIN);
+ if(baseLevel <= 0)
+ {
+ mSkillProgress.at(index)->setVisible(false);
+ mSkillExpLabels.at(index)->setVisible(false);
+ mSkillLevelLabels.at(index)->setVisible(false);
+ mSkillNameLabels.at(index)->setVisible(false);
+ mSkillIcons.at(index)->setVisible(false);
+ }
+ else
+ {
+ mSkillProgress.at(index)->setVisible(true);
+ mSkillExpLabels.at(index)->setVisible(true);
+ mSkillLevelLabels.at(index)->setVisible(true);
+ mSkillNameLabels.at(index)->setVisible(true);
+ mSkillIcons.at(index)->setVisible(true);
+ std::string skillLevel("Lvl: " + toString(baseLevel));
+ if (effLevel < baseLevel)
+ {
+ skillLevel.append(" - " + toString(baseLevel - effLevel));
+ }
+ else if (effLevel > baseLevel)
+ {
+ skillLevel.append(" + " + toString(effLevel - baseLevel));
+ }
+ mSkillLevelLabels.at(index)->setCaption(skillLevel);
+
+ std::pair<int, int> exp = player_node->getExperience(index + skillBegin);
+ std::string sExp (toString(exp.first) + " / " + toString(exp.second));
+
+
+ mSkillNameLabels.at(index)->setCaption(LocalPlayer::getSkillInfo(index + skillBegin).name);
+ mSkillNameLabels.at(index)->adjustSize();
+ mSkillLevelLabels.at(index)->adjustSize();
+ mSkillExpLabels.at(index)->setCaption(sExp);
+ mSkillExpLabels.at(index)->adjustSize();
+ mSkillExpLabels.at(index)->setAlignment(gcn::Graphics::RIGHT);
+
+ // More intense red as exp grows
+ int color = 150 - (int)(150 * ((float) exp.first / exp.second));
+ mSkillProgress.at(index)->setColor(244, color, color);
+ mSkillProgress.at(index)->setProgress((float) exp.first / exp.second);
+ }
+}
+
+void Skill_Tab::update()
+{
+ int skillNum = getSkillNum();
+
+ // Update the skill information for reach skill
+ for (int a = 0; a < skillNum; a++)
+ {
+ updateSkill(a);
+ }
+}
diff --git a/src/gui/skilldialog.h b/src/gui/skilldialog.h
new file mode 100644
index 00000000..b79be800
--- /dev/null
+++ b/src/gui/skilldialog.h
@@ -0,0 +1,79 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef SKILL_H
+#define SKILL_H
+
+#include <vector>
+#include <list>
+
+#include <guichan/listmodel.hpp>
+#include <guichan/actionlistener.hpp>
+
+#include "window.h"
+#include "gccontainer.h"
+
+#include "../guichanfwd.h"
+
+class ProgressBar;
+class Icon;
+class Skill_Tab;
+
+/**
+ * The skill dialog.
+ *
+ * \ingroup Interface
+ */
+class SkillDialog : public Window, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ SkillDialog();
+
+ /**
+ * Destructor.
+ */
+ ~SkillDialog();
+
+ /**
+ * Called when receiving actions from widget.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Update the tabs in this dialog
+ */
+ void update();
+
+ /**
+ * Draw this window.
+ */
+ void draw(gcn::Graphics *g);
+
+ private:
+ std::list<Skill_Tab*> mTabs;
+};
+
+extern SkillDialog *skillDialog;
+
+#endif
diff --git a/src/gui/skin.cpp b/src/gui/skin.cpp
index 10b9885a..0d62fea5 100644
--- a/src/gui/skin.cpp
+++ b/src/gui/skin.cpp
@@ -34,7 +34,7 @@
#include "../utils/strprintf.h"
#include "../utils/xml.h"
-SkinLoader* skinLoader = NULL;
+SkinLoader *skinLoader = NULL;
ConfigListener *SkinLoader::skinConfigListener = NULL;
class SkinConfigListener : public ConfigListener
@@ -46,7 +46,7 @@ class SkinConfigListener : public ConfigListener
}
};
-Skin::Skin(ImageRect skin, Image* close, std::string filePath, std::string name):
+Skin::Skin(ImageRect skin, Image *close, std::string filePath, std::string name):
instances(0),
mFilePath(filePath),
mName(name),
@@ -88,7 +88,7 @@ int Skin::getMinHeight() const
border.grid[6]->getHeight();
}
-Skin* SkinLoader::load(const std::string &filename,
+Skin *SkinLoader::load(const std::string &filename,
const std::string &defaultPath)
{
std::string filePath = filename;
@@ -214,9 +214,9 @@ Skin* SkinLoader::load(const std::string &filename,
delete doc;
// Hard-coded for now until we update the above code to look for window buttons.
- Image* closeImage = resman->getImage("graphics/gui/close_button.png");
+ Image *closeImage = resman->getImage("graphics/gui/close_button.png");
- Skin* skin = new Skin(border, closeImage, filename);
+ Skin *skin = new Skin(border, closeImage, filename);
mSkins[filename] = skin;
diff --git a/src/gui/slider.cpp b/src/gui/slider.cpp
index a2df59a4..cc381c32 100644
--- a/src/gui/slider.cpp
+++ b/src/gui/slider.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/slider.h b/src/gui/slider.h
index 35d875db..56ea334a 100644
--- a/src/gui/slider.h
+++ b/src/gui/slider.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/speechbubble.cpp b/src/gui/speechbubble.cpp
index cd483c30..4fb3409c 100644
--- a/src/gui/speechbubble.cpp
+++ b/src/gui/speechbubble.cpp
@@ -1,9 +1,9 @@
/*
- * Aethyra
- * Copyright (C) 2008, The Legend of Mazzeroth Development Team
+ * Speech bubbles
+ * Copyright (C) 2008 The Legend of Mazzeroth Development Team
+ * Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Legend of Mazzeroth.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,18 +34,17 @@
#include "../utils/gettext.h"
SpeechBubble::SpeechBubble():
- Popup("Speech", "graphics/gui/speechbubble.xml"),
- mText("")
+ Popup("Speech", "graphics/gui/speechbubble.xml")
{
setContentSize(140, 46);
setMinWidth(29);
setMinHeight(29);
- mCaption = new gcn::Label("");
+ mCaption = new gcn::Label;
mCaption->setFont(boldFont);
mCaption->setPosition(5, 3);
- mSpeechBox = new TextBox();
+ mSpeechBox = new TextBox;
mSpeechBox->setEditable(false);
mSpeechBox->setOpaque(false);
mSpeechBox->setTextColor(&guiPalette->getColor(Palette::CHAT));
diff --git a/src/gui/speechbubble.h b/src/gui/speechbubble.h
index 9eb400fb..3eead884 100644
--- a/src/gui/speechbubble.h
+++ b/src/gui/speechbubble.h
@@ -1,9 +1,9 @@
/*
- * Aethyra
- * Copyright (C) 2008, The Legend of Mazzeroth Development Team
+ * Speech bubbles
+ * Copyright (C) 2008 The Legend of Mazzeroth Development Team
+ * Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Legend of Mazzeroth.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/status.cpp b/src/gui/status.cpp
index 8dd32039..2f95f1c8 100644
--- a/src/gui/status.cpp
+++ b/src/gui/status.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,6 +28,7 @@
#include "widgets/layout.h"
#include "../localplayer.h"
+#include "../units.h"
#include "../utils/gettext.h"
#include "../utils/strprintf.h"
@@ -36,9 +36,10 @@
StatusWindow::StatusWindow(LocalPlayer *player):
Window(player->getName()),
- mPlayer(player)
+ mPlayer(player),
+ mCurrency(0)
{
- setWindowName(_("Status"));
+ setWindowName("Status");
setCloseButton(true);
setDefaultSize(400, 345, ImageRect::CENTER);
@@ -48,7 +49,8 @@ StatusWindow::StatusWindow(LocalPlayer *player):
mLvlLabel = new Label(strprintf(_("Level: %d"), 0));
mJobLvlLabel = new Label(strprintf(_("Job: %d"), 0));
- mGpLabel = new Label(strprintf(_("Money: %d GP"), 0));
+ mGpLabel = new Label(strprintf(_("Money: %s"),
+ Units::formatCurrency(mCurrency).c_str()));
mHpLabel = new Label(_("HP:"));
mHpBar = new ProgressBar(1.0f, 80, 15, 0, 171, 34);
@@ -77,8 +79,11 @@ StatusWindow::StatusWindow(LocalPlayer *player):
mStatsDefenseLabel= new Label(_("Defense:"));
mStatsMagicAttackLabel = new Label(_("M.Attack:"));
mStatsMagicDefenseLabel = new Label(_("M.Defense:"));
+ // Gettext flag for next line: xgettext:no-c-format
mStatsAccuracyLabel = new Label(_("% Accuracy:"));
+ // Gettext flag for next line: xgettext:no-c-format
mStatsEvadeLabel = new Label(_("% Evade:"));
+ // Gettext flag for next line: xgettext:no-c-format
mStatsReflexLabel = new Label(_("% Reflex:"));
mStatsAttackPoints = new Label;
@@ -161,42 +166,26 @@ void StatusWindow::update()
{
// Status Part
// -----------
- mLvlLabel->setCaption(strprintf(_("Level: %d"), mPlayer->mLevel));
+ mLvlLabel->setCaption(strprintf(_("Level: %d"), mPlayer->getLevel()));
mLvlLabel->adjustSize();
mJobLvlLabel->setCaption(strprintf(_("Job: %d"), mPlayer->mJobLevel));
mJobLvlLabel->adjustSize();
- mGpLabel->setCaption(strprintf(_("Money: %d GP"), mPlayer->mGp));
- mGpLabel->adjustSize();
-
- mHpBar->setText(toString(mPlayer->mHp) +
- "/" + toString(mPlayer->mMaxHp));
-
- mMpBar->setText(toString(mPlayer->mMp) +
- "/" + toString(mPlayer->mMaxMp));
+ if (mCurrency != mPlayer->getMoney()) {
+ mCurrency = mPlayer->getMoney();
+ mGpLabel->setCaption(strprintf(_("Money: %s"),
+ Units::formatCurrency(mCurrency).c_str()));
+ mGpLabel->adjustSize();
+ }
- mXpBar->setText(toString(mPlayer->getXp()) +
- "/" + toString(mPlayer->mXpForNextLevel));
+ updateHPBar(mHpBar, true);
- mJobBar->setText(toString(mPlayer->mJobXp) +
- "/" + toString(mPlayer->mJobXpForNextLevel));
+ updateMPBar(mMpBar, true);
- // HP Bar coloration
- if (mPlayer->mHp < int(mPlayer->mMaxHp / 3))
- mHpBar->setColor(223, 32, 32); // Red
- else if (mPlayer->mHp < int((mPlayer->mMaxHp / 3) * 2))
- mHpBar->setColor(230, 171, 34); // Orange
- else
- mHpBar->setColor(0, 171, 34); // Green
+ updateXPBar(mXpBar, false);
- mHpBar->setProgress((float) mPlayer->mHp / (float) mPlayer->mMaxHp);
- mMpBar->setProgress((float) mPlayer->mMp / (float) mPlayer->mMaxMp);
-
- mXpBar->setProgress(
- (float) mPlayer->getXp() / (float) mPlayer->mXpForNextLevel);
- mJobBar->setProgress(
- (float) mPlayer->mJobXp / (float) mPlayer->mJobXpForNextLevel);
+ updateJobBar(mJobBar, false);
// Stats Part
// ----------
@@ -291,3 +280,84 @@ void StatusWindow::action(const gcn::ActionEvent &event)
player_node->raiseAttribute(LocalPlayer::LUK);
}
}
+
+void StatusWindow::updateHPBar(ProgressBar *bar, bool showMax)
+{
+ if (showMax)
+ bar->setText(toString(player_node->getHp()) +
+ "/" + toString(player_node->getMaxHp()));
+ else
+ bar->setText(toString(player_node->getHp()));
+
+ // HP Bar coloration
+ if (player_node->getHp() < player_node->getMaxHp() / 3)
+ {
+ bar->setColor(223, 32, 32); // Red
+ }
+ else if (player_node->getHp() < (player_node->getMaxHp() / 3) * 2)
+ {
+ bar->setColor(230, 171, 34); // Orange
+ }
+ else
+ {
+ bar->setColor(0, 171, 34); // Green
+ }
+
+ bar->setProgress((float) player_node->getHp() / (float) player_node->getMaxHp());
+}
+
+void StatusWindow::updateMPBar(ProgressBar *bar, bool showMax)
+{
+ if (showMax)
+ bar->setText(toString(player_node->mMp) +
+ "/" + toString(player_node->mMaxMp));
+ else
+ bar->setText(toString(player_node->mMp));
+
+
+ bar->setProgress((float) player_node->mMp / (float) player_node->mMaxMp);
+}
+
+void StatusWindow::updateXPBar(ProgressBar *bar, bool percent)
+{
+ if (player_node->mXpForNextLevel == 0) {
+ bar->setText(_("Max level"));
+ bar->setProgress(1.0);
+ } else {
+ if (percent)
+ {
+ float xp = (float) player_node->getXp() /
+ player_node->mXpForNextLevel;
+ bar->setText(toString((float) ((int) (xp * 10000.0f)) / 100.0f) +
+ "%");
+ }
+ else
+ bar->setText(toString(player_node->getXp()) +
+ "/" + toString(player_node->mXpForNextLevel));
+
+ bar->setProgress((float) player_node->getXp() /
+ (float) player_node->mXpForNextLevel);
+ }
+}
+
+void StatusWindow::updateJobBar(ProgressBar *bar, bool percent)
+{
+ if (player_node->mJobXpForNextLevel == 0) {
+ bar->setText(_("Max level"));
+ bar->setProgress(1.0);
+ } else {
+ if (percent)
+ {
+ float xp = (float) player_node->mJobXp /
+ player_node->mJobXpForNextLevel;
+ bar->setText(toString((float) ((int) (xp * 10000.0f)) / 100.0f) +
+ "%");
+ }
+ else
+ bar->setText(toString(player_node->mJobXp) +
+ "/" + toString(player_node->mJobXpForNextLevel));
+
+ bar->setProgress((float) player_node->mJobXp /
+ (float) player_node->mJobXpForNextLevel);
+ }
+}
diff --git a/src/gui/status.h b/src/gui/status.h
index 5056f631..1425fe12 100644
--- a/src/gui/status.h
+++ b/src/gui/status.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -58,6 +57,11 @@ class StatusWindow : public Window, public gcn::ActionListener
*/
void update();
+ static void updateHPBar(ProgressBar *bar, bool showMax = false);
+ static void updateMPBar(ProgressBar *bar, bool showMax = false);
+ static void updateXPBar(ProgressBar *bar, bool percent = true);
+ static void updateJobBar(ProgressBar *bar, bool percent = true);
+
private:
LocalPlayer *mPlayer;
@@ -66,6 +70,7 @@ class StatusWindow : public Window, public gcn::ActionListener
*/
gcn::Label *mLvlLabel, *mJobLvlLabel;
gcn::Label *mGpLabel;
+ int mCurrency;
gcn::Label *mHpLabel, *mMpLabel, *mXpLabel, *mJobLabel;
ProgressBar *mHpBar, *mMpBar;
ProgressBar *mXpBar, *mJobBar;
diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp
new file mode 100644
index 00000000..31b2da90
--- /dev/null
+++ b/src/gui/statuswindow.cpp
@@ -0,0 +1,376 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "statuswindow.h"
+
+#include <guichan/widgets/label.hpp>
+
+#include "button.h"
+#include "progressbar.h"
+#include "windowcontainer.h"
+
+#include "../localplayer.h"
+
+#include "../utils/strprintf.h"
+#include "../utils/stringutils.h"
+
+StatusWindow::StatusWindow(LocalPlayer *player):
+ Window(player->getName()),
+ mPlayer(player)
+{
+ setWindowName("Status");
+ setResizable(true);
+ setCloseButton(true);
+ setDefaultSize((windowContainer->getWidth() - 365) / 2,
+ (windowContainer->getHeight() - 255) / 2, 365, 275);
+ loadWindowState();
+
+ // ----------------------
+ // Status Part
+ // ----------------------
+
+ mLvlLabel = new gcn::Label("Level:");
+ mMoneyLabel = new gcn::Label("Money:");
+
+ mHpLabel = new gcn::Label("HP:");
+ mHpBar = new ProgressBar(1.0f, 80, 15, 0, 171, 34);
+ mHpValueLabel = new gcn::Label("");
+
+ int y = 3;
+ int x = 5;
+
+ mLvlLabel->setPosition(x, y);
+ x += mLvlLabel->getWidth() + 40;
+ mMoneyLabel->setPosition(x, y);
+
+ y += mLvlLabel->getHeight() + 5; // Next Row
+ x = 5;
+
+ mHpLabel->setPosition(x, y);
+ x += mHpLabel->getWidth() + 5;
+ mHpBar->setPosition(x, y);
+ x += mHpBar->getWidth() + 5;
+ mHpValueLabel->setPosition(x, y);
+
+ y += mHpLabel->getHeight() + 5; // Next Row
+ x = 5;
+
+ add(mLvlLabel);
+ add(mMoneyLabel);
+ add(mHpLabel);
+ add(mHpValueLabel);
+ add(mHpBar);
+
+ // ----------------------
+ // Stats Part
+ // ----------------------
+
+ // Static Labels
+ gcn::Label *mStatsTitleLabel = new gcn::Label("Stats");
+ gcn::Label *mStatsTotalLabel = new gcn::Label("Total");
+
+ // Derived Stats
+/*
+ mStatsAttackLabel = new gcn::Label("Attack:");
+ mStatsDefenseLabel= new gcn::Label("Defense:");
+ mStatsMagicAttackLabel = new gcn::Label("M.Attack:");
+ mStatsMagicDefenseLabel = new gcn::Label("M.Defense:");
+ mStatsAccuracyLabel = new gcn::Label("% Accuracy:");
+ mStatsEvadeLabel = new gcn::Label("% Evade:");
+ mStatsReflexLabel = new gcn::Label("% Reflex:");
+
+ mStatsAttackPoints = new gcn::Label("");
+ mStatsDefensePoints = new gcn::Label("");
+ mStatsMagicAttackPoints = new gcn::Label("");
+ mStatsMagicDefensePoints = new gcn::Label("");
+ mStatsAccuracyPoints = new gcn::Label("% Accuracy:");
+ mStatsEvadePoints = new gcn::Label("% Evade:");
+ mStatsReflexPoints = new gcn::Label("% Reflex:");
+*/
+ // New labels
+ for (int i = 0; i < 6; i++) {
+ mStatsLabel[i] = new gcn::Label();
+ mStatsDisplayLabel[i] = new gcn::Label();
+ }
+ mCharacterPointsLabel = new gcn::Label();
+ mCorrectionPointsLabel = new gcn::Label();
+
+ // Set button events Id
+ mStatsPlus[0] = new Button("+", "STR+", this);
+ mStatsPlus[1] = new Button("+", "AGI+", this);
+ mStatsPlus[2] = new Button("+", "DEX+", this);
+ mStatsPlus[3] = new Button("+", "VIT+", this);
+ mStatsPlus[4] = new Button("+", "INT+", this);
+ mStatsPlus[5] = new Button("+", "WIL+", this);
+
+ mStatsMinus[0] = new Button("-", "STR-", this);
+ mStatsMinus[1] = new Button("-", "AGI-", this);
+ mStatsMinus[2] = new Button("-", "DEX-", this);
+ mStatsMinus[3] = new Button("-", "VIT-", this);
+ mStatsMinus[4] = new Button("-", "INT-", this);
+ mStatsMinus[5] = new Button("-", "WIL-", this);
+
+
+
+ // Set position
+ mStatsTitleLabel->setPosition(mHpLabel->getX(), mHpLabel->getY() + 23 );
+ mStatsTotalLabel->setPosition(110, mStatsTitleLabel->getY() + 15);
+ int totalLabelY = mStatsTotalLabel->getY();
+
+ for (int i = 0; i < 6; i++)
+ {
+ mStatsLabel[i]->setPosition(5,
+ mStatsTotalLabel->getY() + (i * 23) + 15);
+ mStatsMinus[i]->setPosition(85, totalLabelY + (i * 23) + 15);
+ mStatsDisplayLabel[i]->setPosition(125,
+ totalLabelY + (i * 23) + 15);
+ mStatsPlus[i]->setPosition(185, totalLabelY + (i * 23) + 15);
+ }
+
+ mCharacterPointsLabel->setPosition(5, mStatsDisplayLabel[5]->getY() + 25);
+ mCorrectionPointsLabel->setPosition(5, mStatsDisplayLabel[5]->getY() + 35);
+/*
+ mStatsAttackLabel->setPosition(220, mStatsLabel[0]->getY());
+ mStatsDefenseLabel->setPosition(220, mStatsLabel[1]->getY());
+ mStatsMagicAttackLabel->setPosition(220, mStatsLabel[2]->getY());
+ mStatsMagicDefenseLabel->setPosition(220, mStatsLabel[3]->getY());
+ mStatsAccuracyLabel->setPosition(220, mStatsLabel[4]->getY());
+ mStatsEvadeLabel->setPosition(220, mStatsLabel[5]->getY());
+ mStatsReflexLabel->setPosition(220, mStatsLabel[6]->getY());
+
+ mStatsAttackPoints->setPosition(310, mStatsLabel[0]->getY());
+ mStatsDefensePoints->setPosition(310, mStatsLabel[1]->getY());
+ mStatsMagicAttackPoints->setPosition(310, mStatsLabel[2]->getY());
+ mStatsMagicDefensePoints->setPosition(310, mStatsLabel[3]->getY());
+ mStatsAccuracyPoints->setPosition(310, mStatsLabel[4]->getY());
+ mStatsEvadePoints->setPosition(310, mStatsLabel[5]->getY());
+ mStatsReflexPoints->setPosition(310, mStatsLabel[6]->getY());
+*/
+ // Assemble
+ add(mStatsTitleLabel);
+ add(mStatsTotalLabel);
+ for(int i = 0; i < 6; i++)
+ {
+ add(mStatsLabel[i]);
+ add(mStatsDisplayLabel[i]);
+ add(mStatsPlus[i]);
+ add(mStatsMinus[i]);
+ }/*
+ add(mStatsAttackLabel);
+ add(mStatsDefenseLabel);
+ add(mStatsMagicAttackLabel);
+ add(mStatsMagicDefenseLabel);
+ add(mStatsAccuracyLabel);
+ add(mStatsEvadeLabel);
+ add(mStatsReflexLabel);
+
+ add(mStatsAttackPoints);
+ add(mStatsDefensePoints);
+ add(mStatsMagicAttackPoints);
+ add(mStatsMagicDefensePoints);
+ add(mStatsAccuracyPoints);
+ add(mStatsEvadePoints);
+ add(mStatsReflexPoints);*/
+
+ add(mCharacterPointsLabel);
+ add(mCorrectionPointsLabel);
+}
+
+void StatusWindow::update()
+{
+ // Status Part
+ // -----------
+ mLvlLabel->setCaption( "Level: " +
+ toString(mPlayer->getLevel()) +
+ " (" +
+ toString(mPlayer->getLevelProgress()) +
+ "%)");
+ mLvlLabel->adjustSize();
+
+ mMoneyLabel->setCaption("Money: " + toString(mPlayer->getMoney()) + " GP");
+ mMoneyLabel->adjustSize();
+
+ updateHPBar(mHpBar, true);
+
+ // Stats Part
+ // ----------
+ const std::string attrNames[6] = {
+ "Strength",
+ "Agility",
+ "Dexterity",
+ "Vitality",
+ "Intelligence",
+ "Willpower"
+ };
+ int characterPoints = mPlayer->getCharacterPoints();
+ int correctionPoints = mPlayer->getCorrectionPoints();
+ // Update labels
+ for (int i = 0; i < 6; i++)
+ {
+ mStatsLabel[i]->setCaption(attrNames[i]);
+ mStatsDisplayLabel[i]->setCaption(
+ strprintf("%d / %d",
+ mPlayer->getAttributeEffective(CHAR_ATTR_BEGIN + i),
+ mPlayer->getAttributeBase(CHAR_ATTR_BEGIN + i)));
+
+ mStatsLabel[i]->adjustSize();
+ mStatsDisplayLabel[i]->adjustSize();
+
+ mStatsPlus[i]->setEnabled(characterPoints);
+ mStatsMinus[i]->setEnabled(correctionPoints);
+ }
+ mCharacterPointsLabel->setCaption("Character Points: " +
+ toString(characterPoints));
+ mCharacterPointsLabel->adjustSize();
+
+ mCorrectionPointsLabel->setCaption("Correction Points: " +
+ toString(correctionPoints));
+ mCorrectionPointsLabel->adjustSize();
+/*
+ // Derived Stats Points
+
+ // Attack TODO: Count equipped Weapons and items attack bonuses
+ mStatsAttackPoints->setCaption(
+ toString(mPlayer->ATK + mPlayer->ATK_BONUS));
+ mStatsAttackPoints->adjustSize();
+
+ // Defense TODO: Count equipped Armors and items defense bonuses
+ mStatsDefensePoints->setCaption(
+ toString(mPlayer->DEF + mPlayer->DEF_BONUS));
+ mStatsDefensePoints->adjustSize();
+
+ // Magic Attack TODO: Count equipped items M.Attack bonuses
+ mStatsMagicAttackPoints->setCaption(
+ toString(mPlayer->MATK + mPlayer->MATK_BONUS));
+ mStatsMagicAttackPoints->adjustSize();
+
+ // Magic Defense TODO: Count equipped items M.Defense bonuses
+ mStatsMagicDefensePoints->setCaption(
+ toString(mPlayer->MDEF + mPlayer->MDEF_BONUS));
+ mStatsMagicDefensePoints->adjustSize();
+
+ // Accuracy %
+ mStatsAccuracyPoints->setCaption(toString(mPlayer->HIT));
+ mStatsAccuracyPoints->adjustSize();
+
+ // Evasion %
+ mStatsEvadePoints->setCaption(toString(mPlayer->FLEE));
+ mStatsEvadePoints->adjustSize();
+
+ // Reflex %
+ mStatsReflexPoints->setCaption(toString(mPlayer->DEX / 4)); // + counter
+ mStatsReflexPoints->adjustSize();
+*/
+ // Update Second column widgets position
+ mMoneyLabel->setPosition(mLvlLabel->getX() + mLvlLabel->getWidth() + 20,
+ mLvlLabel->getY());
+
+}
+
+void StatusWindow::draw(gcn::Graphics *g)
+{
+ update();
+
+ Window::draw(g);
+}
+
+void StatusWindow::action(const gcn::ActionEvent &event)
+{
+ const std::string &eventId = event.getId();
+
+ // Stats Part
+ if (eventId == "STR+")
+ {
+ mPlayer->raiseAttribute(LocalPlayer::STR);
+ }
+ else if (eventId == "AGI+")
+ {
+ mPlayer->raiseAttribute(LocalPlayer::AGI);
+ }
+ else if (eventId == "DEX+")
+ {
+ mPlayer->raiseAttribute(LocalPlayer::DEX);
+ }
+ else if (eventId == "VIT+")
+ {
+ mPlayer->raiseAttribute(LocalPlayer::VIT);
+ }
+ else if (eventId == "INT+")
+ {
+ mPlayer->raiseAttribute(LocalPlayer::INT);
+ }
+ else if (eventId == "WIL+")
+ {
+ mPlayer->raiseAttribute(LocalPlayer::WIL);
+ }
+
+ else if (eventId == "STR-")
+ {
+ mPlayer->lowerAttribute(LocalPlayer::STR);
+ }
+ else if (eventId == "AGI-")
+ {
+ mPlayer->lowerAttribute(LocalPlayer::AGI);
+ }
+ else if (eventId == "DEX-")
+ {
+ mPlayer->lowerAttribute(LocalPlayer::DEX);
+ }
+ else if (eventId == "VIT-")
+ {
+ mPlayer->lowerAttribute(LocalPlayer::VIT);
+ }
+ else if (eventId == "INT-")
+ {
+ mPlayer->lowerAttribute(LocalPlayer::INT);
+ }
+ else if (eventId == "WIL-")
+ {
+ mPlayer->lowerAttribute(LocalPlayer::WIL);
+ }
+}
+
+// WARNING: Duplicated method!
+
+void StatusWindow::updateHPBar(ProgressBar *bar, bool showMax)
+{
+ if (showMax)
+ bar->setText(toString(player_node->getHp()) +
+ "/" + toString(player_node->getMaxHp()));
+ else
+ bar->setText(toString(player_node->getHp()));
+
+ // HP Bar coloration
+ if (player_node->getHp() < player_node->getMaxHp() / 3)
+ {
+ bar->setColor(223, 32, 32); // Red
+ }
+ else if (player_node->getHp() < (player_node->getMaxHp() / 3) * 2)
+ {
+ bar->setColor(230, 171, 34); // Orange
+ }
+ else
+ {
+ bar->setColor(0, 171, 34); // Green
+ }
+
+ bar->setProgress((float) player_node->getHp() / (float) player_node->getMaxHp());
+}
diff --git a/src/gui/statuswindow.h b/src/gui/statuswindow.h
new file mode 100644
index 00000000..605145d3
--- /dev/null
+++ b/src/gui/statuswindow.h
@@ -0,0 +1,107 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef STATUS_H
+#define STATUS_H
+
+#include <iosfwd>
+
+#include <guichan/actionlistener.hpp>
+
+#include "window.h"
+
+#include "../guichanfwd.h"
+
+class LocalPlayer;
+class ProgressBar;
+
+
+/**
+ * The player status dialog.
+ *
+ * \ingroup Interface
+ */
+class StatusWindow : public Window, public gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ StatusWindow(LocalPlayer *player);
+
+ /**
+ * Called when receiving actions from widget.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Draw this window
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Updates this dialog with values from PLAYER_INFO *char_info
+ */
+ void update();
+
+ static void updateHPBar(ProgressBar *bar, bool showMax = false);
+
+ private:
+ LocalPlayer *mPlayer;
+
+ /**
+ * Status Part
+ */
+ gcn::Label *mLvlLabel, *mMoneyLabel, *mHpLabel, *mHpValueLabel;
+ ProgressBar *mHpBar;
+
+ /**
+ * Derived Statistics captions
+ */
+/*
+ gcn::Label *mStatsAttackLabel, *mStatsDefenseLabel;
+ gcn::Label *mStatsMagicAttackLabel, *mStatsMagicDefenseLabel;
+ gcn::Label *mStatsAccuracyLabel, *mStatsEvadeLabel;
+ gcn::Label *mStatsReflexLabel;
+
+ gcn::Label *mStatsAttackPoints, *mStatsDefensePoints;
+ gcn::Label *mStatsMagicAttackPoints, *mStatsMagicDefensePoints;
+ gcn::Label *mStatsAccuracyPoints, *mStatsEvadePoints;
+ gcn::Label *mStatsReflexPoints;
+*/
+ /**
+ * Stats captions.
+ */
+ gcn::Label *mStatsLabel[6];
+ gcn::Label *mStatsDisplayLabel[6];
+ gcn::Label *mCharacterPointsLabel;
+ gcn::Label *mCorrectionPointsLabel;
+
+ /**
+ * Stats buttons.
+ */
+ gcn::Button *mStatsPlus[6];
+ gcn::Button *mStatsMinus[6];
+};
+
+extern StatusWindow *statusWindow;
+
+#endif
diff --git a/src/gui/storagewindow.cpp b/src/gui/storagewindow.cpp
index eb0cbc12..479348aa 100644
--- a/src/gui/storagewindow.cpp
+++ b/src/gui/storagewindow.cpp
@@ -39,10 +39,12 @@
#include "../inventory.h"
#include "../item.h"
#include "../localplayer.h"
+#include "../units.h"
#include "../net/messageout.h"
-#include "../net/network.h"
-#include "../net/protocol.h"
+#ifdef EATHENA_SUPPORT
+#include "../net/ea/protocol.h"
+#endif
#include "../resources/iteminfo.h"
@@ -65,7 +67,7 @@ StorageWindow::StorageWindow(Network *network, int invSize):
mStoreButton = new Button(_("Store"), "store", this);
mRetrieveButton = new Button(_("Retrieve"), "retrieve", this);
- mItems = new ItemContainer(player_node->getStorage(), 1);
+ mItems = new ItemContainer(player_node->getStorage(), 10, 5, 1);
mItems->addSelectionListener(this);
mInvenScroll = new ScrollArea(mItems);
diff --git a/src/gui/storagewindow.h b/src/gui/storagewindow.h
index 6a1c2cdb..cc0df2af 100644
--- a/src/gui/storagewindow.h
+++ b/src/gui/storagewindow.h
@@ -40,7 +40,8 @@ class TextBox;
*
* \ingroup Interface
*/
-class StorageWindow : public Window, gcn::ActionListener, gcn::SelectionListener
+class StorageWindow : public Window, gcn::ActionListener,
+ gcn::SelectionListener
{
public:
/**
diff --git a/src/gui/table.cpp b/src/gui/table.cpp
index 17d8bfbf..ec5b0480 100644
--- a/src/gui/table.cpp
+++ b/src/gui/table.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra derived from original code
- * from Guichan.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -38,7 +37,7 @@ class GuiTableActionListener : public gcn::ActionListener
public:
GuiTableActionListener(GuiTable *_table, gcn::Widget *_widget, int _row, int _column);
- virtual ~GuiTableActionListener(void);
+ virtual ~GuiTableActionListener();
virtual void action(const gcn::ActionEvent& actionEvent);
@@ -63,7 +62,7 @@ GuiTableActionListener::GuiTableActionListener(GuiTable *table, gcn::Widget *wid
}
}
-GuiTableActionListener::~GuiTableActionListener(void)
+GuiTableActionListener::~GuiTableActionListener()
{
if (mWidget)
{
@@ -97,13 +96,13 @@ GuiTable::GuiTable(TableModel *initial_model, gcn::Color background,
addKeyListener(this);
}
-GuiTable::~GuiTable(void)
+GuiTable::~GuiTable()
{
uninstallActionListeners();
delete mModel;
}
-TableModel* GuiTable::getModel(void) const
+TableModel *GuiTable::getModel() const
{
return mModel;
}
@@ -126,7 +125,7 @@ void GuiTable::setModel(TableModel *new_model)
}
}
-void GuiTable::recomputeDimensions(void)
+void GuiTable::recomputeDimensions()
{
int rows_nr = mModel->getRows();
int columns_nr = mModel->getColumns();
@@ -154,12 +153,12 @@ void GuiTable::setSelected(int row, int column)
mSelectedRow = row;
}
-int GuiTable::getSelectedRow(void)
+int GuiTable::getSelectedRow()
{
return mSelectedRow;
}
-int GuiTable::getSelectedColumn(void)
+int GuiTable::getSelectedColumn()
{
return mSelectedColumn;
}
@@ -169,7 +168,7 @@ void GuiTable::setLinewiseSelection(bool linewise)
mLinewiseMode = linewise;
}
-int GuiTable::getRowHeight(void)
+int GuiTable::getRowHeight()
{
if (mModel)
return mModel->getRowHeight() + 1; // border
@@ -201,7 +200,7 @@ void GuiTable::setSelectedRow(int selected)
{
mSelectedRow = 0;
}
- else if ((selected >= mModel->getRows() && !mWrappingEnabled) ||
+ else if ((selected >= mModel->getRows() && !mWrappingEnabled) ||
(selected < 0 && mWrappingEnabled))
{
mSelectedRow = mModel->getRows() - 1;
@@ -226,7 +225,7 @@ void GuiTable::setSelectedColumn(int selected)
{
mSelectedColumn = 0;
}
- else if ((selected >= mModel->getColumns() && !mWrappingEnabled) ||
+ else if ((selected >= mModel->getColumns() && !mWrappingEnabled) ||
(selected < 0 && mWrappingEnabled))
{
mSelectedColumn = mModel->getColumns() - 1;
@@ -240,11 +239,11 @@ void GuiTable::setSelectedColumn(int selected)
void GuiTable::uninstallActionListeners(void)
{
- delete_all(action_listeners);
- action_listeners.clear();
+ delete_all(mActionListeners);
+ mActionListeners.clear();
}
-void GuiTable::installActionListeners(void)
+void GuiTable::installActionListeners()
{
if (!mModel)
return;
@@ -256,7 +255,7 @@ void GuiTable::installActionListeners(void)
for (int column = 0; column < columns; ++column)
{
gcn::Widget *widget = mModel->getElementAt(row, column);
- action_listeners.push_back(new GuiTableActionListener(this, widget,
+ mActionListeners.push_back(new GuiTableActionListener(this, widget,
row, column));
}
@@ -290,7 +289,7 @@ void GuiTable::draw(gcn::Graphics* graphics)
int max_rows_nr = mModel->getRows() - first_row; // clip if neccessary:
if (max_rows_nr < rows_nr)
rows_nr = max_rows_nr;
-
+
// Now determine the first and last column
// Take the easy way out; these are usually bounded and all visible.
int first_column = 0;
@@ -338,7 +337,6 @@ void GuiTable::draw(gcn::Graphics* graphics)
graphics->pushClipArea(bounds);
widget->draw(graphics);
graphics->popClipArea();
-
}
x_offset += width;
@@ -369,7 +367,7 @@ void GuiTable::moveToBottom(gcn::Widget *widget)
mTopWidget = NULL;
}
-gcn::Rectangle GuiTable::getChildrenArea(void)
+gcn::Rectangle GuiTable::getChildrenArea()
{
return gcn::Rectangle(0, 0, getWidth(), getHeight());
}
@@ -459,7 +457,7 @@ void GuiTable::mouseWheelMovedDown(gcn::MouseEvent& mouseEvent)
mouseEvent.consume();
}
}
-
+
void GuiTable::mouseDragged(gcn::MouseEvent& mouseEvent)
{
}
@@ -479,7 +477,7 @@ void GuiTable::modelUpdated(bool completed)
}
}
-gcn::Widget* GuiTable::getWidgetAt(int x, int y)
+gcn::Widget *GuiTable::getWidgetAt(int x, int y)
{
int row = getRowForY(y);
int column = getColumnForX(x);
@@ -531,12 +529,13 @@ void GuiTable::_setFocusHandler(gcn::FocusHandler* focusHandler)
{
gcn::Widget::_setFocusHandler(focusHandler);
- if (mModel)
- for (int r = 0; r < mModel->getRows(); ++r)
- for (int c = 0; c < mModel->getColumns(); ++c)
- {
+ if (mModel) {
+ for (int r = 0; r < mModel->getRows(); ++r) {
+ for (int c = 0; c < mModel->getColumns(); ++c) {
gcn::Widget *w = mModel->getElementAt(r, c);
if (w)
w->_setFocusHandler(focusHandler);
}
+ }
+ }
}
diff --git a/src/gui/table.h b/src/gui/table.h
index a508d0e4..d73cf340 100644
--- a/src/gui/table.h
+++ b/src/gui/table.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra derived from original code
- * from Guichan.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -47,17 +46,19 @@ class GuiTable : public gcn::Widget,
public gcn::KeyListener,
public TableModelListener
{
- friend class GuiTableActionListener; // so that the action listener can call distributeActionEvent
+ // so that the action listener can call distributeActionEvent
+ friend class GuiTableActionListener;
+
public:
GuiTable(TableModel * initial_model = NULL, gcn::Color background = 0xffffff,
bool opacity = true);
- virtual ~GuiTable(void);
+ virtual ~GuiTable();
/**
* Retrieves the active table model
*/
- TableModel *getModel(void) const;
+ TableModel *getModel() const;
/**
* Sets the table model
@@ -73,9 +74,9 @@ public:
void setSelected(int row, int column);
- int getSelectedRow(void);
+ int getSelectedRow();
- int getSelectedColumn(void);
+ int getSelectedColumn();
void setSelectedRow(int selected);
@@ -137,25 +138,25 @@ public:
virtual void mouseWheelMovedUp(gcn::MouseEvent& mouseEvent);
virtual void mouseWheelMovedDown(gcn::MouseEvent& mouseEvent);
-
+
virtual void mouseDragged(gcn::MouseEvent& mouseEvent);
// Constraints inherited from TableModelListener
virtual void modelUpdated(bool);
protected:
+ /** Frees all action listeners on inner widgets. */
+ virtual void uninstallActionListeners();
+ /** Installs all action listeners on inner widgets. */
+ virtual void installActionListeners();
- virtual void uninstallActionListeners(void); // frees all action listeners on inner widgets
- virtual void installActionListeners(void); // installs all action listeners on inner widgets
-
- virtual int getRowHeight(void);
+ virtual int getRowHeight();
virtual int getColumnWidth(int i);
-
-private:
+private:
int getRowForY(int y); // -1 on error
int getColumnForX(int x); // -1 on error
- void recomputeDimensions(void);
+ void recomputeDimensions();
bool mLinewiseMode;
bool mWrappingEnabled;
bool mOpaque;
@@ -172,11 +173,14 @@ private:
int mSelectedRow;
int mSelectedColumn;
- int mPopFramesNr; // Number of frames to skip upwards when drawing the selected widget
+ /** Number of frames to skip upwards when drawing the selected widget. */
+ int mPopFramesNr;
- gcn::Widget *mTopWidget; // If someone moves a fresh widget to the top, we must display it
+ /** If someone moves a fresh widget to the top, we must display it. */
+ gcn::Widget *mTopWidget;
- std::vector<GuiTableActionListener *> action_listeners; // Vector for compactness; used as a list in practice.
+ /** Vector for compactness; used as a list in practice. */
+ std::vector<GuiTableActionListener *> mActionListeners;
};
diff --git a/src/gui/table_model.cpp b/src/gui/table_model.cpp
index 8998961e..4fa13bae 100644
--- a/src/gui/table_model.cpp
+++ b/src/gui/table_model.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,13 +35,13 @@ void TableModel::removeListener(TableModelListener *listener)
listeners.erase(listener);
}
-void TableModel::signalBeforeUpdate(void)
+void TableModel::signalBeforeUpdate()
{
for (std::set<TableModelListener *>::const_iterator it = listeners.begin(); it != listeners.end(); it++)
(*it)->modelUpdated(false);
}
-void TableModel::signalAfterUpdate(void)
+void TableModel::signalAfterUpdate()
{
for (std::set<TableModelListener *>::const_iterator it = listeners.begin(); it != listeners.end(); it++)
(*it)->modelUpdated(true);
@@ -61,12 +60,12 @@ StaticTableModel::StaticTableModel(int row, int column) :
mWidths.resize(column, 1);
}
-StaticTableModel::~StaticTableModel(void)
+StaticTableModel::~StaticTableModel()
{
delete_all(mTableModel);
}
-void StaticTableModel::resize(void)
+void StaticTableModel::resize()
{
mRows = getRows();
mColumns = getColumns();
@@ -98,7 +97,7 @@ void StaticTableModel::set(int row, int column, gcn::Widget *widget)
signalAfterUpdate();
}
-gcn::Widget* StaticTableModel::getElementAt(int row, int column)
+gcn::Widget *StaticTableModel::getElementAt(int row, int column)
{
return mTableModel[WIDGET_AT(row, column)];
}
@@ -120,7 +119,7 @@ void StaticTableModel::fixRowHeight(int height)
mHeight = -height;
}
-int StaticTableModel::getRowHeight(void)
+int StaticTableModel::getRowHeight()
{
return abs(mHeight);
}
@@ -133,12 +132,12 @@ int StaticTableModel::getColumnWidth(int column)
return abs(mWidths[column]);
}
-int StaticTableModel::getRows(void)
+int StaticTableModel::getRows()
{
return mRows;
}
-int StaticTableModel::getColumns(void)
+int StaticTableModel::getColumns()
{
return mColumns;
}
diff --git a/src/gui/table_model.h b/src/gui/table_model.h
index 6edd7d65..9ca36120 100644
--- a/src/gui/table_model.h
+++ b/src/gui/table_model.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,8 +29,9 @@ class TableModelListener
{
public:
/**
- * Must be invoked by the TableModel whenever a global change is about to occur or
- * has occurred (e.g., when a row or column is being removed or added).
+ * Must be invoked by the TableModel whenever a global change is about to
+ * occur or has occurred (e.g., when a row or column is being removed or
+ * added).
*
* This method is triggered twice, once before and once after the update.
*
@@ -46,22 +46,22 @@ public:
class TableModel
{
public:
- virtual ~TableModel(void) { }
+ virtual ~TableModel() { }
/**
* Determines the number of rows (lines) in the table
*/
- virtual int getRows(void) = 0;
+ virtual int getRows() = 0;
/**
* Determines the number of columns in each row
*/
- virtual int getColumns(void) = 0;
+ virtual int getColumns() = 0;
/**
* Determines the height for each row
*/
- virtual int getRowHeight(void) = 0;
+ virtual int getRowHeight() = 0;
/**
* Determines the width of each individual column
@@ -81,12 +81,12 @@ protected:
/**
* Tells all listeners that the table is about to see an update
*/
- virtual void signalBeforeUpdate(void);
+ virtual void signalBeforeUpdate();
/**
* Tells all listeners that the table has seen an update
*/
- virtual void signalAfterUpdate(void);
+ virtual void signalAfterUpdate();
private:
std::set<TableModelListener *> listeners;
@@ -97,7 +97,7 @@ class StaticTableModel : public TableModel
{
public:
StaticTableModel(int width, int height);
- virtual ~StaticTableModel(void);
+ virtual ~StaticTableModel();
/**
* Inserts a widget into the table model.
@@ -107,7 +107,8 @@ public:
virtual void set(int row, int column, gcn::Widget *widget);
/**
- * Fixes the column width for a given column; this overrides dynamic width inference.
+ * Fixes the column width for a given column; this overrides dynamic width
+ * inference.
*
* Semantics are undefined for width 0.
*/
@@ -123,17 +124,16 @@ public:
/**
* Resizes the table model
*/
- virtual void resize(void);
+ virtual void resize();
- virtual int getRows(void);
- virtual int getColumns(void);
- virtual int getRowHeight(void);
- virtual int getWidth(void);
- virtual int getHeight(void);
+ virtual int getRows();
+ virtual int getColumns();
+ virtual int getRowHeight();
+ virtual int getWidth();
+ virtual int getHeight();
virtual int getColumnWidth(int index);
virtual gcn::Widget *getElementAt(int row, int column);
-
protected:
int mRows, mColumns;
int mHeight;
diff --git a/src/gui/textbox.cpp b/src/gui/textbox.cpp
index 51a8efc6..10f727e3 100644
--- a/src/gui/textbox.cpp
+++ b/src/gui/textbox.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/textbox.h b/src/gui/textbox.h
index 20f4ebe2..5884e11c 100644
--- a/src/gui/textbox.h
+++ b/src/gui/textbox.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/textdialog.cpp b/src/gui/textdialog.cpp
new file mode 100644
index 00000000..8c65d64b
--- /dev/null
+++ b/src/gui/textdialog.cpp
@@ -0,0 +1,91 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "textdialog.h"
+#include "button.h"
+
+#include "../utils/gettext.h"
+
+#include <guichan/widgets/label.hpp>
+#include <guichan/widgets/textfield.hpp>
+
+TextDialog::TextDialog(const std::string &title, const std::string &msg,
+ Window *parent):
+ Window(title, true, parent),
+ mTextField(new TextField)
+{
+ gcn::Label *textLabel = new gcn::Label(msg);
+ mOkButton = new Button(_("OK"), "OK", this);
+ gcn::Button *cancelButton = new Button(_("Cancel"), "CANCEL", this);
+
+ int w = textLabel->getWidth() + 20;
+ int inWidth = mOkButton->getWidth() + cancelButton->getWidth() + 5;
+ int h = textLabel->getHeight() + 25 + mOkButton->getHeight() + mTextField->getHeight();
+
+ if (w < inWidth + 10)
+ w = inWidth + 10;
+
+ setContentSize(w, h);
+ textLabel->setPosition(10, 10);
+ mTextField->setWidth(85);
+ mTextField->setPosition(10,20 + textLabel->getHeight());
+ mOkButton->setPosition((w - inWidth) / 2,
+ h - 5 - cancelButton->getHeight());
+ cancelButton->setPosition(mOkButton->getX() + mOkButton->getWidth() + 5,
+ h - 5 - cancelButton->getHeight());
+
+ add(textLabel);
+ add(mTextField);
+ add(mOkButton);
+ add(cancelButton);
+
+ if (getParent()) {
+ setLocationRelativeTo(getParent());
+ getParent()->moveToTop(this);
+ }
+ setVisible(true);
+ mTextField->requestFocus();
+}
+
+void TextDialog::action(const gcn::ActionEvent &event)
+{
+ // Proxy button events to our listeners
+ ActionListenerIterator i;
+ for (i = mActionListeners.begin(); i != mActionListeners.end(); ++i)
+ {
+ (*i)->action(event);
+ }
+
+ if (event.getId() == "CANCEL" || event.getId() == "OK")
+ {
+ scheduleDelete();
+ }
+}
+
+const std::string &TextDialog::getText() const
+{
+ return mTextField->getText();
+}
+
+void TextDialog::setOKButtonActionId(const std::string &name)
+{
+ mOkButton->setActionEventId(name);
+}
diff --git a/src/gui/textdialog.h b/src/gui/textdialog.h
new file mode 100644
index 00000000..3dc9259c
--- /dev/null
+++ b/src/gui/textdialog.h
@@ -0,0 +1,66 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef GUI_GUILD_DIALOG_H
+#define GUI_GUILD_DIALOG_H
+
+#include <guichan/actionlistener.hpp>
+#include "textfield.h"
+
+#include "window.h"
+
+/**
+* An option dialog.
+ *
+ * \ingroup GUI
+ */
+class TextDialog : public Window, public gcn::ActionListener
+{
+public:
+ /**
+ * Constructor.
+ *
+ * @see Window::Window
+ */
+ TextDialog(const std::string &title, const std::string &msg,
+ Window *parent = NULL);
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Get the text in the textfield
+ */
+ const std::string &getText() const;
+
+ /**
+ * Set the OK button action id
+ */
+ void setOKButtonActionId(const std::string &name);
+
+private:
+ TextField *mTextField;
+ gcn::Button *mOkButton;
+};
+
+#endif
diff --git a/src/gui/textfield.cpp b/src/gui/textfield.cpp
index 257ddaa1..42279fc4 100644
--- a/src/gui/textfield.cpp
+++ b/src/gui/textfield.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -40,7 +39,7 @@ int TextField::instances = 0;
float TextField::mAlpha = config.getValue("guialpha", 0.8);
ImageRect TextField::skin;
-TextField::TextField(const std::string& text):
+TextField::TextField(const std::string &text):
gcn::TextField(text),
mNumeric(false),
mListener(0)
diff --git a/src/gui/textfield.h b/src/gui/textfield.h
index b82912c0..070d86ae 100644
--- a/src/gui/textfield.h
+++ b/src/gui/textfield.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,12 +38,13 @@ class TextFieldListener
*
* \ingroup GUI
*/
-class TextField : public gcn::TextField {
+class TextField : public gcn::TextField
+{
public:
/**
* Constructor, initializes the text field with the given string.
*/
- TextField(const std::string& text = "");
+ TextField(const std::string &text = "");
/**
* Destructor.
diff --git a/src/gui/textrenderer.h b/src/gui/textrenderer.h
index c0f5a0e9..712c1312 100644
--- a/src/gui/textrenderer.h
+++ b/src/gui/textrenderer.h
@@ -2,7 +2,7 @@
* Text Renderer
* Copyright (C) 2009 The Mana World Development Team
*
- * This file is part of Aethyra based on code from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,17 +35,22 @@ class TextRenderer
/**
* Renders a specified text.
*/
- static inline void renderText(gcn::Graphics *graphics, const std::string&
- text, int x, int y, gcn::Graphics::Alignment align,
- const gcn::Color color, gcn::Font *font, bool outline = false,
- bool shadow = false, int alpha = 255)
+ static inline void renderText(gcn::Graphics *graphics,
+ const std::string &text,
+ int x, int y,
+ gcn::Graphics::Alignment align,
+ const gcn::Color &color,
+ gcn::Font *font,
+ bool outline = false,
+ bool shadow = false, int alpha = 255)
{
graphics->setFont(font);
// Text shadow
if (shadow)
{
- graphics->setColor(guiPalette->getColor(Palette::SHADOW, alpha / 2));
+ graphics->setColor(guiPalette->getColor(Palette::SHADOW,
+ alpha / 2));
if (outline)
{
graphics->drawText(text, x + 2, y + 2, align);
diff --git a/src/gui/trade.cpp b/src/gui/trade.cpp
index 82ac4647..2d80d12d 100644
--- a/src/gui/trade.cpp
+++ b/src/gui/trade.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,24 +38,39 @@
#include "../inventory.h"
#include "../item.h"
#include "../localplayer.h"
+#include "../units.h"
+#ifdef TMWSERV_SUPPORT
+#include "../net/tmwserv/gameserver/player.h"
+#else
#include "../net/messageout.h"
-#include "../net/protocol.h"
+#include "../net/ea/protocol.h"
+#endif
#include "../utils/gettext.h"
-#include "../utils/strprintf.h"
#include "../utils/stringutils.h"
+#include "../utils/strprintf.h"
+#ifdef TMWSERV_SUPPORT
+TradeWindow::TradeWindow():
+#else
TradeWindow::TradeWindow(Network *network):
- Window("Trade"),
+#endif
+ Window(_("Trade: You")),
+#ifdef EATHENA_SUPPORT
mNetwork(network),
mMyInventory(new Inventory(INVENTORY_SIZE, 2)),
mPartnerInventory(new Inventory(INVENTORY_SIZE, 2))
+#else
+ mMyInventory(new Inventory(INVENTORY_SIZE)),
+ mPartnerInventory(new Inventory(INVENTORY_SIZE)),
+ mStatus(PREPARING)
+#endif
{
- setWindowName(_("Trade"));
- setDefaultSize(342, 209, ImageRect::CENTER);
+ setWindowName("Trade");
setResizable(true);
setCloseButton(true);
+ setDefaultSize(342, 209, ImageRect::CENTER);
setMinWidth(342);
setMinHeight(209);
@@ -65,36 +79,58 @@ TradeWindow::TradeWindow(Network *network):
getFont()->getWidth(_("Trade")) ?
_("OK") : _("Trade");
- mAddButton = new Button(_("Add"), "add", this);
+ Button *addButton = new Button(_("Add"), "add", this);
+#ifdef EATHENA_SUPPORT
mOkButton = new Button(longestName, "ok", this);
-
- mMyItemContainer = new ItemContainer(mMyInventory.get(), 2);
- mMyItemContainer->setWidth(160);
+#else
+ Button *cancelButton = new Button(_("Cancel"), "cancel", this);
+#endif
+ mTradeButton = new Button(_("Propose trade"), "trade", this);
+ mTradeButton->setWidth(8 + std::max(
+ mTradeButton->getFont()->getWidth(_("Propose trade")),
+ mTradeButton->getFont()->getWidth(_("Confirm trade"))));
+
+#ifdef TMWSERV_SUPPORT
+ mMyItemContainer = new ItemContainer(mMyInventory.get(), 4, 3, 0);
+#else
+ mMyItemContainer = new ItemContainer(mMyInventory.get(), 4, 3, 2);
+#endif
mMyItemContainer->addSelectionListener(this);
- mMyScroll = new ScrollArea(mMyItemContainer);
+ ScrollArea *myScroll = new ScrollArea(mMyItemContainer);
- mPartnerItemContainer = new ItemContainer(mPartnerInventory.get(), 2);
- mPartnerItemContainer->setWidth(160);
+#ifdef TMWSERV_SUPPORT
+ mPartnerItemContainer = new ItemContainer(mPartnerInventory.get(), 4, 3, 0);
+#else
+ mPartnerItemContainer = new ItemContainer(mPartnerInventory.get(), 4, 3, 2);
+#endif
mPartnerItemContainer->addSelectionListener(this);
- mPartnerScroll = new ScrollArea(mPartnerItemContainer);
+ ScrollArea *partnerScroll = new ScrollArea(mPartnerItemContainer);
+
+ mMoneyLabel = new Label(strprintf(_("You get %s."), ""));
+ gcn::Label *mMoneyLabel2 = new Label(_("You give:"));
- mMoneyLabel = new Label(strprintf(_("You get %d GP."), 0));
- mMoneyLabel2 = new Label(_("You give:"));
mMoneyField = new TextField;
- mMoneyField->setWidth(50);
+ mMoneyField->setWidth(40);
+ Button *moneyChange = new Button(_("Change"), "money", this);
place(1, 0, mMoneyLabel);
- place(0, 1, mMyScroll).setPadding(3);
- place(1, 1, mPartnerScroll).setPadding(3);
+ place(0, 1, myScroll).setPadding(3);
+ place(1, 1, partnerScroll).setPadding(3);
ContainerPlacer place;
place = getPlacer(0, 0);
place(0, 0, mMoneyLabel2);
place(1, 0, mMoneyField);
+ place(2, 0, moneyChange).setHAlign(LayoutCell::LEFT);
place = getPlacer(0, 2);
- place(6, 0, mAddButton);
- place(7, 0, mOkButton);
+ place(0, 0, addButton);
+#ifdef EATHENA_SUPPORT
+ place(1, 0, mOkButton);
+#else
+ place(2, 0, mTradeButton);
+ place(3, 0, cancelButton);
+#endif
Layout &layout = getLayout();
layout.extend(0, 2, 2, 1);
layout.setRowHeight(1, Layout::AUTO_SET);
@@ -102,7 +138,9 @@ TradeWindow::TradeWindow(Network *network):
layout.setColWidth(0, Layout::AUTO_SET);
layout.setColWidth(1, Layout::AUTO_SET);
+#ifdef EATHENA_SUPPORT
mOkButton->setCaption(_("OK"));
+#endif
loadWindowState();
}
@@ -111,34 +149,37 @@ TradeWindow::~TradeWindow()
{
}
-void TradeWindow::addMoney(int amount)
+void TradeWindow::setMoney(int amount)
{
- mMoneyLabel->setCaption(strprintf(_("You get %d GP."), amount));
+ mMoneyLabel->setCaption(strprintf(_("You get %s."),
+ Units::formatCurrency(amount).c_str()));
mMoneyLabel->adjustSize();
+#ifdef TMWSERV_SUPPORT
+ setStatus(PREPARING);
+#endif
+}
+
+#ifdef TMWSERV_SUPPORT
+void TradeWindow::addItem(int id, bool own, int quantity)
+{
+ (own ? mMyInventory : mPartnerInventory)->addItem(id, quantity);
+ setStatus(PREPARING);
}
+#endif
+#ifdef EATHENA_SUPPORT
void TradeWindow::addItem(int id, bool own, int quantity, bool equipment)
{
if (own)
{
- mMyItemContainer->setWidth(mMyScroll->getWidth());
mMyInventory->addItem(id, quantity, equipment);
}
else
{
- mPartnerItemContainer->setWidth(mPartnerScroll->getWidth());
mPartnerInventory->addItem(id, quantity, equipment);
}
}
-void TradeWindow::removeItem(int id, bool own)
-{
- if (own)
- mMyInventory->removeItem(id);
- else
- mPartnerInventory->removeItem(id);
-}
-
void TradeWindow::changeQuantity(int index, bool own, int quantity)
{
if (own)
@@ -154,21 +195,36 @@ void TradeWindow::increaseQuantity(int index, bool own, int quantity)
else
mPartnerInventory->getItem(index)->increaseQuantity(quantity);
}
+#endif
void TradeWindow::reset()
{
mMyInventory->clear();
mPartnerInventory->clear();
+#ifdef EATHENA_SUPPORT
mOkButton->setCaption(_("OK"));
mOkButton->setActionEventId("ok");
mOkButton->setEnabled(true);
mOkOther = false;
mOkMe = false;
- mMoneyLabel->setCaption(strprintf(_("You get %d GP."), 0));
+#endif
+ mMoneyLabel->setCaption(strprintf(_("You get %s."), ""));
mMoneyField->setEnabled(true);
mMoneyField->setText("");
+#ifdef TMWSERV_SUPPORT
+ setStatus(PREPARING);
+#endif
}
+#ifdef TMWSERV_SUPPORT
+
+void TradeWindow::receivedOk()
+{
+ setStatus(ACCEPTING);
+}
+
+#else
+
void TradeWindow::receivedOk(bool own)
{
if (own)
@@ -191,8 +247,15 @@ void TradeWindow::receivedOk(bool own)
}
}
+#endif
+
void TradeWindow::tradeItem(Item *item, int quantity)
{
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::tradeItem(item->getInvIndex(), quantity);
+ addItem(item->getId(), true, quantity);
+ item->increaseQuantity(-quantity);
+#else
// TODO: Our newer version of eAthena doesn't register this following
// function. Detect the actual server version, and re-enable this
// for that version only.
@@ -201,6 +264,7 @@ void TradeWindow::tradeItem(Item *item, int quantity)
outMsg.writeInt16(CMSG_TRADE_ITEM_ADD_REQUEST);
outMsg.writeInt16(item->getInvIndex());
outMsg.writeInt32(quantity);
+#endif
}
void TradeWindow::valueChanged(const gcn::SelectionEvent &event)
@@ -217,6 +281,18 @@ void TradeWindow::valueChanged(const gcn::SelectionEvent &event)
mMyItemContainer->selectNone();
}
+#ifdef TMWSERV_SUPPORT
+void TradeWindow::setStatus(Status s)
+{
+ if (s == mStatus) return;
+ mStatus = s;
+
+ mTradeButton->setCaption
+ (s == PREPARING ? _("Propose trade") : _("Confirm trade"));
+ mTradeButton->setEnabled(s != PROPOSING);
+}
+#endif
+
void TradeWindow::action(const gcn::ActionEvent &event)
{
Item *item = inventoryWindow->getSelectedItem();
@@ -233,7 +309,7 @@ void TradeWindow::action(const gcn::ActionEvent &event)
if (mMyInventory->contains(item))
{
- chatWindow->chatLog(_("Failed adding item. You can not "
+ localChatTab->chatLog(_("Failed adding item. You can not "
"overlap one kind of item on the window."),
BY_SERVER);
return;
@@ -248,12 +324,24 @@ void TradeWindow::action(const gcn::ActionEvent &event)
// Choose amount of items to trade
new ItemAmountWindow(AMOUNT_TRADE_ADD, this, item);
}
+
+#ifdef TMWSERV_SUPPORT
+ setStatus(PREPARING);
+#endif
}
else if (event.getId() == "cancel")
{
+ setVisible(false);
+ reset();
+ player_node->setTrading(false);
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::acceptTrade(false);
+#else
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_TRADE_CANCEL_REQUEST);
+#endif
}
+#ifdef EATHENA_SUPPORT
else if (event.getId() == "ok")
{
std::stringstream tempMoney(mMoneyField->getText());
@@ -275,15 +363,34 @@ void TradeWindow::action(const gcn::ActionEvent &event)
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_TRADE_ADD_COMPLETE);
}
+#endif
else if (event.getId() == "trade")
{
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::acceptTrade(true);
+ setStatus(PROPOSING);
+#else
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_TRADE_OK);
+#endif
+ }
+#ifdef TMWSERV_SUPPORT
+ else if (event.getId() == "money")
+ {
+ int v = atoi(mMoneyField->getText().c_str());
+ Net::GameServer::Player::tradeMoney(v);
+ mMoneyField->setText(strprintf("%d", v));
+ setStatus(PREPARING);
}
+#endif
}
void TradeWindow::close()
{
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::acceptTrade(false);
+#else
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_TRADE_CANCEL_REQUEST);
+#endif
}
diff --git a/src/gui/trade.h b/src/gui/trade.h
index 76ba5a4c..4c215ba6 100644
--- a/src/gui/trade.h
+++ b/src/gui/trade.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,7 +34,9 @@
class Inventory;
class Item;
class ItemContainer;
+#ifdef EATHENA_SUPPORT
class Network;
+#endif
class ScrollArea;
/**
@@ -49,7 +50,11 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener
/**
* Constructor.
*/
+#ifdef TMWSERV_SUPPORT
+ TradeWindow();
+#else
TradeWindow(Network *network);
+#endif
/**
* Destructor.
@@ -57,24 +62,25 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener
~TradeWindow();
/**
- * Add money to the trade window.
+ * Displays expected money in the trade window.
*/
- void addMoney(int quantity);
+ void setMoney(int quantity);
/**
* Add an item to the trade window.
*/
- void addItem(int id, bool own, int quantity, bool equipment);
+ void addItem(int id, bool own, int quantity);
/**
- * Remove a item from the trade window.
+ * Reset both item containers
*/
- void removeItem(int id, bool own);
+ void reset();
+#ifdef EATHENA_SUPPORT
/**
- * Reset both item containers
+ * Add an item to the trade window.
*/
- void reset();
+ void addItem(int id, bool own, int quantity, bool equipment);
/**
* Change quantity of an item.
@@ -85,11 +91,16 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener
* Increase quantity of an item.
*/
void increaseQuantity(int index, bool own, int quantity);
+#endif
/**
* Player received ok message from server
*/
+#ifdef TMWSERV_SUPPORT
+ void receivedOk();
+#else
void receivedOk(bool own);
+#endif
/**
* Send trade packet.
@@ -114,7 +125,23 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener
void close();
private:
+#ifdef TMWSERV_SUPPORT
+ enum Status
+ {
+ PREPARING, /**< Players are adding items. */
+ PROPOSING, /**< Local player is proposing a trade. */
+ ACCEPTING /**< Distant player is proposing a trade. */
+ };
+
+ /**
+ * Sets the current status of the trade.
+ */
+ void setStatus(Status);
+#endif
+
+#ifdef EATHENA_SUPPORT
Network *mNetwork;
+#endif
typedef const std::auto_ptr<Inventory> InventoryPtr;
InventoryPtr mMyInventory;
@@ -124,11 +151,18 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener
ItemContainer *mPartnerItemContainer;
gcn::Label *mMoneyLabel;
- gcn::Label *mMoneyLabel2;
- gcn::Button *mAddButton, *mOkButton;
- ScrollArea *mMyScroll, *mPartnerScroll;
+ gcn::Button *mTradeButton;
+#ifdef EATHENA_SUPPORT
+ gcn::Button *mAddButton;
+ gcn::Button *mOkButton;
+#endif
gcn::TextField *mMoneyField;
+
+#ifdef TMWSERV_SUPPORT
+ Status mStatus;
+#else
bool mOkOther, mOkMe;
+#endif
};
extern TradeWindow *tradeWindow;
diff --git a/src/gui/truetypefont.cpp b/src/gui/truetypefont.cpp
index e50fb457..b4b839e9 100644
--- a/src/gui/truetypefont.cpp
+++ b/src/gui/truetypefont.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -44,8 +43,7 @@ class TextChunk
bool operator==(const TextChunk &chunk) const
{
- return (
- chunk.text == text && chunk.color == color);
+ return (chunk.text == text && chunk.color == color);
}
void generate(TTF_Font *font)
@@ -134,12 +132,12 @@ void TrueTypeFont::drawString(gcn::Graphics *graphics,
bool found = false;
- for (CacheIterator i = cache.begin(); i != cache.end(); i++)
+ for (CacheIterator i = mCache.begin(); i != mCache.end(); ++i)
{
if (chunk == (*i))
{
// Raise priority: move it to front
- cache.splice(cache.begin(), cache, i);
+ mCache.splice(mCache.begin(), mCache, i);
found = true;
break;
}
@@ -148,19 +146,19 @@ void TrueTypeFont::drawString(gcn::Graphics *graphics,
// Surface not found
if (!found)
{
- if (cache.size() >= CACHE_SIZE)
+ if (mCache.size() >= CACHE_SIZE)
{
- cache.pop_back();
+ mCache.pop_back();
}
- cache.push_front(chunk);
- cache.front().generate(mFont);
+ mCache.push_front(chunk);
+ mCache.front().generate(mFont);
}
- cache.front().img->setAlpha(alpha);
- g->drawImage(cache.front().img, x, y);
+ mCache.front().img->setAlpha(alpha);
+ g->drawImage(mCache.front().img, x, y);
}
-int TrueTypeFont::getWidth(const std::string& text) const
+int TrueTypeFont::getWidth(const std::string &text) const
{
int w, h;
TTF_SizeUTF8(mFont, text.c_str(), &w, &h);
diff --git a/src/gui/truetypefont.h b/src/gui/truetypefont.h
index 085aa226..cbe64368 100644
--- a/src/gui/truetypefont.h
+++ b/src/gui/truetypefont.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,8 +26,8 @@
#include <string>
#include <guichan/font.hpp>
-#ifndef __APPLE__
-#include <SDL/SDL_ttf.h>
+#ifdef __APPLE__
+#include <SDL_ttf/SDL_ttf.h>
#else
#include <SDL_ttf.h>
#endif
@@ -56,20 +55,22 @@ class TrueTypeFont : public gcn::Font
*/
~TrueTypeFont();
- virtual int getWidth(const std::string& text) const;
+ virtual int getWidth(const std::string &text) const;
virtual int getHeight() const;
/**
* @see Font::drawString
*/
- void drawString(gcn::Graphics* graphics, const std::string& text, int x, int y);
+ void drawString(gcn::Graphics *graphics,
+ const std::string &text,
+ int x, int y);
private:
TTF_Font *mFont;
// Word surfaces cache
- std::list<TextChunk> cache;
+ std::list<TextChunk> mCache;
};
#endif
diff --git a/src/gui/unregisterdialog.cpp b/src/gui/unregisterdialog.cpp
new file mode 100644
index 00000000..7906afc1
--- /dev/null
+++ b/src/gui/unregisterdialog.cpp
@@ -0,0 +1,141 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "unregisterdialog.h"
+
+#include <string>
+#include <sstream>
+
+#include <guichan/widgets/label.hpp>
+
+#include "../main.h"
+#include "../log.h"
+#include "../logindata.h"
+
+#include "button.h"
+#include "checkbox.h"
+#include "register.h"
+#include "passwordfield.h"
+#include "textfield.h"
+#include "ok_dialog.h"
+
+#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
+
+UnRegisterDialog::UnRegisterDialog(Window *parent, LoginData *loginData):
+ Window("Unregister", true, parent),
+ mWrongDataNoticeListener(new WrongDataNoticeListener()),
+ mLoginData(loginData)
+{
+ gcn::Label *userLabel = new gcn::Label(strprintf(_("Name: %s"), mLoginData->username.c_str()));
+ gcn::Label *passwordLabel = new gcn::Label(_("Password:"));
+ mPasswordField = new PasswordField(mLoginData->password);
+ mUnRegisterButton = new Button(_("Unregister"), "unregister", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+
+ const int width = 210;
+ const int height = 80;
+ setContentSize(width, height);
+
+ userLabel->setPosition(5, 5);
+ userLabel->setWidth(width - 5);
+ mPasswordField->setPosition(
+ 68, userLabel->getY() + userLabel->getHeight() + 7);
+ mPasswordField->setWidth(130);
+
+ passwordLabel->setPosition(5, mPasswordField->getY() + 1);
+
+ mCancelButton->setPosition(
+ width - 5 - mCancelButton->getWidth(),
+ height - 5 - mCancelButton->getHeight());
+ mUnRegisterButton->setPosition(
+ mCancelButton->getX() - 5 - mUnRegisterButton->getWidth(),
+ mCancelButton->getY());
+
+ add(userLabel);
+ add(passwordLabel);
+ add(mPasswordField);
+ add(mUnRegisterButton);
+ add(mCancelButton);
+
+ setLocationRelativeTo(getParent());
+ setVisible(true);
+ mPasswordField->requestFocus();
+ mPasswordField->setActionEventId("cancel");
+}
+
+UnRegisterDialog::~UnRegisterDialog()
+{
+ delete mWrongDataNoticeListener;
+}
+
+void
+UnRegisterDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "cancel")
+ {
+ scheduleDelete();
+ }
+ else if (event.getId() == "unregister")
+ {
+ const std::string username = mLoginData->username.c_str();
+ const std::string password = mPasswordField->getText();
+ logger->log("UnregisterDialog::unregistered, Username is %s",
+ username.c_str());
+
+ std::stringstream errorMsg;
+ bool error = false;
+
+ // Check password
+ if (password.length() < LEN_MIN_PASSWORD)
+ {
+ // Pass too short
+ errorMsg << "The password needs to be at least "
+ << LEN_MIN_PASSWORD
+ << " characters long.";
+ error = true;
+ }
+ else if (password.length() > LEN_MAX_PASSWORD - 1 )
+ {
+ // Pass too long
+ errorMsg << "The password needs to be less than "
+ << LEN_MAX_PASSWORD
+ << " characters long.";
+ error = true;
+ }
+
+ if (error)
+ {
+ mWrongDataNoticeListener->setTarget(this->mPasswordField);
+
+ OkDialog *dlg = new OkDialog("Error", errorMsg.str());
+ dlg->addActionListener(mWrongDataNoticeListener);
+ }
+ else
+ {
+ // No errors detected, unregister the new user.
+ mUnRegisterButton->setEnabled(false);
+ mLoginData->password = password;
+ state = STATE_UNREGISTER_ATTEMPT;
+ scheduleDelete();
+ }
+ }
+}
diff --git a/src/gui/unregisterdialog.h b/src/gui/unregisterdialog.h
new file mode 100644
index 00000000..1e3cc88f
--- /dev/null
+++ b/src/gui/unregisterdialog.h
@@ -0,0 +1,70 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef UNREGISTERDIALOG_H
+#define UNREGISTERDIALOG_H
+
+#include <iosfwd>
+#include <guichan/actionlistener.hpp>
+
+#include "window.h"
+#include "../guichanfwd.h"
+
+class LoginData;
+class OkDialog;
+class WrongDataNoticeListener;
+
+/**
+ * The Unregister dialog.
+ *
+ * \ingroup Interface
+ */
+class UnRegisterDialog : public Window, public gcn::ActionListener {
+ public:
+ /**
+ * Constructor
+ *
+ * @see Window::Window
+ */
+ UnRegisterDialog(Window *parent,LoginData *loginData);
+
+ /**
+ * Destructor
+ */
+ ~UnRegisterDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ private:
+ gcn::TextField *mPasswordField;
+
+ gcn::Button *mUnRegisterButton;
+ gcn::Button *mCancelButton;
+
+ WrongDataNoticeListener *mWrongDataNoticeListener;
+
+ LoginData *mLoginData;
+};
+
+#endif
diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp
index 927d6eaf..8c903c28 100644
--- a/src/gui/updatewindow.cpp
+++ b/src/gui/updatewindow.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -106,7 +105,7 @@ UpdaterWindow::UpdaterWindow(const std::string &updateHost,
{
mCurlError[0] = 0;
- mBrowserBox = new BrowserBox();
+ mBrowserBox = new BrowserBox;
mScrollArea = new ScrollArea(mBrowserBox);
mLabel = new Label(_("Connecting..."));
mProgressBar = new ProgressBar(0.0, 310, 20, 168, 116, 31);
@@ -130,7 +129,7 @@ UpdaterWindow::UpdaterWindow(const std::string &updateHost,
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
- setLocationRelativeTo(getParent());
+ center();
setVisible(true);
mCancelButton->requestFocus();
@@ -184,7 +183,7 @@ void UpdaterWindow::action(const gcn::ActionEvent &event)
}
else if (event.getId() == "play")
{
- state = LOADDATA_STATE;
+ state = STATE_LOADDATA;
}
}
@@ -231,7 +230,7 @@ int UpdaterWindow::updateProgress(void *ptr,
uw->mCurrentFile + " (" + toString((int) (progress * 100)) + "%)");
uw->setProgress(progress);
- if (state != UPDATE_STATE || uw->mDownloadStatus == UPDATE_ERROR)
+ if (state != STATE_UPDATE || uw->mDownloadStatus == UPDATE_ERROR)
{
// If the action was canceled return an error code to stop the mThread
return -1;
@@ -359,7 +358,7 @@ int UpdaterWindow::downloadThread(void *ptr)
// Remove the corrupted file
::remove(outFilename.c_str());
logger->log(
- _("Checksum for file %s failed: (%lx/%lx)"),
+ "Checksum for file %s failed: (%lx/%lx)",
uw->mCurrentFile.c_str(),
adler, uw->mCurrentChecksum);
attempts++;
diff --git a/src/gui/updatewindow.h b/src/gui/updatewindow.h
index 234a6f57..ace398b4 100644
--- a/src/gui/updatewindow.h
+++ b/src/gui/updatewindow.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,6 +31,8 @@
#include "../utils/mutex.h"
+#include "../utils/mutex.h"
+
class BrowserBox;
class Button;
class ProgressBar;
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index 56274573..c840e456 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,12 +19,14 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "ministatus.h"
#include "popupmenu.h"
#include "viewport.h"
#include "../beingmanager.h"
#include "../configuration.h"
#include "../flooritemmanager.h"
+#include "../game.h"
#include "../graphics.h"
#include "../keyboardconfig.h"
#include "../localplayer.h"
@@ -50,8 +51,13 @@ Viewport::Viewport():
mTileViewX(0),
mTileViewY(0),
mShowDebugPath(false),
+ mVisibleNames(false),
mPlayerFollowMouse(false),
+#ifdef TMWSERV_SUPPORT
+ mLocalWalkTime(-1)
+#else
mWalkTime(0)
+#endif
{
setOpaque(false);
addMouseListener(this);
@@ -60,16 +66,20 @@ Viewport::Viewport():
mScrollRadius = (int) config.getValue("ScrollRadius", 0);
mScrollCenterOffsetX = (int) config.getValue("ScrollCenterOffsetX", 0);
mScrollCenterOffsetY = (int) config.getValue("ScrollCenterOffsetY", 0);
+ mVisibleNames = config.getValue("visiblenames", 1);
config.addListener("ScrollLaziness", this);
config.addListener("ScrollRadius", this);
+ config.addListener("visiblenames", this);
- mPopupMenu = new PopupMenu();
+ mPopupMenu = new PopupMenu;
}
Viewport::~Viewport()
{
delete mPopupMenu;
+
+ config.removeListener("visiblenames", this);
}
void Viewport::setMap(Map *map)
@@ -77,6 +87,8 @@ void Viewport::setMap(Map *map)
mMap = map;
}
+extern MiniStatusWindow *miniStatusWindow;
+
void Viewport::draw(gcn::Graphics *gcnGraphics)
{
static int lastTick = tick_time;
@@ -97,6 +109,14 @@ void Viewport::draw(gcn::Graphics *gcnGraphics)
}
// Calculate viewpoint
+#ifdef TMWSERV_SUPPORT
+ int midTileX = (graphics->getWidth() + mScrollCenterOffsetX) / 2;
+ int midTileY = (graphics->getHeight() + mScrollCenterOffsetX) / 2;
+
+ const Vector &playerPos = player_node->getPosition();
+ const int player_x = (int) playerPos.x - midTileX;
+ const int player_y = (int) playerPos.y - midTileY;
+#else
int midTileX = (graphics->getWidth() + mScrollCenterOffsetX) / 32 / 2;
int midTileY = (graphics->getHeight() + mScrollCenterOffsetY) / 32 / 2;
@@ -104,6 +124,7 @@ void Viewport::draw(gcn::Graphics *gcnGraphics)
player_node->getXOffset();
int player_y = (player_node->mY - midTileY) * 32 +
player_node->getYOffset();
+#endif
if (mScrollLaziness < 1)
mScrollLaziness = 1; // Avoids division by zero
@@ -146,8 +167,10 @@ void Viewport::draw(gcn::Graphics *gcnGraphics)
};
// Don't move camera so that the end of the map is on screen
- int viewXmax = (mMap->getWidth() * 32) - graphics->getWidth();
- int viewYmax = (mMap->getHeight() * 32) - graphics->getHeight();
+ const int viewXmax =
+ mMap->getWidth() * mMap->getTileWidth() - graphics->getWidth();
+ const int viewYmax =
+ mMap->getHeight() * mMap->getTileHeight() - graphics->getHeight();
if (mMap)
{
if (mPixelViewX < 0)
@@ -168,30 +191,13 @@ void Viewport::draw(gcn::Graphics *gcnGraphics)
{
mMap->draw(graphics, (int) mPixelViewX, (int) mPixelViewY);
- // Find a path from the player to the mouse, and draw it. This is for
- // debug purposes.
- if (mShowDebugPath)
- {
- // Get the current mouse position
- SDL_GetMouseState(&mMouseX, &mMouseY);
-
- int mouseTileX = mMouseX / 32 + mTileViewX;
- int mouseTileY = mMouseY / 32 + mTileViewY;
-
- Path debugPath = mMap->findPath(player_node->mX, player_node->mY,
- mouseTileX, mouseTileY);
-
- graphics->setColor(gcn::Color(255, 0, 0));
- for (PathIterator i = debugPath.begin(); i != debugPath.end(); i++)
- {
- int squareX = i->x * 32 - (int) mPixelViewX + 12;
- int squareY = i->y * 32 - (int) mPixelViewY + 12;
-
- graphics->fillRectangle(gcn::Rectangle(squareX, squareY, 8, 8));
- graphics->drawText(toString(mMap->getMetaTile(i->x, i->y)->Gcost),
- squareX + 4, squareY + 12,
- gcn::Graphics::CENTER);
- }
+ if (mShowDebugPath) {
+ mMap->drawCollision(graphics,
+ (int) mPixelViewX,
+ (int) mPixelViewY);
+#if 0
+ drawDebugPath(graphics);
+#endif
}
}
@@ -215,6 +221,9 @@ void Viewport::draw(gcn::Graphics *gcnGraphics)
(*i)->drawEmotion(graphics, (int) mPixelViewX, (int) mPixelViewY);
}
+ if (miniStatusWindow)
+ miniStatusWindow->drawIcons(graphics);
+
// Draw contained widgets
WindowContainer::draw(gcnGraphics);
}
@@ -229,11 +238,51 @@ void Viewport::logic()
Uint8 button = SDL_GetMouseState(&mMouseX, &mMouseY);
if (mPlayerFollowMouse && button & SDL_BUTTON(1) &&
+#ifdef TMWSERV_SUPPORT
+ get_elapsed_time(mLocalWalkTime) >= walkingMouseDelay)
+ {
+ mLocalWalkTime = tick_time;
+ player_node->setDestination(mMouseX + (int) mPixelViewX,
+ mMouseY + (int) mPixelViewY);
+#else
mWalkTime != player_node->mWalkTime)
{
player_node->setDestination(mMouseX / 32 + mTileViewX,
mMouseY / 32 + mTileViewY);
mWalkTime = player_node->mWalkTime;
+#endif
+ }
+}
+
+void Viewport::drawDebugPath(Graphics *graphics)
+{
+ // Get the current mouse position
+ SDL_GetMouseState(&mMouseX, &mMouseY);
+
+ const int mouseTileX = (mMouseX + (int) mPixelViewX) / 32;
+ const int mouseTileY = (mMouseY + (int) mPixelViewY) / 32;
+ const Vector &playerPos = player_node->getPosition();
+
+ Path debugPath = mMap->findPath(
+ (int) playerPos.x / 32,
+ (int) playerPos.y / 32,
+ mouseTileX, mouseTileY, 0xFF);
+
+ drawPath(graphics, debugPath);
+}
+
+void Viewport::drawPath(Graphics *graphics, const Path &path)
+{
+ graphics->setColor(gcn::Color(255, 0, 0));
+ for (Path::const_iterator i = path.begin(); i != path.end(); ++i)
+ {
+ int squareX = i->x * 32 - (int) mPixelViewX + 12;
+ int squareY = i->y * 32 - (int) mPixelViewY + 12;
+
+ graphics->fillRectangle(gcn::Rectangle(squareX, squareY, 8, 8));
+ graphics->drawText(
+ toString(mMap->getMetaTile(i->x, i->y)->Gcost),
+ squareX + 4, squareY + 12, gcn::Graphics::CENTER);
}
}
@@ -249,10 +298,10 @@ void Viewport::mousePressed(gcn::MouseEvent &event)
mPlayerFollowMouse = false;
- const int tilex = event.getX() / 32 + mTileViewX;
- const int tiley = event.getY() / 32 + mTileViewY;
- const int x = (int)((float) event.getX() + mPixelViewX);
- const int y = (int)((float) event.getY() + mPixelViewY);
+ const int pixelx = event.getX() + (int) mPixelViewX;
+ const int pixely = event.getY() + (int) mPixelViewY;
+ const int tilex = pixelx / mMap->getTileWidth();
+ const int tiley = pixely / mMap->getTileHeight();
// Right click might open a popup
if (event.getButton() == gcn::MouseEvent::RIGHT)
@@ -260,7 +309,7 @@ void Viewport::mousePressed(gcn::MouseEvent &event)
Being *being;
FloorItem *floorItem;
- if ((being = beingManager->findBeingByPixel(x, y)) &&
+ if ((being = beingManager->findBeingByPixel(pixelx, pixely)) &&
being != player_node)
{
mPopupMenu->showPopup(event.getX(), event.getY(), being);
@@ -284,12 +333,13 @@ void Viewport::mousePressed(gcn::MouseEvent &event)
// Left click can cause different actions
if (event.getButton() == gcn::MouseEvent::LEFT)
{
- Being *being;
FloorItem *item;
+#ifdef EATHENA_SUPPORT
+ Being *being;
// Interact with some being
// if ((being = beingManager->findBeing(tilex, tiley)))
- if ((being = beingManager->findBeingByPixel(x, y)))
+ if ((being = beingManager->findBeingByPixel(pixelx, pixely)))
{
switch (being->getType())
{
@@ -320,22 +370,38 @@ void Viewport::mousePressed(gcn::MouseEvent &event)
}
}
// Pick up some item
- else if ((item = floorItemManager->findByCoordinates(tilex, tiley)))
+ else
+#endif
+ if ((item = floorItemManager->findByCoordinates(tilex, tiley)))
{
player_node->pickUp(item);
}
// Just walk around
else
{
+#ifdef TMWSERV_SUPPORT
+ // FIXME: REALLY UGLY!
+ Uint8 *keys = SDL_GetKeyState(NULL);
+ if (!(keys[SDLK_LSHIFT] || keys[SDLK_RSHIFT]) &&
+ get_elapsed_time(mLocalWalkTime) >= walkingMouseDelay)
+ {
+ mLocalWalkTime = tick_time;
+ player_node->setDestination(event.getX() + (int) mPixelViewX,
+ event.getY() + (int) mPixelViewY);
+ }
+#else
player_node->stopAttack();
player_node->setDestination(tilex, tiley);
+#endif
mPlayerFollowMouse = true;
}
}
else if (event.getButton() == gcn::MouseEvent::MIDDLE)
{
// Find the being nearest to the clicked position
- Being *target = beingManager->findBeingByPixel(x, y);
+ Being *target = beingManager->findNearestLivingBeing(
+ tilex, tiley,
+ 20, Being::MONSTER);
if (target)
player_node->setTarget(target);
@@ -347,12 +413,22 @@ void Viewport::mouseDragged(gcn::MouseEvent &event)
if (!mMap || !player_node)
return;
+#ifdef TMWSERV_SUPPORT
+ if (mPlayerFollowMouse
+ && get_elapsed_time(mLocalWalkTime) >= walkingMouseDelay)
+ {
+ mLocalWalkTime = tick_time;
+ player_node->setDestination(event.getX() + (int) mPixelViewX,
+ event.getY() + (int) mPixelViewY);
+ }
+#else
if (mPlayerFollowMouse && mWalkTime == player_node->mWalkTime)
{
int destX = event.getX() / 32 + mTileViewX;
int destY = event.getY() / 32 + mTileViewY;
player_node->setDestination(destX, destY);
}
+#endif
}
void Viewport::mouseReleased(gcn::MouseEvent &event)
@@ -369,4 +445,20 @@ void Viewport::optionChanged(const std::string &name)
{
mScrollLaziness = (int) config.getValue("ScrollLaziness", 32);
mScrollRadius = (int) config.getValue("ScrollRadius", 32);
+
+ if (name == "visiblenames") {
+ mVisibleNames = config.getValue("visiblenames", 1);
+ }
+}
+
+void Viewport::mouseMoved(gcn::MouseEvent &event)
+{
+ // Check if we are on the map
+ if (!mMap || !player_node)
+ return;
+
+ const int tilex = (event.getX() + (int) mPixelViewX) / 32;
+ const int tiley = (event.getY() + (int) mPixelViewY) / 32;
+
+ mSelectedBeing = beingManager->findBeing(tilex, tiley);
}
diff --git a/src/gui/viewport.h b/src/gui/viewport.h
index 12fdb187..c051e5a2 100644
--- a/src/gui/viewport.h
+++ b/src/gui/viewport.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,6 +29,7 @@
#include "../configlistener.h"
#include "../position.h"
+class Being;
class FloorItem;
class Graphics;
class ImageSet;
@@ -37,6 +37,9 @@ class Item;
class Map;
class PopupMenu;
+/** Delay between two mouse calls when dragging mouse and move the player */
+const int walkingMouseDelay = 500;
+
/**
* The viewport on the map. Displays the current map and handles mouse input
* and the popup menu.
@@ -95,6 +98,11 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
void mouseReleased(gcn::MouseEvent &event);
/**
+ * Handles mouse move on map.
+ */
+ void mouseMoved(gcn::MouseEvent &event);
+
+ /**
* Shows a popup for an item.
* TODO Find some way to get rid of Item here
*/
@@ -131,6 +139,17 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
void scrollBy(float x, float y) { mPixelViewX += x; mPixelViewY += y; }
private:
+ /**
+ * Finds a path from the player to the mouse, and draws it. This is for
+ * debug purposes.
+ */
+ void drawDebugPath(Graphics *graphics);
+
+ /**
+ * Draws the given path.
+ */
+ void drawPath(Graphics *graphics, const Path &path);
+
Map *mMap; /**< The current map. */
int mScrollRadius;
@@ -144,11 +163,17 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
int mTileViewX; /**< Current viewpoint in tiles. */
int mTileViewY; /**< Current viewpoint in tiles. */
bool mShowDebugPath; /**< Show a path from player to pointer. */
+ bool mVisibleNames; /**< Show target names. */
bool mPlayerFollowMouse;
+#ifdef TMWSERV_SUPPORT
+ int mLocalWalkTime; /**< Timestamp before the next walk can be sent. */
+#else
int mWalkTime;
+#endif
PopupMenu *mPopupMenu; /**< Popup menu. */
+ Being *mSelectedBeing; /**< Current selected being. */
};
extern Viewport *viewport; /**< The viewport */
diff --git a/src/gui/widgets/avatar.cpp b/src/gui/widgets/avatar.cpp
new file mode 100644
index 00000000..a36c0302
--- /dev/null
+++ b/src/gui/widgets/avatar.cpp
@@ -0,0 +1,55 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "gui/widgets/avatar.h"
+
+#include "gui/icon.h"
+
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+
+#include <guichan/widgets/label.hpp>
+
+Avatar::Avatar(const std::string &name):
+ mName(name)
+{
+ setSize(110, 12);
+ mLabel = new gcn::Label(name);
+ mLabel->setSize(85, 12);
+ mLabel->setPosition(25, 0);
+ ResourceManager *resman = ResourceManager::getInstance();
+ mStatusOffline = resman->getImage("graphics/gui/circle-gray.png");
+ mStatusOnline = resman->getImage("graphics/gui/circle-green.png");
+ mStatus = new Icon(mStatusOffline);
+ mStatus->setSize(25, 12);
+ mStatus->setPosition(0, 0);
+}
+
+void Avatar::setOnline(bool online)
+{
+ mStatus->setImage(online ? mStatusOnline : mStatusOffline);
+}
+
+void Avatar::draw(gcn::Graphics *g)
+{
+ mLabel->draw(g);
+ mStatus->draw(g);
+}
diff --git a/src/gui/widgets/avatar.h b/src/gui/widgets/avatar.h
new file mode 100644
index 00000000..16972104
--- /dev/null
+++ b/src/gui/widgets/avatar.h
@@ -0,0 +1,61 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef AVATAR_H
+#define AVATAR_H
+
+#include "guichanfwd.h"
+
+#include <guichan/widget.hpp>
+
+#include <string>
+
+class Image;
+class Icon;
+
+class Avatar : public gcn::Widget
+{
+public:
+ /**
+ * Constructor.
+ * @param name Character name
+ */
+ Avatar(const std::string &name);
+
+ /**
+ * Set the avatar online status.
+ */
+ void setOnline(bool online);
+
+ /**
+ * Draws the avatar.
+ */
+ void draw(gcn::Graphics *g);
+
+private:
+ std::string mName;
+ Icon *mStatus;
+ Image *mStatusOnline;
+ Image *mStatusOffline;
+ gcn::Label *mLabel;
+};
+
+#endif // AVATAR_H
diff --git a/src/gui/widgets/channeltab.cpp b/src/gui/widgets/channeltab.cpp
new file mode 100644
index 00000000..f8c92a6e
--- /dev/null
+++ b/src/gui/widgets/channeltab.cpp
@@ -0,0 +1,70 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <guichan/widgets/label.hpp>
+
+#include "channeltab.h"
+
+#include "../browserbox.h"
+#include "../chatinput.h"
+#include "../itemlinkhandler.h"
+#include "../recorder.h"
+#include "../scrollarea.h"
+
+#include "../../beingmanager.h"
+#include "../../commandhandler.h"
+#include "../../channel.h"
+#include "../../configuration.h"
+#include "../../game.h"
+#include "../../localplayer.h"
+
+#ifdef TMWSERV_SUPPORT
+#include "../../net/tmwserv/chatserver/chatserver.h"
+#include "../../net/tmwserv/gameserver/player.h"
+#else
+#include "../../party.h"
+#include "../../net/messageout.h"
+#include "../../net/ea/protocol.h"
+#endif
+
+#include "../../resources/iteminfo.h"
+#include "../../resources/itemdb.h"
+
+#include "../../utils/dtor.h"
+#include "../../utils/gettext.h"
+#include "../../utils/strprintf.h"
+#include "../../utils/stringutils.h"
+
+ChannelTab::ChannelTab(Channel *channel) : ChatTab(channel->getName()),
+ mChannel(channel)
+{
+ channel->setTab(this);
+}
+
+ChannelTab::~ChannelTab()
+{
+}
+
+void ChannelTab::sendChat(std::string &msg) {
+#ifdef TMSERV_SUPPORT
+ Net::ChatServer::chat(getId(), msg);
+#endif
+}
diff --git a/src/gui/widgets/channeltab.h b/src/gui/widgets/channeltab.h
new file mode 100644
index 00000000..91b4f7c6
--- /dev/null
+++ b/src/gui/widgets/channeltab.h
@@ -0,0 +1,57 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef CHANNELTAB_H
+#define CHANNELTAB_H
+
+#include "chattab.h"
+
+class Channel;
+
+/**
+ * A tab for a chat channel.
+ */
+class ChannelTab : public ChatTab
+{
+ public:
+
+ Channel *getChannel() { return mChannel; }
+
+ protected:
+ friend class Channel;
+
+ /**
+ * Constructor.
+ */
+ ChannelTab(Channel *channel);
+
+ /**
+ * Destructor.
+ */
+ ~ChannelTab();
+
+ void sendChat(std::string &msg);
+
+ private:
+ Channel *mChannel;
+};
+
+#endif // CHANNELTAB_H
diff --git a/src/gui/widgets/chattab.cpp b/src/gui/widgets/chattab.cpp
new file mode 100644
index 00000000..120d4e21
--- /dev/null
+++ b/src/gui/widgets/chattab.cpp
@@ -0,0 +1,324 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <guichan/widgets/label.hpp>
+
+#include "chattab.h"
+#include "layouthelper.h"
+
+#include "../browserbox.h"
+#include "../chatinput.h"
+#include "../itemlinkhandler.h"
+#include "../recorder.h"
+#include "../scrollarea.h"
+
+#include "../../commandhandler.h"
+#include "../../configuration.h"
+#include "../../localplayer.h"
+
+#ifdef TMWSERV_SUPPORT
+#include "../../net/tmwserv/chatserver/chatserver.h"
+#include "../../net/tmwserv/gameserver/player.h"
+#else
+#include "../../net/messageout.h"
+#include "../../net/ea/protocol.h"
+#endif
+
+#include "../../resources/iteminfo.h"
+#include "../../resources/itemdb.h"
+
+#include "../../utils/strprintf.h"
+#include "../../utils/stringutils.h"
+
+ChatTab::ChatTab(const std::string &name) : Tab()
+{
+ setCaption(name);
+
+ mTextOutput = new BrowserBox;
+ mTextOutput->setOpaque(false);
+ mTextOutput->setMaxRow((int) config.getValue("ChatLogLength", 0));
+ mTextOutput->setLinkHandler(chatWindow->mItemLinkHandler);
+
+ mScrollArea = new ScrollArea(mTextOutput);
+ mScrollArea->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER,
+ gcn::ScrollArea::SHOW_ALWAYS);
+ mScrollArea->setScrollAmount(0, 1);
+ mScrollArea->setOpaque(false);
+
+ chatWindow->addTab(this);
+}
+
+ChatTab::~ChatTab()
+{
+ chatWindow->removeTab(this);
+ delete mTextOutput;
+ delete mScrollArea;
+}
+
+void ChatTab::chatLog(const char* line, int own, bool ignoreRecord)
+{
+ chatLog(std::string(line), own, ignoreRecord);
+}
+
+void ChatTab::chatLog(std::string line, int own, bool ignoreRecord)
+{
+ // Trim whitespace
+ trim(line);
+
+ if (line.empty())
+ return;
+
+ CHATLOG tmp;
+ tmp.own = own;
+ tmp.nick = "";
+ tmp.text = line;
+
+ std::string::size_type pos = line.find(" : ");
+ if (pos != std::string::npos)
+ {
+ tmp.nick = line.substr(0, pos);
+ tmp.text = line.substr(pos + 3);
+ }
+ else
+ {
+ // Fix the owner of welcome message.
+ if (line.substr(0, 7) == "Welcome")
+ {
+ own = BY_SERVER;
+ }
+ }
+
+ // *implements actions in a backwards compatible way*
+ if (own == BY_PLAYER &&
+ tmp.text.at(0) == '*' &&
+ tmp.text.at(tmp.text.length()-1) == '*')
+ {
+ tmp.text[0] = ' ';
+ tmp.text.erase(tmp.text.length() - 1);
+ own = ACT_IS;
+ }
+
+ std::string lineColor = "##C";
+ switch (own)
+ {
+ case BY_GM:
+ if (tmp.nick.empty())
+ {
+ tmp.nick = std::string(_("Global announcement:"));
+ tmp.nick += " ";
+ lineColor = "##G";
+ }
+ else
+ {
+ tmp.nick = strprintf(_("Global announcement from %s:"),
+ tmp.nick.c_str());
+ tmp.nick += " ";
+ lineColor = "##1"; // Equiv. to BrowserBox::RED
+ }
+ break;
+ case BY_PLAYER:
+ tmp.nick += CAT_NORMAL;
+ lineColor = "##Y";
+ break;
+ case BY_OTHER:
+ tmp.nick += CAT_NORMAL;
+ lineColor = "##C";
+ break;
+ case BY_SERVER:
+ tmp.nick = _("Server:");
+ tmp.nick += " ";
+ tmp.text = line;
+ lineColor = "##S";
+ break;
+ case BY_CHANNEL:
+ tmp.nick = "";
+ // TODO: Use a predefined color
+ lineColor = "##2"; // Equiv. to BrowserBox::GREEN
+ break;
+#ifdef EATHENA_SUPPORT
+ case BY_PARTY:
+ tmp.nick += CAT_NORMAL;
+ lineColor = "##P";
+ break;
+#endif
+ case ACT_WHISPER:
+ tmp.nick = strprintf(_("%s whispers:"), tmp.nick.c_str());
+ tmp.nick += " ";
+ lineColor = "##W";
+ break;
+ case ACT_IS:
+ tmp.nick += CAT_IS;
+ lineColor = "##I";
+ break;
+ case BY_LOGGER:
+ tmp.nick = "";
+ tmp.text = line;
+ lineColor = "##L";
+ break;
+ }
+
+ if (tmp.nick == ": ")
+ {
+ tmp.nick = "";
+ lineColor = "##S";
+ }
+
+#ifdef EATHENA_SUPPORT
+ if (tmp.nick.empty() && tmp.text.substr(0, 17) == "Visible GM status")
+ {
+ player_node->setGM();
+ }
+#endif
+
+ // Get the current system time
+ time_t t;
+ time(&t);
+
+ // Format the time string properly
+ std::stringstream timeStr;
+ timeStr << "[" << ((((t / 60) / 60) % 24 < 10) ? "0" : "")
+ << (int) (((t / 60) / 60) % 24)
+ << ":" << (((t / 60) % 60 < 10) ? "0" : "")
+ << (int) ((t / 60) % 60)
+ << "] ";
+
+ line = lineColor + timeStr.str() + tmp.nick + tmp.text;
+
+ // We look if the Vertical Scroll Bar is set at the max before
+ // adding a row, otherwise the max will always be a row higher
+ // at comparison.
+ if (mScrollArea->getVerticalScrollAmount() >= mScrollArea->getVerticalMaxScroll())
+ {
+ mTextOutput->addRow(line);
+ mScrollArea->setVerticalScrollAmount(mScrollArea->getVerticalMaxScroll());
+ }
+ else
+ {
+ mTextOutput->addRow(line);
+ }
+
+ mScrollArea->logic();
+ chatWindow->mRecorder->record(line.substr(3));
+}
+
+void ChatTab::chatLog(std::string &nick, std::string &msg)
+{
+ chatLog(nick + ": " + msg, nick == player_node->getName() ? BY_PLAYER : BY_OTHER, false);
+}
+
+void ChatTab::chatSend(std::string &msg)
+{
+ trim(msg);
+
+ if (msg.empty()) return;
+
+#ifdef EATHENA_SUPPORT
+ // Send party message
+ if (msg.at(0) == chatWindow->mPartyPrefix)
+ {
+ msg.erase(0, 1);
+ std::size_t length = msg.length() + 1;
+
+ if (length == 0)
+ {
+ chatLog(_("Trying to send a blank party message."), BY_SERVER, true);
+ return;
+ }
+ MessageOut outMsg(chatWindow->mNetwork);
+
+ outMsg.writeInt16(CMSG_PARTY_MESSAGE);
+ outMsg.writeInt16(length + 4);
+ outMsg.writeString(msg, length);
+ return;
+ }
+#endif
+
+ // Check for item link
+ std::string::size_type start = msg.find('[');
+ while (start != std::string::npos && msg[start+1] != '@')
+ {
+ std::string::size_type end = msg.find(']', start);
+ if (start+1 != end && end != std::string::npos)
+ {
+ // Catch multiple embeds and ignore them
+ // so it doesn't crash the client.
+ while ((msg.find('[', start + 1) != std::string::npos) &&
+ (msg.find('[', start + 1) < end))
+ {
+ start = msg.find('[', start + 1);
+ }
+
+ std::string temp = msg.substr(start + 1, end - start - 1);
+
+ toLower(trim(temp));
+
+ const ItemInfo itemInfo = ItemDB::get(temp);
+ if (itemInfo.getName() != _("Unknown item"))
+ {
+ msg.insert(end, "@@");
+ msg.insert(start+1, "|");
+ msg.insert(start+1, toString(itemInfo.getId()));
+ msg.insert(start+1, "@@");
+ }
+ }
+ start = msg.find('[', start + 1);
+ }
+
+
+ // Prepare ordinary message
+ if (msg[0] != '/')
+ {
+ sendChat(msg);
+ }
+ else
+ {
+ commandHandler->handleCommand(std::string(msg, 1));
+ }
+}
+
+void ChatTab::scroll(int amount)
+{
+ int range = mScrollArea->getHeight() / 8 * amount;
+ gcn::Rectangle scr;
+ scr.y = mScrollArea->getVerticalScrollAmount() + range;
+ scr.height = abs(range);
+ mTextOutput->showPart(scr);
+}
+
+void ChatTab::clearText()
+{
+ mTextOutput->clearRows();
+}
+
+void ChatTab::sendChat(std::string &msg) {
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::say(msg);
+#else
+ msg = player_node->getName() + " : " + msg;
+
+ MessageOut outMsg(chatWindow->mNetwork);
+ outMsg.writeInt16(CMSG_CHAT_MESSAGE);
+ // Added + 1 in order to let eAthena parse admin commands correctly
+ outMsg.writeInt16(msg.length() + 4 + 1);
+ outMsg.writeString(msg, msg.length() + 1);
+ return;
+#endif
+}
diff --git a/src/gui/widgets/chattab.h b/src/gui/widgets/chattab.h
new file mode 100644
index 00000000..a478abeb
--- /dev/null
+++ b/src/gui/widgets/chattab.h
@@ -0,0 +1,118 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef CHATTAB_H
+#define CHATTAB_H
+
+#include <guichan/widgets/container.hpp>
+
+#include "tab.h"
+
+#include "../chat.h"
+
+class BrowserBox;
+class Recorder;
+class ScrollArea;
+
+enum
+{
+ BY_GM,
+#ifdef EATHENA_SUPPORT
+ BY_PARTY,
+#endif
+ BY_PLAYER,
+ BY_OTHER,
+ BY_SERVER,
+ BY_CHANNEL,
+ ACT_WHISPER, // getting whispered at
+ ACT_IS, // equivalent to "/me" on IRC
+ BY_LOGGER
+};
+
+/**
+ * A tab for the chat window. This is special to ease chat handling.
+ */
+class ChatTab : public Tab
+{
+ public:
+ /**
+ * Constructor.
+ */
+ ChatTab(const std::string &name);
+
+ /**
+ * Destructor.
+ */
+ ~ChatTab();
+
+ /**
+ * Adds a line of text to our message list. Parameters:
+ *
+ * @param line Text message.
+ * @param own Type of message (usually the owner-type).
+ * @param channelName which channel to send the message to.
+ * @param ignoreRecord should this not be recorded?
+ */
+ void chatLog(std::string line, int own = BY_SERVER, bool ignoreRecord = false);
+ void chatLog(const char* line, int own = BY_SERVER, bool ignoreRecord = false);
+
+ /**
+ * Adds the text to the message list
+ *
+ * @param msg The message text which is to be sent.
+ *
+ */
+ void chatLog(std::string &nick, std::string &msg);
+
+ /**
+ * Determines whether the message is a command or message, then
+ * sends the given message to the game server to be said, or to the
+ * command handler
+ *
+ * @param msg The message text which is to be sent.
+ *
+ */
+ void chatSend(std::string &msg);
+
+ /**
+ * Scrolls the chat window
+ *
+ * @param amount direction and amount to scroll. Negative numbers scroll
+ * up, positive numbers scroll down. The absolute amount indicates the
+ * amount of 1/8ths of chat window real estate that should be scrolled.
+ */
+ void scroll(int amount);
+
+ void clearText();
+
+ protected:
+ friend class ChatWindow;
+
+ virtual void sendChat(std::string &msg);
+
+ ScrollArea *mScrollArea;
+ BrowserBox *mTextOutput;
+ //Recorder *mRecorder;
+};
+
+extern ChatTab *localChatTab;
+
+#endif // CHATTAB_H
diff --git a/src/gui/widgets/dropdown.cpp b/src/gui/widgets/dropdown.cpp
index 21fee368..21378772 100644
--- a/src/gui/widgets/dropdown.cpp
+++ b/src/gui/widgets/dropdown.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
- * Copyright (C) 2008 The Mana World Development Team
+ * The Mana World
+ * Copyright (C) 2006 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,28 +19,28 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <algorithm>
+#include "gui/widgets/dropdown.h"
-#include "dropdown.h"
+#include "gui/listbox.h"
+#include "gui/palette.h"
+#include "gui/scrollarea.h"
-#include "../listbox.h"
-#include "../palette.h"
-#include "../scrollarea.h"
+#include "configuration.h"
+#include "graphics.h"
-#include "../../configuration.h"
-#include "../../graphics.h"
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
-#include "../../resources/image.h"
-#include "../../resources/resourcemanager.h"
+#include "utils/dtor.h"
-#include "../../utils/dtor.h"
+#include <algorithm>
int DropDown::instances = 0;
Image *DropDown::buttons[2][2];
ImageRect DropDown::skin;
float DropDown::mAlpha = config.getValue("guialpha", 0.8);
-DropDown::DropDown(gcn::ListModel *listModel, gcn::ScrollArea *scrollArea,
+DropDown::DropDown(gcn::ListModel *listModel, gcn::ScrollArea *scrollArea,
gcn::ListBox *listBox, bool opacity):
gcn::DropDown::DropDown(listModel, scrollArea, listBox),
mOpaque(opacity)
diff --git a/src/gui/widgets/dropdown.h b/src/gui/widgets/dropdown.h
index 191740d9..601d55c8 100644
--- a/src/gui/widgets/dropdown.h
+++ b/src/gui/widgets/dropdown.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
- * Copyright (C) 2008 The Mana World Development Team
+ * The Mana World
+ * Copyright (C) 2006 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,15 +27,15 @@
class Image;
class ImageRect;
- /**
- * A drop down box from which you can select different values. It is one of
- * the most complicated Widgets you will find in Guichan. For drawing the
- * DroppedDown box it uses one ScrollArea and one ListBox. It also uses an
- * internal FocusHandler to handle the focus of the internal ScollArea and
- * ListBox. DropDown uses a ListModel to handle the list. To be able to use
- * DropDown you must give DropDown an implemented ListModel which represents
- * your list.
- */
+/**
+ * A drop down box from which you can select different values. It is one of
+ * the most complicated Widgets you will find in Guichan. For drawing the
+ * DroppedDown box it uses one ScrollArea and one ListBox. It also uses an
+ * internal FocusHandler to handle the focus of the internal ScollArea and
+ * ListBox. DropDown uses a ListModel to handle the list. To be able to use
+ * DropDown you must give DropDown an implemented ListModel which represents
+ * your list.
+ */
class DropDown : public gcn::DropDown
{
public:
@@ -58,9 +57,9 @@ class DropDown : public gcn::DropDown
*/
~DropDown();
- void draw(gcn::Graphics* graphics);
+ void draw(gcn::Graphics *graphics);
- void drawFrame(gcn::Graphics* graphics);
+ void drawFrame(gcn::Graphics *graphics);
/**
* Sets the widget to be opaque, that is sets the widget to display its
@@ -68,7 +67,7 @@ class DropDown : public gcn::DropDown
*
* @param opaque True if the widget should be opaque, false otherwise.
*/
- void setOpaque(bool opaque) {mOpaque = opaque;}
+ void setOpaque(bool opaque) { mOpaque = opaque; }
/**
* Checks if the widget is opaque, that is if the widget area displays
@@ -76,7 +75,7 @@ class DropDown : public gcn::DropDown
*
* @return True if the widget is opaque, false otherwise.
*/
- bool isOpaque() const {return mOpaque;}
+ bool isOpaque() const { return mOpaque; }
protected:
diff --git a/src/gui/widgets/layout.cpp b/src/gui/widgets/layout.cpp
index 7fab91d7..9ca82fa3 100644
--- a/src/gui/widgets/layout.cpp
+++ b/src/gui/widgets/layout.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,9 +19,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <cassert>
+#include "gui/widgets/layout.h"
-#include "layout.h"
+#include <cassert>
ContainerPlacer ContainerPlacer::at(int x, int y)
{
diff --git a/src/gui/widgets/layout.h b/src/gui/widgets/layout.h
index 04b75ca5..b9359e91 100644
--- a/src/gui/widgets/layout.h
+++ b/src/gui/widgets/layout.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,10 +22,10 @@
#ifndef WIDGET_LAYOUT_H
#define WIDGET_LAYOUT_H
-#include <vector>
-
#include <guichan/widgets/container.hpp>
+#include <vector>
+
class LayoutCell;
/**
diff --git a/src/gui/widgets/layouthelper.cpp b/src/gui/widgets/layouthelper.cpp
index ed002f99..820d2d82 100644
--- a/src/gui/widgets/layouthelper.cpp
+++ b/src/gui/widgets/layouthelper.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2009 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "layouthelper.h"
+#include "gui/widgets/layouthelper.h"
LayoutHelper::LayoutHelper(gcn::Container *container):
mContainer(container)
diff --git a/src/gui/widgets/layouthelper.h b/src/gui/widgets/layouthelper.h
index 1125d209..ddcc6b26 100644
--- a/src/gui/widgets/layouthelper.h
+++ b/src/gui/widgets/layouthelper.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2009 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,7 +22,7 @@
#ifndef LAYOUTHELPER_H
#define LAYOUTHELPER_H
-#include "layout.h"
+#include "gui/widgets/layout.h"
#include <guichan/widgetlistener.hpp>
diff --git a/src/gui/widgets/resizegrip.cpp b/src/gui/widgets/resizegrip.cpp
index 3dbf6d1a..1bb33e15 100644
--- a/src/gui/widgets/resizegrip.cpp
+++ b/src/gui/widgets/resizegrip.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,15 +19,15 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <guichan/graphics.hpp>
+#include "gui/widgets/resizegrip.h"
-#include "resizegrip.h"
+#include "configuration.h"
+#include "graphics.h"
-#include "../../configuration.h"
-#include "../../graphics.h"
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
-#include "../../resources/image.h"
-#include "../../resources/resourcemanager.h"
+#include <guichan/graphics.hpp>
Image *ResizeGrip::gripImage = 0;
int ResizeGrip::mInstances = 0;
diff --git a/src/gui/widgets/resizegrip.h b/src/gui/widgets/resizegrip.h
index 83af24da..40a40a0f 100644
--- a/src/gui/widgets/resizegrip.h
+++ b/src/gui/widgets/resizegrip.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/widgets/tab.cpp b/src/gui/widgets/tab.cpp
index 942ad3ef..af31822e 100644
--- a/src/gui/widgets/tab.cpp
+++ b/src/gui/widgets/tab.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,20 +19,21 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <guichan/widgets/label.hpp>
+#include "gui/widgets/tab.h"
+
+#include "gui/widgets/tabbedarea.h"
-#include "tab.h"
-#include "tabbedarea.h"
+#include "gui/palette.h"
-#include "../palette.h"
+#include "configuration.h"
+#include "graphics.h"
-#include "../../configuration.h"
-#include "../../graphics.h"
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
-#include "../../resources/image.h"
-#include "../../resources/resourcemanager.h"
+#include "utils/dtor.h"
-#include "../../utils/dtor.h"
+#include <guichan/widgets/label.hpp>
int Tab::mInstances = 0;
float Tab::mAlpha = config.getValue("guialpha", 0.8);
diff --git a/src/gui/widgets/tab.h b/src/gui/widgets/tab.h
index 4b331d66..3af4e2bf 100644
--- a/src/gui/widgets/tab.h
+++ b/src/gui/widgets/tab.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp
index 2c454b69..8e93d394 100644
--- a/src/gui/widgets/tabbedarea.cpp
+++ b/src/gui/widgets/tabbedarea.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,8 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "tabbedarea.h"
-#include "tab.h"
+#include "gui/widgets/tabbedarea.h"
+#include "gui/widgets/tab.h"
#include <guichan/widgets/container.hpp>
@@ -72,7 +71,7 @@ gcn::Widget* TabbedArea::getWidget(const std::string &name)
void TabbedArea::addTab(const std::string &caption, gcn::Widget *widget)
{
- Tab* tab = new Tab();
+ Tab* tab = new Tab;
tab->setCaption(caption);
mTabsToDelete.push_back(tab);
diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h
index 863ff79e..dffbd36b 100644
--- a/src/gui/widgets/tabbedarea.h
+++ b/src/gui/widgets/tabbedarea.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,6 +23,7 @@
#define TABBEDAREA_H
#include <guichan/widget.hpp>
+#include <guichan/widgets/container.hpp>
#include <guichan/widgets/tabbedarea.hpp>
#include <string>
@@ -85,9 +85,10 @@ class TabbedArea : public gcn::TabbedArea
*/
void logic();
+ int getContainerHeight() { return mWidgetContainer->getHeight(); }
+
private:
typedef std::vector< std::pair<gcn::Tab*, gcn::Widget*> > TabContainer;
};
#endif
-
diff --git a/src/gui/widgets/textpreview.cpp b/src/gui/widgets/textpreview.cpp
index 5408eebe..d0bba285 100644
--- a/src/gui/widgets/textpreview.cpp
+++ b/src/gui/widgets/textpreview.cpp
@@ -2,7 +2,7 @@
* The Mana World
* Copyright (C) 2006 The Mana World Development Team
*
- * This file is part of Aethyra based on code from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,22 +19,22 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <typeinfo>
+#include "gui/widgets/textpreview.h"
-#include "textpreview.h"
+#include "gui/gui.h"
+#include "gui/palette.h"
+#include "gui/textrenderer.h"
+#include "gui/truetypefont.h"
-#include "../gui.h"
-#include "../palette.h"
-#include "../textrenderer.h"
-#include "../truetypefont.h"
+#include "configuration.h"
-#include "../../configuration.h"
+#include <typeinfo>
float TextPreview::mAlpha = config.getValue("guialpha", 0.8);
-TextPreview::TextPreview(const std::string* text)
+TextPreview::TextPreview(const std::string &text):
+ mText(text)
{
- mText = text;
mTextAlpha = false;
mFont = gui->getFont();
mTextColor = &guiPalette->getColor(Palette::TEXT);
@@ -65,7 +65,7 @@ void TextPreview::draw(gcn::Graphics* graphics)
if (mTextBGColor && typeid(*mFont) == typeid(TrueTypeFont))
{
TrueTypeFont *font = static_cast<TrueTypeFont*>(mFont);
- int x = font->getWidth(*mText) + 1 + 2 * ((mOutline || mShadow) ? 1 :0);
+ int x = font->getWidth(mText) + 1 + 2 * ((mOutline || mShadow) ? 1 :0);
int y = font->getHeight() + 1 + 2 * ((mOutline || mShadow) ? 1 : 0);
graphics->setColor(gcn::Color((int) mTextBGColor->r,
(int) mTextBGColor->g,
@@ -74,7 +74,7 @@ void TextPreview::draw(gcn::Graphics* graphics)
graphics->fillRectangle(gcn::Rectangle(1, 1, x, y));
}
- TextRenderer::renderText(graphics, *mText, 2, 2, gcn::Graphics::LEFT,
+ TextRenderer::renderText(graphics, mText, 2, 2, gcn::Graphics::LEFT,
gcn::Color(mTextColor->r, mTextColor->g,
mTextColor->b, alpha),
mFont, mOutline, mShadow, alpha);
diff --git a/src/gui/widgets/textpreview.h b/src/gui/widgets/textpreview.h
index 8e116262..0ca343bf 100644
--- a/src/gui/widgets/textpreview.h
+++ b/src/gui/widgets/textpreview.h
@@ -2,7 +2,7 @@
* The Mana World
* Copyright (C) 2006 The Mana World Development Team
*
- * This file is part of Aethyra based on code from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,14 +32,14 @@
class TextPreview : public gcn::Widget
{
public:
- TextPreview(const std::string* text);
+ TextPreview(const std::string &text);
/**
* Sets the color the text is printed in.
*
* @param color the color to set
*/
- inline void setTextColor(const gcn::Color* color)
+ inline void setTextColor(const gcn::Color *color)
{
mTextColor = color;
}
@@ -49,7 +49,7 @@ class TextPreview : public gcn::Widget
*
* @param alpha whether to use alpha values for the text or not
*/
- inline void useTextAlpha(bool alpha)
+ inline void useTextAlpha(bool alpha)
{
mTextAlpha = alpha;
}
@@ -60,7 +60,7 @@ class TextPreview : public gcn::Widget
*
* @param color the color to set
*/
- inline void setTextBGColor(const gcn::Color* color)
+ inline void setTextBGColor(const gcn::Color *color)
{
mTextBGColor = color;
}
@@ -70,7 +70,7 @@ class TextPreview : public gcn::Widget
*
* @param color the color to set
*/
- inline void setBGColor(const gcn::Color* color)
+ inline void setBGColor(const gcn::Color *color)
{
mBGColor = color;
}
@@ -124,14 +124,14 @@ class TextPreview : public gcn::Widget
* Gets opacity for this widget (whether or not the background color
* is shown below the widget)
*/
- bool isOpaque() { return mOpaque; }
+ bool isOpaque() const { return mOpaque; }
private:
gcn::Font *mFont;
- const std::string* mText;
- const gcn::Color* mTextColor;
- const gcn::Color* mBGColor;
- const gcn::Color* mTextBGColor;
+ std::string mText;
+ const gcn::Color *mTextColor;
+ const gcn::Color *mBGColor;
+ const gcn::Color *mTextBGColor;
static float mAlpha;
bool mTextAlpha;
bool mOpaque;
diff --git a/src/gui/widgets/whispertab.cpp b/src/gui/widgets/whispertab.cpp
new file mode 100644
index 00000000..ba469c00
--- /dev/null
+++ b/src/gui/widgets/whispertab.cpp
@@ -0,0 +1,78 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <guichan/widgets/label.hpp>
+
+#include "whispertab.h"
+
+#include "../../beingmanager.h"
+#include "../../commandhandler.h"
+#include "../../channel.h"
+#include "../../configuration.h"
+#include "../../game.h"
+#include "../../localplayer.h"
+
+#ifdef TMWSERV_SUPPORT
+#include "../../net/tmwserv/chatserver/chatserver.h"
+#include "../../net/tmwserv/gameserver/player.h"
+#else
+#include "../../party.h"
+#include "../../net/messageout.h"
+#include "../../net/ea/protocol.h"
+#endif
+
+#include "../../resources/iteminfo.h"
+#include "../../resources/itemdb.h"
+
+#include "../../utils/dtor.h"
+#include "../../utils/gettext.h"
+#include "../../utils/strprintf.h"
+#include "../../utils/stringutils.h"
+
+WhisperTab::WhisperTab(const std::string &nick) :
+ ChatTab(nick),
+ mNick(nick)
+{
+}
+
+WhisperTab::~WhisperTab()
+{
+}
+
+void WhisperTab::sendChat(std::string &msg) {
+ if (msg.length() == 0) {
+ chatLog(_("Cannot send empty chat!"), BY_SERVER, false);
+ return;
+ }
+
+#ifdef TMWSERV_SUPPORT
+ Net::ChatServer::privMsg(mNick, msg);
+#else
+ MessageOut outMsg(chatWindow->mNetwork);
+ outMsg.writeInt16(CMSG_CHAT_WHISPER);
+ outMsg.writeInt16(msg.length() + 28);
+ outMsg.writeString(mNick, 24);
+ outMsg.writeString(msg, msg.length());
+#endif
+
+ chatLog(strprintf(_("%s: %s"), player_node->getName().c_str(),
+ msg.c_str()), BY_PLAYER, false);
+}
diff --git a/src/gui/widgets/whispertab.h b/src/gui/widgets/whispertab.h
new file mode 100644
index 00000000..e3ebf0f3
--- /dev/null
+++ b/src/gui/widgets/whispertab.h
@@ -0,0 +1,55 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef WHISPERTAB_H
+#define WHISPERTAB_H
+
+#include "chattab.h"
+
+class Channel;
+
+/**
+ * A tab for whispers from a single player.
+ */
+class WhisperTab : public ChatTab
+{
+ public:
+ const std::string &getNick() const { return mNick; }
+
+ protected:
+ friend class ChatWindow;
+
+ /**
+ * Constructor.
+ *
+ * @param nick the name of the player this tab is whispering to
+ */
+ WhisperTab(const std::string &nick);
+
+ ~WhisperTab();
+
+ void sendChat(std::string &msg);
+
+ private:
+ std::string mNick;
+};
+
+#endif // CHANNELTAB_H
diff --git a/src/gui/window.cpp b/src/gui/window.cpp
index 476dcd7e..3bc03fb8 100644
--- a/src/gui/window.cpp
+++ b/src/gui/window.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,7 +38,7 @@
int Window::instances = 0;
int Window::mouseResize = 0;
-Window::Window(const std::string& caption, bool modal, Window *parent, const std::string& skin):
+Window::Window(const std::string &caption, bool modal, Window *parent, const std::string &skin):
gcn::Window(caption),
mGrip(0),
mParent(parent),
@@ -248,7 +247,7 @@ void Window::setResizable(bool r)
if (r)
{
- mGrip = new ResizeGrip();
+ mGrip = new ResizeGrip;
mGrip->setX(getWidth() - mGrip->getWidth() - getChildrenArea().x);
mGrip->setY(getHeight() - mGrip->getHeight() - getChildrenArea().y);
add(mGrip);
@@ -282,7 +281,7 @@ void Window::setCloseButton(bool flag)
mCloseButton = flag;
}
-bool Window::isResizable()
+bool Window::isResizable() const
{
return mGrip;
}
@@ -546,6 +545,14 @@ void Window::setDefaultSize(int defaultX, int defaultY,
mDefaultHeight = defaultHeight;
}
+void Window::setDefaultSize()
+{
+ mDefaultX = getX();
+ mDefaultY = getY();
+ mDefaultWidth = getWidth();
+ mDefaultHeight = getHeight();
+}
+
void Window::setDefaultSize(int defaultWidth, int defaultHeight,
ImageRect::ImagePosition position,
int offsetX, int offsetY)
@@ -666,3 +673,7 @@ void Window::reflowLayout(int w, int h)
setContentSize(w, h);
}
+void Window::center()
+{
+ setLocationRelativeTo(getParent());
+}
diff --git a/src/gui/window.h b/src/gui/window.h
index 8907ead4..c41a4221 100644
--- a/src/gui/window.h
+++ b/src/gui/window.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,7 +29,6 @@
#include "../graphics.h"
#include "../guichanfwd.h"
-class GCContainer;
class ContainerPlacer;
class Layout;
class LayoutCell;
@@ -111,46 +109,34 @@ class Window : public gcn::Window, gcn::WidgetListener
/**
* Returns whether the window can be resized.
*/
- bool isResizable();
+ bool isResizable() const;
/**
* Sets the minimum width of the window.
*/
void setMinWidth(int width);
+ int getMinWidth() const { return mMinWinWidth; }
+
/**
* Sets the minimum height of the window.
*/
void setMinHeight(int height);
+ int getMinHeight() const { return mMinWinHeight; }
+
/**
* Sets the maximum width of the window.
*/
void setMaxWidth(int width);
+ int getMaxWidth() const { return mMaxWinWidth; }
+
/**
* Sets the minimum height of the window.
*/
void setMaxHeight(int height);
- /**
- * Gets the minimum width of the window.
- */
- int getMinWidth() const { return mMinWinWidth; }
-
- /**
- * Gets the minimum height of the window.
- */
- int getMinHeight() const { return mMinWinHeight; }
-
- /**
- * Gets the maximum width of the window.
- */
- int getMaxWidth() const { return mMaxWinWidth; }
-
- /**
- * Gets the minimum height of the window.
- */
int getMaxHeight() const { return mMaxWinHeight; }
/**
@@ -226,7 +212,7 @@ class Window : public gcn::Window, gcn::WidgetListener
/**
* Returns the name of the window. This is not the window title.
*/
- const std::string& getWindowName() { return mWindowName; }
+ const std::string &getWindowName() const { return mWindowName; }
/**
* Reads the position (and the size for resizable windows) in the
@@ -251,6 +237,11 @@ class Window : public gcn::Window, gcn::WidgetListener
int defaultWidth, int defaultHeight);
/**
+ * Set the default win pos and size tot he current ones.
+ */
+ void setDefaultSize();
+
+ /**
* Set the default win pos and size.
* (which can be different of the actual ones.)
* This version of setDefaultSize sets the window's position based
@@ -292,6 +283,11 @@ class Window : public gcn::Window, gcn::WidgetListener
ContainerPlacer getPlacer(int x, int y);
/**
+ * Positions the window in the center of it's parent.
+ */
+ void center();
+
+ /**
* Overrideable functionality for when the window is to close. This
* allows for class implementations to clean up or do certain actions
* on window close they couldn't do otherwise.
@@ -321,7 +317,6 @@ class Window : public gcn::Window, gcn::WidgetListener
*/
int getResizeHandles(gcn::MouseEvent &event);
- GCContainer *mChrome; /**< Contained container */
ResizeGrip *mGrip; /**< Resize grip */
Window *mParent; /**< The parent window */
Layout *mLayout; /**< Layout handler */
diff --git a/src/gui/windowcontainer.cpp b/src/gui/windowcontainer.cpp
index ad86a253..eda739b9 100644
--- a/src/gui/windowcontainer.cpp
+++ b/src/gui/windowcontainer.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/gui/windowcontainer.h b/src/gui/windowcontainer.h
index 23b221cf..bc918184 100644
--- a/src/gui/windowcontainer.h
+++ b/src/gui/windowcontainer.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/guichanfwd.h b/src/guichanfwd.h
index 8859780f..4863421c 100644
--- a/src/guichanfwd.h
+++ b/src/guichanfwd.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/guild.cpp b/src/guild.cpp
new file mode 100644
index 00000000..62c6e3f4
--- /dev/null
+++ b/src/guild.cpp
@@ -0,0 +1,69 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "guild.h"
+
+Guild::Guild(short id, short rights):
+ mId(id),
+ mCanInviteUsers(false)
+{
+ // to invite, rights must be greater than 0
+ if (rights > 0)
+ mCanInviteUsers = true;
+}
+
+void Guild::addMember(const std::string &name)
+{
+ if (!isMember(name))
+ {
+ mMembers.push_back(name);
+ }
+}
+
+void Guild::removeMember(const std::string &name)
+{
+ std::vector<std::string>::iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while(itr != itr_end)
+ {
+ if((*itr) == name)
+ {
+ mMembers.erase(itr);
+ }
+ ++itr;
+ }
+}
+
+bool Guild::isMember(const std::string &name)
+{
+ std::vector<std::string>::iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while(itr != itr_end)
+ {
+ if((*itr) == name)
+ {
+ return true;
+ }
+ ++itr;
+ }
+
+ return false;
+}
diff --git a/src/guild.h b/src/guild.h
new file mode 100644
index 00000000..9ae16f0b
--- /dev/null
+++ b/src/guild.h
@@ -0,0 +1,108 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef GUILD_H
+#define GUILD_H
+
+#include <guichan/listmodel.hpp>
+
+#include <string>
+#include <vector>
+
+class Guild : public gcn::ListModel
+{
+public:
+ /**
+ * Constructor with guild id passed to it
+ */
+ Guild(short id, short rights);
+
+ /**
+ * Set the guild's name
+ */
+ void setName(const std::string &name)
+ {
+ mName = name;
+ }
+
+ /**
+ * Add member to the list
+ */
+ void addMember(const std::string &name);
+
+ /**
+ * Get the name of the guild
+ * @return returns name of the guild
+ */
+ const std::string &getName() const
+ {
+ return mName;
+ }
+
+ /**
+ * Get the id of the guild
+ * @return Returns the id of the guild
+ */
+ short getId() const
+ {
+ return mId;
+ }
+
+ /**
+ * Remove member from the guild
+ */
+ void removeMember(const std::string &name);
+
+ /**
+ * Get size of members list
+ * @return Returns the number of members in the guild.
+ */
+ int getNumberOfElements() {
+ return mMembers.size();
+ }
+
+ /**
+ * Get member at i
+ * @return Returns the name of member.
+ */
+ std::string getElementAt(int i) {
+ return mMembers[i];
+ }
+
+ /**
+ * Get whether user can invite users to this guild
+ * @return Returns true if user can invite users
+ */
+ bool getInviteRights()
+ {
+ return mCanInviteUsers;
+ }
+
+ bool isMember(const std::string &name);
+
+private:
+ std::string mName;
+ short mId;
+ std::vector<std::string> mMembers;
+ bool mCanInviteUsers;
+};
+
+#endif
diff --git a/src/imageparticle.cpp b/src/imageparticle.cpp
index d2c955ee..557b3553 100644
--- a/src/imageparticle.cpp
+++ b/src/imageparticle.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2006 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/imageparticle.h b/src/imageparticle.h
index 3465b3e0..317b17ea 100644
--- a/src/imageparticle.h
+++ b/src/imageparticle.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2006 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/inventory.cpp b/src/inventory.cpp
index 3d1a4786..59f51e39 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,7 +29,11 @@ struct SlotUsed : public std::unary_function<Item*, bool>
{
bool operator()(const Item *item) const
{
+#ifdef TMWSERV_SUPPORT
+ return item && item->getId() && item->getQuantity();
+#else
return item && item->getId() != -1 && item->getQuantity() > 0;
+#endif
}
};
@@ -50,15 +53,19 @@ Inventory::~Inventory()
delete [] mItems;
}
-Item* Inventory::getItem(int index) const
+Item *Inventory::getItem(int index) const
{
+#ifdef TMWSERV_SUPPORT
+ if (index < 0 || index >= mSize)
+#else
if (index < 0 || index >= mSize || !mItems[index] || mItems[index]->getQuantity() <= 0)
+#endif
return 0;
return mItems[index];
}
-Item* Inventory::findItem(int itemId) const
+Item *Inventory::findItem(int itemId) const
{
for (int i = 0; i < mSize; i++)
if (mItems[i] && mItems[i]->getId() == itemId)
diff --git a/src/inventory.h b/src/inventory.h
index e23f7657..008b7ec4 100644
--- a/src/inventory.h
+++ b/src/inventory.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,8 +24,12 @@
class Item;
+#ifdef EATHENA_SUPPORT
#define INVENTORY_SIZE 102
#define STORAGE_SIZE 301
+#else
+#define INVENTORY_SIZE 50
+#endif
class Inventory
{
@@ -34,7 +37,7 @@ class Inventory
/**
* Constructor.
*/
- Inventory(int size, int offset);
+ Inventory(int size, int offset = 0);
/**
* Destructor.
@@ -62,12 +65,12 @@ class Inventory
/**
* Adds a new item in a free slot.
*/
- void addItem(int id, int quantity, bool equipment);
+ void addItem(int id, int quantity, bool equipment = false);
/**
* Sets the item at the given position.
*/
- void setItem(int index, int id, int quantity, bool equipment);
+ void setItem(int index, int id, int quantity, bool equipment = false);
/**
* Remove a item from the inventory.
@@ -109,6 +112,7 @@ class Inventory
*/
int getInventorySize() const;
+ static const int NO_SLOT_INDEX = -1; /**< Slot has no index. */
protected:
Item **mItems; /**< The holder of items */
int mSize; /**< The max number of inventory items */
diff --git a/src/item.cpp b/src/item.cpp
index 2125756a..6f04b879 100644
--- a/src/item.cpp
+++ b/src/item.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,13 +22,20 @@
#include "item.h"
#include "resources/image.h"
+#include "resources/iteminfo.h"
#include "resources/resourcemanager.h"
-Item::Item(int id, int quantity, bool equipment, bool equipped):
+Item::Item(int id, int quantity, bool equipment
+#ifdef EATHENA_SUPPORT
+ , bool equipped
+#endif
+ ):
mImage(0),
mQuantity(quantity),
- mEquipment(equipment),
- mEquipped(equipped)
+ mEquipment(equipment)
+#ifdef EATHENA_SUPPORT
+ , mEquipped(equipped)
+#endif
{
setId(id);
}
@@ -44,6 +50,11 @@ void Item::setId(int id)
{
mId = id;
+#ifdef TMWSERV_SUPPORT
+ // Types 0 and 1 are not equippable items.
+ mEquipment = id && getInfo().getType() >= 2;
+#endif
+
// Load the associated image
if (mImage)
mImage->decRef();
diff --git a/src/item.h b/src/item.h
index d67b5be4..1fd1ee88 100644
--- a/src/item.h
+++ b/src/item.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,8 +35,11 @@ class Item
/**
* Constructor.
*/
- Item(int id = -1, int quantity = 0,
- bool equipment = false, bool equipped = false);
+ Item(int id = -1, int quantity = 0, bool equipment = false
+#ifdef EATHENA_SUPPORT
+ , bool equipped = false
+#endif
+ );
/**
* Destructor.
@@ -84,6 +86,7 @@ class Item
*/
bool isEquipment() const { return mEquipment; }
+#ifdef EATHENA_SUPPORT
/**
* Sets whether this item is equipped.
*/
@@ -93,6 +96,7 @@ class Item
* Returns whether this item is equipped.
*/
bool isEquipped() const { return mEquipped; }
+#endif
/**
* Sets the inventory index of this item.
@@ -114,7 +118,9 @@ class Item
Image *mImage; /**< Item image. */
int mQuantity; /**< Number of items. */
bool mEquipment; /**< Item is equipment. */
+#ifdef EATHENA_SUPPORT
bool mEquipped; /**< Item is equipped. */
+#endif
int mInvIndex; /**< Inventory index. */
};
diff --git a/src/itemshortcut.cpp b/src/itemshortcut.cpp
index 0627ccda..2dea8c56 100644
--- a/src/itemshortcut.cpp
+++ b/src/itemshortcut.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -73,14 +72,20 @@ void ItemShortcut::useItem(int index)
{
if (item->isEquipment())
{
+#ifdef EATHENA_SUPPORT
if (item->isEquipped())
player_node->unequipItem(item);
else
+#endif
player_node->equipItem(item);
}
else
{
+#ifdef TMWSERV_SUPPORT
+ player_node->useItem(item->getInvIndex());
+#else
player_node->useItem(item);
+#endif
}
}
}
diff --git a/src/itemshortcut.h b/src/itemshortcut.h
index 4203f600..95e17f44 100644
--- a/src/itemshortcut.h
+++ b/src/itemshortcut.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/joystick.cpp b/src/joystick.cpp
index 18a09207..b72c9103 100644
--- a/src/joystick.cpp
+++ b/src/joystick.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,12 +19,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <cassert>
-
#include "configuration.h"
#include "joystick.h"
#include "log.h"
+#include <cassert>
+
int Joystick::joystickCount = 0;
void Joystick::init()
diff --git a/src/joystick.h b/src/joystick.h
index 67b5ab70..4c5390c2 100644
--- a/src/joystick.h
+++ b/src/joystick.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/keyboardconfig.cpp b/src/keyboardconfig.cpp
index 8ed23c65..06ce4ac7 100644
--- a/src/keyboardconfig.cpp
+++ b/src/keyboardconfig.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
- * Copyright (C) 2007 The Mana World Development Team
+ * Custom keyboard shortcuts configuration
+ * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au>
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/keyboardconfig.h b/src/keyboardconfig.h
index 61d7887d..f7750b30 100644
--- a/src/keyboardconfig.h
+++ b/src/keyboardconfig.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
- * Copyright (C) 2007 The Mana World Development Team
+ * Custom keyboard shortcuts configuration
+ * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au>
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index f72aa59a..4dd8f05f 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,50 +33,95 @@
#include "particle.h"
#include "simpleanimation.h"
#include "sound.h"
+#include "statuseffect.h"
#include "text.h"
#include "gui/gui.h"
+#include "gui/ministatus.h"
#include "gui/palette.h"
+#ifdef EATHENA_SUPPORT
#include "gui/storagewindow.h"
+#endif
+#ifdef TMWSERV_SUPPORT
+#include "effectmanager.h"
+#include "guild.h"
+
+#include "net/tmwserv/gameserver/player.h"
+#include "net/tmwserv/chatserver/guild.h"
+#include "net/tmwserv/chatserver/party.h"
+#endif
+
+#ifdef EATHENA_SUPPORT
#include "net/messageout.h"
-#include "net/protocol.h"
+#include "net/ea/protocol.h"
+#endif
#include "resources/animation.h"
#include "resources/imageset.h"
+#include "resources/iteminfo.h"
#include "resources/resourcemanager.h"
+#include "utils/gettext.h"
#include "utils/stringutils.h"
+#ifdef TMWSERV_SUPPORT
+const short walkingKeyboardDelay = 100;
+#endif
+
LocalPlayer *player_node = NULL;
static const int NAME_X_OFFSET = 15;
static const int NAME_Y_OFFSET = 30;
+#ifdef TMWSERV_SUPPORT
+LocalPlayer::LocalPlayer():
+ Player(65535, 0, NULL),
+ mEquipment(new Equipment),
+ mAttributeBase(NB_CHARACTER_ATTRIBUTES, -1),
+ mAttributeEffective(NB_CHARACTER_ATTRIBUTES, -1),
+ mExpCurrent(CHAR_SKILL_NB, -1),
+ mExpNext(CHAR_SKILL_NB, -1),
+ mCharacterPoints(-1),
+ mCorrectionPoints(-1),
+ mLevelProgress(0),
+#else
LocalPlayer::LocalPlayer(Uint32 id, Uint16 job, Map *map):
Player(id, job, map),
mCharId(0),
mJobXp(0),
- mLevel(0),
mJobLevel(0),
mXpForNextLevel(0), mJobXpForNextLevel(0),
- mHp(0), mMaxHp(0), mMp(0), mMaxMp(0),
- mGp(0),
+ mMp(0), mMaxMp(0),
mAttackRange(0),
- mTotalWeight(0), mMaxWeight(0),
ATK(0), MATK(0), DEF(0), MDEF(0), HIT(0), FLEE(0),
ATK_BONUS(0), MATK_BONUS(0), DEF_BONUS(0), MDEF_BONUS(0), FLEE_BONUS(0),
mStatPoint(0), mSkillPoint(0),
mStatsPointsToAttribute(0),
- mEquipment(new Equipment()),
- mXp(0), mNetwork(0),
+ mEquipment(new Equipment),
+ mNetwork(0),
+ mXp(0),
+ mInStorage(false),
+ mTargetTime(-1),
+ mLastTarget(-1),
+#endif
+ mLevel(1),
+ mMoney(0),
+ mTotalWeight(1), mMaxWeight(1),
+ mHp(1), mMaxHp(1),
mTarget(NULL), mPickUpTarget(NULL),
mTrading(false), mGoingToTarget(false),
- mTargetTime(-1), mLastAction(-1),
- mLastTarget(-1), mWalkingDir(0),
+ mLastAction(-1),
+ mWalkingDir(0),
mDestX(0), mDestY(0),
+#ifdef TMWSERV_SUPPORT
+ mLocalWalkTime(-1),
+ mInventory(new Inventory(INVENTORY_SIZE)),
+ mExpMessageTime(0)
+#else
mInventory(new Inventory(INVENTORY_SIZE, 2)),
mStorage(new Inventory(STORAGE_SIZE, 1))
+#endif
{
// Variable to keep the local player from doing certain actions before a map
// is initialized. e.g. drawing a player's name using the TextManager, since
@@ -92,7 +136,9 @@ LocalPlayer::LocalPlayer(Uint32 id, Uint16 job, Map *map):
LocalPlayer::~LocalPlayer()
{
delete mInventory;
+#ifdef EATHENA_SUPPORT
delete mStorage;
+#endif
for (int i = Being::TC_SMALL; i < Being::NUM_TC; i++)
{
@@ -105,6 +151,7 @@ LocalPlayer::~LocalPlayer()
void LocalPlayer::logic()
{
+#ifdef EATHENA_SUPPORT
switch (mAction)
{
case STAND:
@@ -120,7 +167,7 @@ void LocalPlayer::logic()
break;
case WALK:
- mFrame = (get_elapsed_time(mWalkTime) * 6) / mWalkSpeed;
+ mFrame = (get_elapsed_time(mWalkTime) * 6) / getWalkSpeed();
if (mFrame >= 6)
nextStep();
break;
@@ -161,11 +208,33 @@ void LocalPlayer::logic()
break;
}
+#endif
// Actions are allowed once per second
if (get_elapsed_time(mLastAction) >= 1000)
mLastAction = -1;
+#ifdef TMWSERV_SUPPORT
+ // Show XP messages
+ if (!mExpMessages.empty())
+ {
+ if (mExpMessageTime == 0)
+ {
+ const Vector &pos = getPosition();
+
+ particleEngine->addTextRiseFadeOutEffect(
+ mExpMessages.front(),
+ (int) pos.x + 16,
+ (int) pos.y - 16,
+ &guiPalette->getColor(Palette::EXP_INFO),
+ gui->getInfoParticleFont(), true);
+
+ mExpMessages.pop_front();
+ mExpMessageTime = 30;
+ }
+ mExpMessageTime--;
+ }
+#else
// Targeting allowed 4 times a second
if (get_elapsed_time(mLastTarget) >= 250)
mLastTarget = -1;
@@ -180,21 +249,32 @@ void LocalPlayer::logic()
if (mTarget)
{
- // Find whether target is in range
- const int rangeX = abs(mTarget->mX - mX);
- const int rangeY = abs(mTarget->mY - mY);
- const int attackRange = getAttackRange();
- const int inRange = rangeX > attackRange || rangeY > attackRange ? 1 : 0;
-
- mTarget->setTargetAnimation(
- mTargetCursor[inRange][mTarget->getTargetCursorSize()]);
-
- if (mTarget->mAction == DEAD)
- stopAttack();
-
- if (mKeepAttacking && mTarget)
- attack(mTarget, true);
+ if (mTarget->getType() == Being::NPC)
+ {
+ // NPCs are always in range
+ mTarget->setTargetAnimation(
+ mTargetCursor[0][mTarget->getTargetCursorSize()]);
+ }
+ else
+ {
+ // Find whether target is in range
+ const int rangeX = abs(mTarget->mX - mX);
+ const int rangeY = abs(mTarget->mY - mY);
+ const int attackRange = getAttackRange();
+ const int inRange = rangeX > attackRange || rangeY > attackRange
+ ? 1 : 0;
+
+ mTarget->setTargetAnimation(
+ mTargetCursor[inRange][mTarget->getTargetCursorSize()]);
+
+ if (mTarget->mAction == DEAD)
+ stopAttack();
+
+ if (mKeepAttacking && mTarget)
+ attack(mTarget, true);
+ }
}
+#endif
Being::logic();
}
@@ -225,6 +305,8 @@ void LocalPlayer::setName(const std::string &name)
void LocalPlayer::nextStep()
{
+ // TODO: Fix picking up when reaching target (this method is obsolete)
+ // TODO: Fix holding walking button to keep walking smoothly
if (mPath.empty())
{
if (mPickUpTarget)
@@ -234,10 +316,13 @@ void LocalPlayer::nextStep()
walk(mWalkingDir);
}
+ // TODO: Fix automatically walking within range of target, when wanted
if (mGoingToTarget && mTarget && withinAttackRange(mTarget))
{
mAction = Being::STAND;
+#ifdef EATHENA_SUPPORT
attack(mTarget, true);
+#endif
mGoingToTarget = false;
mPath.clear();
return;
@@ -248,17 +333,99 @@ void LocalPlayer::nextStep()
mPath.clear();
}
+#ifdef EATHENA_SUPPORT
Player::nextStep();
+#endif
+}
+
+#ifdef TMWSERV_SUPPORT
+bool LocalPlayer::checkInviteRights(const std::string &guildName)
+{
+ Guild *guild = getGuild(guildName);
+ if (guild)
+ {
+ return guild->getInviteRights();
+ }
+
+ return false;
+}
+
+void LocalPlayer::inviteToGuild(Being *being)
+{
+ // TODO: Allow user to choose which guild to invite being to
+ // For now, just invite to the first guild you have permissions to invite with
+ std::map<int, Guild*>::iterator itr = mGuilds.begin();
+ std::map<int, Guild*>::iterator itr_end = mGuilds.end();
+ for (; itr != itr_end; ++itr)
+ {
+ if (checkInviteRights(itr->second->getName()))
+ {
+ Net::ChatServer::Guild::invitePlayer(being->getName(), itr->second->getId());
+ return;
+ }
+ }
+}
+
+void LocalPlayer::inviteToParty(const std::string &name)
+{
+ Net::ChatServer::Party::invitePlayer(name);
+}
+
+void LocalPlayer::clearInventory()
+{
+ mEquipment->clear();
+ mInventory->clear();
+}
+
+void LocalPlayer::setInvItem(int index, int id, int amount)
+{
+ mInventory->setItem(index, id, amount);
+}
+
+#endif
+
+void LocalPlayer::moveInvItem(Item *item, int newIndex)
+{
+ // special case, the old and new cannot copy over each other.
+ if (item->getInvIndex() == newIndex)
+ return;
+
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::moveItem(
+ item->getInvIndex(), newIndex, item->getQuantity());
+#endif
+ // TODO: eAthena support
}
void LocalPlayer::equipItem(Item *item)
{
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::equip(item->getInvIndex());
+#else
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_PLAYER_EQUIP);
outMsg.writeInt16(item->getInvIndex());
outMsg.writeInt16(0);
+#endif
+}
+
+#ifdef TMWSERV_SUPPORT
+
+void LocalPlayer::unequipItem(int slot)
+{
+ Net::GameServer::Player::unequip(slot);
+
+ // Tidy equipment directly to avoid weapon still shown bug, for instance
+ mEquipment->setEquipment(slot, 0);
+}
+
+void LocalPlayer::useItem(int slot)
+{
+ Net::GameServer::Player::useItem(slot);
}
+#else
+
void LocalPlayer::unequipItem(Item *item)
{
if (!item)
@@ -281,48 +448,102 @@ void LocalPlayer::useItem(Item *item)
// Note: id is dest of item, usually player_node->account_ID ??
}
+#endif
+
void LocalPlayer::dropItem(Item *item, int quantity)
{
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::drop(item->getInvIndex(), quantity);
+#else
// TODO: Fix wrong coordinates of drops, serverside?
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_PLAYER_INVENTORY_DROP);
outMsg.writeInt16(item->getInvIndex());
outMsg.writeInt16(quantity);
+#endif
}
+#ifdef TMWSERV_SUPPORT
+void LocalPlayer::splitItem(Item *item, int quantity)
+{
+ int newIndex = mInventory->getFreeSlot();
+ if (newIndex > Inventory::NO_SLOT_INDEX)
+ {
+ Net::GameServer::Player::moveItem(
+ item->getInvIndex(), newIndex, quantity);
+ }
+}
+#endif
+
void LocalPlayer::pickUp(FloorItem *item)
{
+#ifdef TMWSERV_SUPPORT
+ int dx = item->getX() - (int) getPosition().x / 32;
+ int dy = item->getY() - (int) getPosition().y / 32;
+#else
int dx = item->getX() - mX;
int dy = item->getY() - mY;
+#endif
if (dx * dx + dy * dy < 4)
{
+#ifdef TMWSERV_SUPPORT
+ int id = item->getId();
+ Net::GameServer::Player::pickUp(id >> 16, id & 0xFFFF);
+#else
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_ITEM_PICKUP);
outMsg.writeInt32(item->getId());
+#endif
mPickUpTarget = NULL;
}
else
{
+#ifdef TMWSERV_SUPPORT
+ setDestination(item->getX() * 32 + 16, item->getY() * 32 + 16);
+#else
setDestination(item->getX(), item->getY());
+#endif
mPickUpTarget = item;
+#ifdef EATHENA_SUPPORT
stopAttack();
+#endif
}
}
void LocalPlayer::walk(unsigned char dir)
{
+ // TODO: Evaluate the implementation of this method for tmwserv
if (!mMap || !dir)
return;
+#ifdef TMWSERV_SUPPORT
+ const Vector &pos = getPosition();
+ int dScaler; // Distance to walk
+#endif
+
if (mAction == WALK && !mPath.empty())
{
// Just finish the current action, otherwise we get out of sync
+#ifdef TMWSERV_SUPPORT
+ Being::setDestination(pos.x, pos.y);
+#else
Being::setDestination(mX, mY);
+#endif
return;
}
int dx = 0, dy = 0;
+#ifdef TMWSERV_SUPPORT
+ if (dir & UP)
+ dy -= 32;
+ if (dir & DOWN)
+ dy += 32;
+ if (dir & LEFT)
+ dx -= 32;
+ if (dir & RIGHT)
+ dx += 32;
+#else
if (dir & UP)
dy--;
if (dir & DOWN)
@@ -331,26 +552,65 @@ void LocalPlayer::walk(unsigned char dir)
dx--;
if (dir & RIGHT)
dx++;
+#endif
+
// Prevent skipping corners over colliding tiles
- if (dx && mMap->tileCollides(mX + dx, mY))
+#ifdef TMWSERV_SUPPORT
+ if (dx && !mMap->getWalk(((int) pos.x + dx) / 32,
+ (int) pos.y / 32, getWalkMask()))
+ dx = 16 - (int) pos.x % 32;
+ if (dy && !mMap->getWalk((int) pos.x / 32,
+ ((int) pos.y + dy) / 32, getWalkMask()))
+ dy = 16 - (int) pos.y % 32;
+#else
+ if (dx && !mMap->getWalk(mX + dx, mY, getWalkMask()))
dx = 0;
- if (dy && mMap->tileCollides(mX, mY + dy))
+ if (dy && !mMap->getWalk(mX, mY + dy, getWalkMask()))
dy = 0;
+#endif
// Choose a straight direction when diagonal target is blocked
- if (dx && dy && mMap->tileCollides(mX + dx, mY + dy))
+#ifdef TMWSERV_SUPPORT
+ if (dx && dy && !mMap->getWalk((pos.x + dx) / 32,
+ (pos.y + dy) / 32, getWalkMask()))
+ dx = 16 - (int) pos.x % 32;
+
+ // Checks our path up to 5 tiles, if a blocking tile is found
+ // We go to the last good tile, and break out of the loop
+ for (dScaler = 1; dScaler <= 10; dScaler++)
+ {
+ if ( (dx || dy) &&
+ !mMap->getWalk( ((int) pos.x + (dx * dScaler)) / 32,
+ ((int) pos.y + (dy * dScaler)) / 32, getWalkMask()) )
+ {
+ dScaler--;
+ break;
+ }
+ }
+
+ if (dScaler >= 0)
+ {
+ setDestination((int) pos.x + (dx * dScaler), (int) pos.y + (dy * dScaler));
+ }
+#else
+ if (dx && dy && !mMap->getWalk(mX + dx, mY + dy, getWalkMask()))
dx = 0;
// Walk to where the player can actually go
- if ((dx || dy) && !mMap->tileCollides(mX + dx, mY + dy))
+ if ((dx || dy) && mMap->getWalk(mX + dx, mY + dy, getWalkMask()))
{
setDestination(mX + dx, mY + dy);
}
+#endif
else if (dir)
{
// If the being can't move, just change direction
- // TODO: Communicate this to the server (waiting on tmwserv)
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::changeDir(dir);
+#else
+ // TODO: Communicate this to the server
+#endif
setDirection(dir);
}
}
@@ -362,6 +622,7 @@ Being* LocalPlayer::getTarget() const
void LocalPlayer::setTarget(Being *target)
{
+#ifdef EATHENA_SUPPORT
if (mLastTarget != -1 || target == this)
return;
@@ -379,32 +640,63 @@ void LocalPlayer::setTarget(Being *target)
mKeepAttacking = false;
mTargetTime = -1;
}
+#endif
if (mTarget)
mTarget->untarget();
if (mTarget && mTarget->getType() == Being::MONSTER)
- static_cast<Monster *>(mTarget)->showName(false);
+ static_cast<Monster *>(mTarget)->setShowName(false);
mTarget = target;
if (target && target->getType() == Being::MONSTER)
- static_cast<Monster *>(target)->showName(true);
+ static_cast<Monster *>(target)->setShowName(true);
}
+#ifdef TMWSERV_SUPPORT
+void LocalPlayer::setDestination(int x, int y)
+#else
void LocalPlayer::setDestination(Uint16 x, Uint16 y)
+#endif
{
+#ifdef TMWSERV_SUPPORT
+ // Fix coordinates so that the player does not seem to dig into walls.
+ const int tx = x / 32;
+ const int ty = y / 32;
+ int fx = x % 32;
+ int fy = y % 32;
+
+ if (fx != 16 && !mMap->getWalk(tx + fx / 16 * 2 - 1, ty, getWalkMask()))
+ fx = 16;
+ if (fy != 16 && !mMap->getWalk(tx, ty + fy / 16 * 2 - 1, getWalkMask()))
+ fy = 16;
+ if (fx != 16 && fy != 16 && !mMap->getWalk(tx + fx / 16 * 2 - 1,
+ ty + fy / 16 * 2 - 1,
+ getWalkMask()))
+ fx = 16;
+
+ x = tx * 32 + fx;
+ y = ty * 32 + fy;
+#endif
+
// Only send a new message to the server when destination changes
if (x != mDestX || y != mDestY)
{
mDestX = x;
mDestY = y;
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::walk(x, y);
+ //Debugging fire burst
+ effectManager->trigger(15,x,y);
+#else
char temp[4] = "";
MessageOut outMsg(mNetwork);
set_coordinates(temp, x, y, mDirection);
outMsg.writeInt16(0x0085);
outMsg.writeString(temp, 3);
+#endif
}
mPickUpTarget = NULL;
@@ -413,18 +705,36 @@ void LocalPlayer::setDestination(Uint16 x, Uint16 y)
void LocalPlayer::setWalkingDir(int dir)
{
- if (mWalkingDir != dir)
- {
- mWalkingDir = dir;
- }
+ mWalkingDir = dir;
// If we're not already walking, start walking.
- if (mAction != WALK && dir)
+ if (mAction != WALK && dir
+#ifdef TMWSERV_SUPPORT
+ && get_elapsed_time(mLocalWalkTime) >= walkingKeyboardDelay
+#endif
+ )
{
walk(dir);
}
}
+#ifdef TMWSERV_SUPPORT
+void LocalPlayer::stopWalking(bool sendToServer)
+{
+ if (mAction == WALK && mWalkingDir) {
+ mWalkingDir = 0;
+ mLocalWalkTime = 0;
+ Being::setDestination(getPosition().x,getPosition().y);
+ if (sendToServer)
+ Net::GameServer::Player::walk(getPosition().x, getPosition().y);
+ setAction(STAND);
+ }
+
+ clearPath();
+}
+#endif
+
+#ifdef EATHENA_SUPPORT
void LocalPlayer::raiseAttribute(Attribute attr)
{
MessageOut outMsg(mNetwork);
@@ -468,6 +778,7 @@ void LocalPlayer::raiseSkill(Uint16 skillId)
outMsg.writeInt16(CMSG_SKILL_LEVELUP_REQUEST);
outMsg.writeInt16(skillId);
}
+#endif
void LocalPlayer::toggleSit()
{
@@ -475,18 +786,23 @@ void LocalPlayer::toggleSit()
return;
mLastAction = tick_time;
- char type;
+ Being::Action newAction;
switch (mAction)
{
- case STAND: type = 2; break;
- case SIT: type = 3; break;
+ case STAND: newAction = SIT; break;
+ case SIT: newAction = STAND; break;
default: return;
}
+#ifdef TMWSERV_SUPPORT
+ setAction(newAction);
+ Net::GameServer::Player::changeAction(newAction);
+#else
MessageOut outMsg(mNetwork);
outMsg.writeInt16(0x0089);
outMsg.writeInt32(0);
- outMsg.writeInt8(type);
+ outMsg.writeInt8((newAction == SIT) ? 2 : 3);
+#endif
}
void LocalPlayer::emote(Uint8 emotion)
@@ -495,11 +811,15 @@ void LocalPlayer::emote(Uint8 emotion)
return;
mLastAction = tick_time;
+ // XXX Convert for new server
+#ifdef EATHENA_SUPPORT
MessageOut outMsg(mNetwork);
outMsg.writeInt16(0x00bf);
outMsg.writeInt8(emotion);
+#endif
}
+#ifdef EATHENA_SUPPORT
void LocalPlayer::tradeReply(bool accept)
{
if (!accept)
@@ -509,12 +829,21 @@ void LocalPlayer::tradeReply(bool accept)
outMsg.writeInt16(CMSG_TRADE_RESPONSE);
outMsg.writeInt8(accept ? 3 : 4);
}
+#endif
void LocalPlayer::trade(Being *being) const
{
+#ifdef TMWSERV_SUPPORT
+ extern std::string tradePartnerName;
+ extern int tradePartnerID;
+ tradePartnerName = being->getName();
+ tradePartnerID = being->getId();
+ Net::GameServer::Player::requestTrade(tradePartnerID);
+#else
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_TRADE_REQUEST);
outMsg.writeInt32(being->getId());
+#endif
}
bool LocalPlayer::tradeRequestOk() const
@@ -522,11 +851,70 @@ bool LocalPlayer::tradeRequestOk() const
return !mTrading;
}
+#ifdef TMWSERV_SUPPORT
+
+void LocalPlayer::attack()
+{
+ if (mLastAction != -1)
+ return;
+
+ // Can only attack when standing still
+ if (mAction != STAND && mAction != ATTACK)
+ return;
+
+ //Face direction of the target
+ if(mTarget){
+ unsigned char dir = 0;
+ int x = 0, y = 0;
+ Vector plaPos = this->getPosition();
+ Vector tarPos = mTarget->getPosition();
+ x = plaPos.x - tarPos.x;
+ y = plaPos.y - tarPos.y;
+ if(abs(x) < abs(y)){
+ //Check to see if target is above me or below me
+ if(y > 0){
+ dir = UP;
+ } else {
+ dir = DOWN;
+ }
+ } else {
+ //check to see if the target is to the left or right of me
+ if(x > 0){
+ dir = LEFT;
+ } else {
+ dir = RIGHT;
+ }
+ }
+ setDirection(dir);
+ }
+
+ mLastAction = tick_time;
+
+ setAction(ATTACK);
+
+ if (mEquippedWeapon)
+ {
+ std::string soundFile = mEquippedWeapon->getSound(EQUIP_EVENT_STRIKE);
+ if (soundFile != "") sound.playSfx(soundFile);
+ }
+ else {
+ sound.playSfx("sfx/fist-swish.ogg");
+ }
+ Net::GameServer::Player::attack(getSpriteDirection());
+}
+
+void LocalPlayer::useSpecial(int special)
+{
+ Net::GameServer::Player::useSpecial(special);
+}
+
+#else
+
void LocalPlayer::attack(Being *target, bool keep)
{
mKeepAttacking = keep;
- if (!target)
+ if (!target || target->getType() == Being::NPC)
return;
if ((mTarget != target) || !mTarget)
@@ -538,10 +926,8 @@ void LocalPlayer::attack(Being *target, bool keep)
int dist_x = target->mX - mX;
int dist_y = target->mY - mY;
- // Must be standing and be within attack range to continue
- if ((mAction != STAND) || (mAttackRange < abs(dist_x)) ||
- (mAttackRange < abs(dist_y)))
- return;
+ // Must be standing to attack
+ if (mAction != STAND) return;
if (abs(dist_y) >= abs(dist_x))
{
@@ -558,9 +944,6 @@ void LocalPlayer::attack(Being *target, bool keep)
setDirection(LEFT);
}
- // Implement charging attacks here
- mLastAttackTime = 0;
-
mWalkTime = tick_time;
mTargetTime = tick_time;
@@ -597,13 +980,87 @@ void LocalPlayer::stopAttack()
mLastTarget = -1;
}
+#endif // no TMWSERV_SUPPORT
+
void LocalPlayer::revive()
{
+ // XXX Convert for new server
+#ifdef EATHENA_SUPPORT
MessageOut outMsg(mNetwork);
outMsg.writeInt16(0x00b2);
outMsg.writeInt8(0);
+#endif
+}
+
+#ifdef TMWSERV_SUPPORT
+
+void LocalPlayer::raiseAttribute(size_t attr)
+{
+ // we assume that the server allows the change. When not we will undo it later.
+ mCharacterPoints--;
+ mAttributeBase.at(attr)++;
+ Net::GameServer::Player::raiseAttribute(attr + CHAR_ATTR_BEGIN);
+}
+
+void LocalPlayer::lowerAttribute(size_t attr)
+{
+ // we assume that the server allows the change. When not we will undo it later.
+ mCorrectionPoints--;
+ mCharacterPoints++;
+ mAttributeBase.at(attr)--;
+ Net::GameServer::Player::lowerAttribute(attr + CHAR_ATTR_BEGIN);
+}
+
+const struct LocalPlayer::SkillInfo& LocalPlayer::getSkillInfo(int skill)
+{
+ static const SkillInfo skills[CHAR_SKILL_NB + 1] =
+ {
+ { _("Unarmed"), "graphics/images/unarmed.png" }, // CHAR_SKILL_WEAPON_NONE
+ { _("Knife"), "graphics/images/knife.png" }, // CHAR_SKILL_WEAPON_KNIFE
+ { _("Sword"), "graphics/images/sword.png" }, // CHAR_SKILL_WEAPON_SWORD
+ { _("Polearm"), "graphics/images/polearm.png" }, // CHAR_SKILL_WEAPON_POLEARM
+ { _("Staff"), "graphics/images/staff.png" }, // CHAR_SKILL_WEAPON_STAFF
+ { _("Whip"), "graphics/images/whip.png" }, // CHAR_SKILL_WEAPON_WHIP
+ { _("Bow"), "graphics/images/bow.png" }, // CHAR_SKILL_WEAPON_BOW
+ { _("Shooting"), "graphics/images/shooting.png" }, // CHAR_SKILL_WEAPON_SHOOTING
+ { _("Mace"), "graphics/images/mace.png" }, // CHAR_SKILL_WEAPON_MACE
+ { _("Axe"), "graphics/images/axe.png" }, // CHAR_SKILL_WEAPON_AXE
+ { _("Thrown"), "graphics/images/thrown.png" }, // CHAR_SKILL_WEAPON_THROWN
+ { _("Magic"), "graphics/images/magic.png" }, // CHAR_SKILL_MAGIC_IAMJUSTAPLACEHOLDER
+ { _("Craft"), "graphics/images/craft.png" }, // CHAR_SKILL_CRAFT_IAMJUSTAPLACEHOLDER
+ { _("Unknown Skill"), "graphics/images/unknown.png" }
+ };
+
+ if ((skill < 0) || (skill > CHAR_SKILL_NB))
+ {
+ return skills[CHAR_SKILL_NB];
+ }
+ else
+ {
+ return skills[skill];
+ }
}
+void LocalPlayer::setExperience(int skill, int current, int next)
+{
+ int diff = current - mExpCurrent.at(skill);
+ if (mMap && mExpCurrent.at(skill) != -1 && diff > 0)
+ {
+ const std::string text = toString(diff) + " " + getSkillInfo(skill).name + " xp";
+ mExpMessages.push_back(text);
+ }
+
+ mExpCurrent.at(skill) = current;
+ mExpNext.at(skill) = next;
+}
+
+std::pair<int, int> LocalPlayer::getExperience(int skill)
+{
+ return std::pair<int, int> (mExpCurrent.at(skill), mExpNext.at(skill));
+}
+
+#else
+
void LocalPlayer::setXp(int xp)
{
if (mMap && xp > mXp)
@@ -618,7 +1075,9 @@ void LocalPlayer::setXp(int xp)
mXp = xp;
}
-void LocalPlayer::pickedUp(std::string item)
+#endif
+
+void LocalPlayer::pickedUp(const std::string &item)
{
if (mMap)
{
@@ -629,8 +1088,32 @@ void LocalPlayer::pickedUp(std::string item)
}
}
+int LocalPlayer::getAttackRange()
+{
+#ifdef TMWSERV_SUPPORT
+ Item *weapon = mEquipment->getEquipment(EQUIP_FIGHT1_SLOT);
+ if (weapon)
+ {
+ const ItemInfo info = weapon->getInfo();
+ return info.getAttackRange();
+ }
+ return 32; // unarmed range
+#else
+ return mAttackRange;
+#endif
+}
+
bool LocalPlayer::withinAttackRange(Being *target)
{
+#ifdef TMWSERV_SUPPORT
+ const Vector &targetPos = target->getPosition();
+ const Vector &pos = getPosition();
+ const int dx = abs(targetPos.x - pos.x);
+ const int dy = abs(targetPos.y - pos.y);
+ const int range = getAttackRange();
+
+ return !(dx > range || dy > range);
+#else
int dist_x = abs(target->mX - mX);
int dist_y = abs(target->mY - mY);
@@ -640,14 +1123,64 @@ bool LocalPlayer::withinAttackRange(Being *target)
}
return true;
+#endif
}
void LocalPlayer::setGotoTarget(Being *target)
{
+#ifdef TMWSERV_SUPPORT
+ mTarget = target;
+ mGoingToTarget = true;
+ const Vector &targetPos = target->getPosition();
+ setDestination(targetPos.x, targetPos.y);
+#else
mLastTarget = -1;
setTarget(target);
mGoingToTarget = true;
setDestination(target->mX, target->mY);
+#endif
+}
+
+
+extern MiniStatusWindow *miniStatusWindow;
+
+void LocalPlayer::handleStatusEffect(StatusEffect *effect, int effectId)
+{
+ Being::handleStatusEffect(effect, effectId);
+
+
+
+ if (effect) {
+ effect->deliverMessage();
+ effect->playSFX();
+
+ AnimatedSprite *sprite = effect->getIcon();
+
+ if (!sprite) {
+ // delete sprite, if necessary
+ for (unsigned int i = 0; i < mStatusEffectIcons.size();)
+ if (mStatusEffectIcons[i] == effectId) {
+ mStatusEffectIcons.erase(mStatusEffectIcons.begin() + i);
+ miniStatusWindow->eraseIcon(i);
+ } else i++;
+ } else {
+ // replace sprite or append
+ bool found = false;
+
+ for (unsigned int i = 0; i < mStatusEffectIcons.size(); i++)
+ if (mStatusEffectIcons[i] == effectId) {
+ miniStatusWindow->setIcon(i, sprite);
+ found = true;
+ break;
+ }
+
+ if (!found) { // add new
+ int offset = mStatusEffectIcons.size();
+ miniStatusWindow->setIcon(offset, sprite);
+ mStatusEffectIcons.push_back(effectId);
+ }
+ }
+ }
}
void LocalPlayer::initTargetCursor()
@@ -679,7 +1212,7 @@ void LocalPlayer::loadTargetCursor(std::string filename, int width, int height,
ResourceManager *resman = ResourceManager::getInstance();
currentImageSet = resman->getImageSet(filename, width, height);
- Animation *anim = new Animation();
+ Animation *anim = new Animation;
for (unsigned int i = 0; i < currentImageSet->size(); ++i)
{
@@ -696,9 +1229,11 @@ void LocalPlayer::loadTargetCursor(std::string filename, int width, int height,
mTargetCursor[index][size] = currentCursor;
}
+#ifdef EATHENA_SUPPORT
void LocalPlayer::setInStorage(bool inStorage)
{
mInStorage = inStorage;
storageWindow->setVisible(inStorage);
}
+#endif
diff --git a/src/localplayer.h b/src/localplayer.h
index bd59462e..99cb00d6 100644
--- a/src/localplayer.h
+++ b/src/localplayer.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,19 +23,106 @@
#define LOCALPLAYER_H
#include <memory>
+#include <vector>
#include "player.h"
-// TODO move into some sane place...
-#define MAX_SLOT 2
-
class Equipment;
class FloorItem;
class ImageSet;
class Inventory;
class Item;
class Map;
+#ifdef EATHENA_SUPPORT
class Network;
+#endif
+
+#ifdef TMWSERV_SUPPORT
+
+/**
+ * Attributes used during combat. Available to all the beings.
+ */
+enum
+{
+BASE_ATTR_BEGIN = 0,
+ BASE_ATTR_PHY_ATK_MIN = BASE_ATTR_BEGIN,
+ BASE_ATTR_PHY_ATK_DELTA,
+ /**< Physical attack power. */
+ BASE_ATTR_MAG_ATK, /**< Magical attack power. */
+ BASE_ATTR_PHY_RES, /**< Resistance to physical damage. */
+ BASE_ATTR_MAG_RES, /**< Resistance to magical damage. */
+ BASE_ATTR_EVADE, /**< Ability to avoid hits. */
+ BASE_ATTR_HIT, /**< Ability to hit stuff. */
+ BASE_ATTR_HP, /**< Hit Points (Base value: maximum, Modded value: current) */
+ BASE_ATTR_HP_REGEN,/**< number of HP regenerated every 10 game ticks */
+ BASE_ATTR_END,
+ BASE_ATTR_NB = BASE_ATTR_END - BASE_ATTR_BEGIN,
+
+ BASE_ELEM_BEGIN = BASE_ATTR_END,
+ BASE_ELEM_NEUTRAL = BASE_ELEM_BEGIN,
+ BASE_ELEM_FIRE,
+ BASE_ELEM_WATER,
+ BASE_ELEM_EARTH,
+ BASE_ELEM_AIR,
+ BASE_ELEM_SACRED,
+ BASE_ELEM_DEATH,
+ BASE_ELEM_END,
+ BASE_ELEM_NB = BASE_ELEM_END - BASE_ELEM_BEGIN,
+
+ NB_BEING_ATTRIBUTES = BASE_ELEM_END
+};
+
+/**
+ * Attributes of characters. Used to derive being attributes.
+ */
+enum
+{
+ CHAR_ATTR_BEGIN = NB_BEING_ATTRIBUTES,
+ CHAR_ATTR_STRENGTH = CHAR_ATTR_BEGIN,
+ CHAR_ATTR_AGILITY,
+ CHAR_ATTR_DEXTERITY,
+ CHAR_ATTR_VITALITY,
+ CHAR_ATTR_INTELLIGENCE,
+ CHAR_ATTR_WILLPOWER,
+ CHAR_ATTR_END,
+ CHAR_ATTR_NB = CHAR_ATTR_END - CHAR_ATTR_BEGIN,
+
+ CHAR_SKILL_BEGIN = CHAR_ATTR_END,
+
+ CHAR_SKILL_WEAPON_BEGIN = CHAR_SKILL_BEGIN,
+ CHAR_SKILL_WEAPON_NONE = CHAR_SKILL_WEAPON_BEGIN,
+ CHAR_SKILL_WEAPON_KNIFE,
+ CHAR_SKILL_WEAPON_SWORD,
+ CHAR_SKILL_WEAPON_POLEARM,
+ CHAR_SKILL_WEAPON_STAFF,
+ CHAR_SKILL_WEAPON_WHIP,
+ CHAR_SKILL_WEAPON_BOW,
+ CHAR_SKILL_WEAPON_SHOOTING,
+ CHAR_SKILL_WEAPON_MACE,
+ CHAR_SKILL_WEAPON_AXE,
+ CHAR_SKILL_WEAPON_THROWN,
+ CHAR_SKILL_WEAPON_END,
+ CHAR_SKILL_WEAPON_NB = CHAR_SKILL_WEAPON_END - CHAR_SKILL_WEAPON_BEGIN,
+
+ CHAR_SKILL_MAGIC_BEGIN = CHAR_SKILL_WEAPON_END,
+ CHAR_SKILL_MAGIC_IAMJUSTAPLACEHOLDER = CHAR_SKILL_MAGIC_BEGIN,
+ // add magic skills here
+ CHAR_SKILL_MAGIC_END,
+ CHAR_SKILL_MAGIC_NB = CHAR_SKILL_MAGIC_END - CHAR_SKILL_MAGIC_BEGIN,
+
+ CHAR_SKILL_CRAFT_BEGIN = CHAR_SKILL_MAGIC_END,
+ CHAR_SKILL_CRAFT_IAMJUSTAPLACEHOLDER = CHAR_SKILL_CRAFT_BEGIN,
+ // add crafting skills here
+ CHAR_SKILL_CRAFT_END,
+ CHAR_SKILL_CRAFT_NB = CHAR_SKILL_CRAFT_END - CHAR_SKILL_CRAFT_BEGIN,
+
+ CHAR_SKILL_END = CHAR_SKILL_CRAFT_END,
+ CHAR_SKILL_NB = CHAR_SKILL_END - CHAR_SKILL_BEGIN,
+
+ NB_CHARACTER_ATTRIBUTES = CHAR_SKILL_END
+};
+
+#endif
/**
* The local player character.
@@ -46,13 +132,21 @@ class LocalPlayer : public Player
public:
enum Attribute
{
+#ifdef TMWSERV_SUPPORT
+ STR = 0, AGI, DEX, VIT, INT, WIL, CHR
+#else
STR = 0, AGI, VIT, INT, DEX, LUK
+#endif
};
/**
* Constructor.
*/
+#ifdef TMWSERV_SUPPORT
+ LocalPlayer();
+#else
LocalPlayer(Uint32 id, Uint16 job, Map *map);
+#endif
/**
* Destructor.
@@ -60,8 +154,11 @@ class LocalPlayer : public Player
~LocalPlayer();
virtual void setName(const std::string &name);
+
+#ifdef EATHENA_SUPPORT
void setNetwork(Network *network) { mNetwork = network; }
Network *getNetwork() {return mNetwork; }
+#endif
virtual void logic();
/**
@@ -75,10 +172,37 @@ class LocalPlayer : public Player
*/
Inventory* getInventory() const { return mInventory; }
+#ifdef EATHENA_SUPPORT
/**
* Returns the player's storage
*/
Inventory* getStorage() const { return mStorage; }
+#endif
+
+#ifdef TMWSERV_SUPPORT
+ /**
+ * Check the player has permission to invite users to specific guild
+ */
+ bool checkInviteRights(const std::string &guildName);
+
+ /**
+ * Invite a player to join guild
+ */
+ void inviteToGuild(Being *being);
+
+ /**
+ * Invite a player to join their party
+ */
+ void inviteToParty(const std::string &name);
+
+ void clearInventory();
+ void setInvItem(int index, int id, int amount);
+#endif
+
+ /**
+ * Move the Inventory item from the old slot to the new slot.
+ */
+ void moveInvItem(Item *item, int newIndex);
/**
* Equips an item.
@@ -88,21 +212,37 @@ class LocalPlayer : public Player
/**
* Unequips an item.
*/
+#ifdef TMWSERV_SUPPORT
+ void unequipItem(int slot);
+#else
void unequipItem(Item *item);
+#endif
+#ifdef TMWSERV_SUPPORT
+ void useItem(int slot);
+#else
void useItem(Item *item);
+#endif
+
void dropItem(Item *item, int quantity);
+
+#ifdef TMWSERV_SUPPORT
+ void splitItem(Item *item, int quantity);
+#endif
+
void pickUp(FloorItem *item);
+#ifdef EATHENA_SUPPORT
/**
* Sets the attack range.
*/
void setAttackRange(int range) { mAttackRange = range; }
+#endif
/**
* Gets the attack range.
*/
- int getAttackRange() const { return mAttackRange; }
+ int getAttackRange();
/**
* Sents a trade request to the given being.
@@ -126,7 +266,12 @@ class LocalPlayer : public Player
*/
void setTrading(bool trading) { mTrading = trading; }
+#ifdef TMWSERV_SUPPORT
+ void attack();
+ void useSpecial(int id);
+#else
void attack(Being *target = NULL, bool keep = false);
+#endif
/**
* Triggers whether or not to show the name as a GM name.
@@ -136,7 +281,9 @@ class LocalPlayer : public Player
*/
virtual void setGM();
+#ifdef EATHENA_SUPPORT
void stopAttack();
+#endif
/**
* Overridden to do nothing. The attacks of the local player are
@@ -148,12 +295,15 @@ class LocalPlayer : public Player
* @param type the attack type
*/
virtual void handleAttack(Being *victim, int damage, AttackType type) {}
+ virtual void handleAttack() {}
+
/**
* Returns the current target of the player. Returns 0 if no being is
* currently targeted.
*/
Being* getTarget() const;
+
/**
* Sets the target being of the player.
*/
@@ -162,7 +312,11 @@ class LocalPlayer : public Player
/**
* Sets a new destination for this being to walk to.
*/
+#ifdef TMWSERV_SUPPORT
+ void setDestination(int x, int y);
+#else
virtual void setDestination(Uint16 x, Uint16 y);
+#endif
/**
* Sets a new direction to keep walking in.
@@ -170,6 +324,12 @@ class LocalPlayer : public Player
void setWalkingDir(int dir);
/**
+ * Gets the walking direction
+ */
+ int getWalkingDir() const
+ { return mWalkingDir; }
+
+ /**
* Sets going to being to attack
*/
void setGotoTarget(Being *target);
@@ -179,8 +339,26 @@ class LocalPlayer : public Player
*/
bool withinAttackRange(Being *target);
+#ifdef EATHENA_SUPPORT
void raiseAttribute(Attribute attr);
void raiseSkill(Uint16 skillId);
+#else
+
+ /**
+ * Stops the player dead in his tracks
+ */
+ void stopWalking(bool sendToServer = true);
+
+ /**
+ * Uses a character point to raise an attribute
+ */
+ void raiseAttribute(size_t attr);
+
+ /**
+ * Uses a correction point to lower an attribute
+ */
+ void lowerAttribute(size_t attr);
+#endif
void toggleSit();
void emote(Uint8 emotion);
@@ -188,6 +366,12 @@ class LocalPlayer : public Player
void revive();
/**
+ * Shows item pickup effect if the player is on a map.
+ */
+ void pickedUp(const std::string &item);
+
+#ifdef EATHENA_SUPPORT
+ /**
* Accessors for mInStorage
*/
bool getInStorage() { return mInStorage; }
@@ -200,11 +384,6 @@ class LocalPlayer : public Player
void setXp(int xp);
/**
- * Shows item pickup effect if the player is on a map.
- */
- void pickedUp(std::string item);
-
- /**
* Returns the amount of experience points.
*/
int getXp() const { return mXp; }
@@ -212,16 +391,12 @@ class LocalPlayer : public Player
Uint32 mCharId; /**< Used only during character selection. */
Uint32 mJobXp;
- Uint16 mLevel;
Uint32 mJobLevel;
Uint32 mXpForNextLevel, mJobXpForNextLevel;
- Uint16 mHp, mMaxHp, mMp, mMaxMp;
- Uint32 mGp;
+ Uint16 mMp, mMaxMp;
Uint16 mAttackRange;
- int mTotalWeight, mMaxWeight;
-
Uint8 mAttr[6];
Uint8 mAttrUp[6];
@@ -230,6 +405,88 @@ class LocalPlayer : public Player
Uint16 mStatPoint, mSkillPoint;
Uint16 mStatsPointsToAttribute;
+#endif
+
+ int getHp() const
+ { return mHp; }
+
+ int getMaxHp() const
+ { return mMaxHp; }
+
+ void setHp(int value)
+ { mHp = value; }
+
+ void setMaxHp(int value)
+ { mMaxHp = value; }
+
+ int getLevel() const
+ { return mLevel; }
+
+ void setLevel(int value)
+ { mLevel = value; }
+
+#ifdef TMWSERV_SUPPORT
+ void setLevelProgress(int percent)
+ { mLevelProgress = percent; }
+
+ int getLevelProgress() const
+ { return mLevelProgress; }
+#endif
+
+ int getMoney() const
+ { return mMoney; }
+
+ void setMoney(int value)
+ { mMoney = value; }
+
+ int getTotalWeight() const
+ { return mTotalWeight; }
+
+ void setTotalWeight(int value)
+ { mTotalWeight = value; }
+
+ int getMaxWeight() const
+ { return mMaxWeight; }
+
+ void setMaxWeight(int value)
+ { mMaxWeight = value; }
+
+#ifdef TMWSERV_SUPPORT
+ int getAttributeBase(int num) const
+ { return mAttributeBase[num]; }
+
+ void setAttributeBase(int num, int value)
+ { mAttributeBase[num] = value; }
+
+ int getAttributeEffective(int num) const
+ { return mAttributeEffective[num]; }
+
+ void setAttributeEffective(int num, int value)
+ { mAttributeEffective[num] = value; }
+
+ int getCharacterPoints() const
+ { return mCharacterPoints; }
+
+ void setCharacterPoints(int n)
+ { mCharacterPoints = n; }
+
+ int getCorrectionPoints() const
+ { return mCorrectionPoints; }
+
+ void setCorrectionPoints(int n)
+ { mCorrectionPoints = n; }
+
+ void setExperience(int skill, int current, int next);
+
+ struct SkillInfo {
+ std::string name;
+ std::string icon;
+ };
+
+ static const SkillInfo& getSkillInfo(int skill);
+
+ std::pair<int, int> getExperience(int skill);
+#endif
bool mUpdateName; /** Whether or not the name settings have changed */
@@ -240,27 +497,57 @@ class LocalPlayer : public Player
const std::auto_ptr<Equipment> mEquipment;
protected:
+ virtual void
+ handleStatusEffect(StatusEffect *effect, int effectId);
+
void walk(unsigned char dir);
+#ifdef EATHENA_SUPPORT
+ Network *mNetwork;
int mXp; /**< Experience points. */
+ bool mInStorage; /**< Whether storage is currently accessible */
+ int mTargetTime; /** How long the being has been targeted **/
+ int mLastTarget; /** Time stamp of last targeting action, -1 if none. */
+#endif
+
+#ifdef TMWSERV_SUPPORT
+ // Character status:
+ std::vector<int> mAttributeBase;
+ std::vector<int> mAttributeEffective;
+ std::vector<int> mExpCurrent;
+ std::vector<int> mExpNext;
+ int mCharacterPoints;
+ int mCorrectionPoints;
+ int mLevelProgress;
+#endif
+ int mLevel;
+ int mMoney;
+ int mTotalWeight;
+ int mMaxWeight;
+ int mHp;
+ int mMaxHp;
- Network *mNetwork;
Being *mTarget;
FloorItem *mPickUpTarget;
bool mTrading;
- bool mInStorage; /**< Whether storage is currently accessible */
bool mGoingToTarget;
bool mKeepAttacking; /** Whether or not to continue to attack */
- int mTargetTime; /** How long the being has been targeted **/
int mLastAction; /**< Time stamp of the last action, -1 if none. */
- int mLastTarget; /** Time stamp of last targeting action, -1 if none. */
int mWalkingDir; /**< The direction the player is walking in. */
int mDestX; /**< X coordinate of destination. */
int mDestY; /**< Y coordinate of destination. */
+#ifdef TMWSERV_SUPPORT
+ int mLocalWalkTime; /**< Timestamp used to control keyboard walk
+ messages flooding */
+#endif
+
+ std::vector<int> mStatusEffectIcons;
Inventory *mInventory;
+#ifdef EATHENA_SUPPORT
Inventory *mStorage;
+#endif
// Load the target cursors into memory
void initTargetCursor();
@@ -276,6 +563,11 @@ class LocalPlayer : public Player
/** Animated target cursors. */
SimpleAnimation *mTargetCursor[2][NUM_TC];
+
+#ifdef TMWSERV_SUPPORT
+ std::list<std::string> mExpMessages; /**< Queued exp messages*/
+ int mExpMessageTime;
+#endif
};
extern LocalPlayer *player_node;
diff --git a/src/lockedarray.h b/src/lockedarray.h
index 3ef2bb99..c4c83ea9 100644
--- a/src/lockedarray.h
+++ b/src/lockedarray.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -45,7 +44,7 @@ class LockedArray
bool isLocked() const { return mLocked; };
T getEntry() const { return mData[mCurEntry]; };
- void setEntry(T entry) { mData[mCurEntry] = entry; };
+ void setEntry(T entry) { mData[mCurEntry] = entry; mFilled = true; };
void next();
void prev();
@@ -54,6 +53,11 @@ class LockedArray
unsigned int getSize() const { return mSize; };
+ /**
+ * Clears the array without changing size or data type
+ */
+ void clear();
+
protected:
unsigned int mSize;
@@ -61,11 +65,14 @@ class LockedArray
unsigned int mCurEntry;
bool mLocked;
+
+ bool mFilled;
};
template<class T>
LockedArray<T>::LockedArray(unsigned int size):
- mSize(size), mData(new T[size]), mCurEntry(0), mLocked(false)
+ mSize(size), mData(new T[size]), mCurEntry(0), mLocked(false),
+ mFilled(false)
{
std::fill_n(mData, mSize, (T)0);
}
@@ -106,4 +113,19 @@ void LockedArray<T>::select(unsigned int pos)
mCurEntry = 0;
}
+template<class T>
+void LockedArray<T>::clear()
+{
+ if (!mFilled) return;
+
+ delete [] mData;
+
+ mData = new T[mSize];
+
+ std::fill_n(mData, mSize, (T)0);
+
+ mCurEntry = 0;
+
+ mLocked = false;
+}
#endif
diff --git a/src/log.cpp b/src/log.cpp
index 29eeb010..75b015da 100644
--- a/src/log.cpp
+++ b/src/log.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -104,7 +103,7 @@ void Logger::log(const char *log_text, ...)
if (mChatWindow)
{
- mChatWindow->chatLog(buf, BY_LOGGER);
+ localChatTab->chatLog(buf, BY_LOGGER);
}
// Delete temporary buffer
diff --git a/src/log.h b/src/log.h
index a50eab9d..b06bdc89 100644
--- a/src/log.h
+++ b/src/log.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/logindata.h b/src/logindata.h
index 3f686a22..ae89eb5f 100644
--- a/src/logindata.h
+++ b/src/logindata.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,21 +24,51 @@
#include <string>
+#include <string>
+
struct LoginData
{
std::string username;
std::string password;
+ std::string newPassword;
std::string hostname;
std::string updateHost;
+#ifdef TMWSERV_SUPPORT
+ std::string email;
+ std::string newEmail;
+#endif
short port;
+#ifdef EATHENA_SUPPORT
int account_ID;
int session_ID1;
int session_ID2;
char sex;
+#endif
bool remember; /**< Whether to store the username and host. */
bool registerLogin; /**< Whether an account is being registered. */
-};
+ void clear()
+ {
+ username.clear();
+ password.clear();
+ newPassword.clear();
+ hostname.clear();
+ updateHost.clear();
+#ifdef TMWSERV_SUPPORT
+ email.clear();
+ newEmail.clear();
#endif
+ port = 0;
+
+#ifdef EATHENA_SUPPORT
+ account_ID = 0;
+ session_ID1 = 0;
+ session_ID2 = 0;
+ sex = 0;
+#endif
+ };
+};
+
+#endif // LOGINDATA_H
diff --git a/src/main.cpp b/src/main.cpp
index 014154e2..2ce47ac6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,18 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <getopt.h>
-#include <iostream>
-#include <physfs.h>
-#include <SDL_image.h>
-#include <unistd.h>
-#include <vector>
-
-#include <guichan/actionlistener.hpp>
-
-#include <libxml/parser.h>
-
-#include <SDL/SDL_ttf.h>
+#include "main.h"
#include "configuration.h"
#include "emoteshortcut.h"
@@ -43,16 +31,19 @@
#include "lockedarray.h"
#include "log.h"
#include "logindata.h"
-#include "main.h"
#ifdef USE_OPENGL
#include "openglgraphics.h"
#endif
#include "player_relations.h"
#include "serverinfo.h"
#include "sound.h"
+#include "statuseffect.h"
+#include "units.h"
#include "gui/button.h"
+#ifdef EATHENA_SUPPORT
#include "gui/char_server.h"
+#endif
#include "gui/char_select.h"
#include "gui/gui.h"
#include "gui/label.h"
@@ -63,13 +54,35 @@
#include "gui/register.h"
#include "gui/sdlinput.h"
#include "gui/setup.h"
+#ifdef TMWSERV_SUPPORT
+#include "gui/connection.h"
+#include "gui/quitdialog.h"
+#include "gui/serverdialog.h"
+#endif
#include "gui/updatewindow.h"
-#include "net/charserverhandler.h"
-#include "net/loginhandler.h"
-#include "net/maploginhandler.h"
+#ifdef TMWSERV_SUPPORT
+#include "net/tmwserv/charserverhandler.h"
+#include "net/tmwserv/connection.h"
+#include "net/tmwserv/loginhandler.h"
+#include "net/tmwserv/logouthandler.h"
+#include "net/tmwserv/network.h"
+#else
+#include "net/ea/charserverhandler.h"
+#include "net/ea/loginhandler.h"
+#include "net/ea/network.h"
+#include "net/ea/maploginhandler.h"
#include "net/messageout.h"
-#include "net/network.h"
+#endif
+
+#ifdef TMWSERV_SUPPORT
+#include "net/tmwserv/accountserver/accountserver.h"
+#include "net/tmwserv/accountserver/account.h"
+
+#include "net/tmwserv/chatserver/chatserver.h"
+
+#include "net/tmwserv/gameserver/gameserver.h"
+#endif
#include "resources/colordb.h"
#include "resources/emotedb.h"
@@ -79,8 +92,24 @@
#include "resources/npcdb.h"
#include "resources/resourcemanager.h"
+#ifdef TMWSERV_SUPPORT
+#include "utils/dtor.h"
+#endif
#include "utils/gettext.h"
#include "utils/stringutils.h"
+#include "utils/strprintf.h"
+
+#include <SDL_image.h>
+
+#include <guichan/actionlistener.hpp>
+
+#include <libxml/parser.h>
+
+#include <getopt.h>
+#include <iostream>
+#include <physfs.h>
+#include <unistd.h>
+#include <vector>
#ifdef __APPLE__
#include <CoreFoundation/CFBundle.h>
@@ -109,29 +138,43 @@ namespace
} listener;
}
+#ifdef TMWSERV_SUPPORT
+std::string token; //used to store magic_token
+#else
// Account infos
char n_server, n_character;
-Graphics *graphics;
-
// TODO Anyone knows a good location for this? Or a way to make it non-global?
class SERVER_INFO;
SERVER_INFO **server_info;
+#endif
+
+Graphics *graphics;
unsigned char state;
std::string errorMessage;
-unsigned char screen_mode;
Sound sound;
Music *bgm;
Configuration config; /**< XML file configuration reader */
+Configuration branding; /**< XML branding information reader */
Logger *logger; /**< Log object */
KeyboardConfig keyboard;
+#ifdef TMWSERV_SUPPORT
+Net::Connection *gameServerConnection = 0;
+Net::Connection *chatServerConnection = 0;
+Net::Connection *accountServerConnection = 0;
+#endif
+
CharServerHandler charServerHandler;
LoginData loginData;
-LockedArray<LocalPlayer*> charInfo(MAX_SLOT + 1);
+#ifdef TMWSERV_SUPPORT
+LoginHandler loginHandler;
+LogoutHandler logoutHandler;
+#endif
+LockedArray<LocalPlayer*> charInfo(maxSlot + 1);
Palette *guiPalette;
@@ -142,8 +185,10 @@ std::string homeDir;
std::string updateHost;
std::string updatesDir;
+#ifdef EATHENA_SUPPORT
LoginHandler loginHandler;
MapLoginHandler mapLoginHandler;
+#endif
SDL_Surface *icon;
@@ -160,8 +205,9 @@ struct Options
printHelp(false),
printVersion(false),
skipUpdate(false),
- chooseDefault(false)
- {};
+ chooseDefault(false),
+ serverPort(0)
+ {}
bool printHelp;
bool printVersion;
@@ -169,10 +215,13 @@ struct Options
bool chooseDefault;
std::string username;
std::string password;
- std::string playername;
+ std::string character;
std::string configPath;
std::string updateHost;
std::string dataPath;
+
+ std::string serverName;
+ short serverPort;
};
/**
@@ -187,7 +236,7 @@ static void setUpdatesDir()
if (updateHost.empty())
{
updateHost =
- config.getValue("updatehost", "http://www.aethyra.org/updates");
+ config.getValue("updatehost", "http://updates.themanaworld.org/");
}
// Remove any trailing slash at the end of the update host
@@ -209,7 +258,7 @@ static void setUpdatesDir()
{
logger->log("Error: Invalid update host: %s", updateHost.c_str());
errorMessage = _("Invalid update host: ") + updateHost;
- state = ERROR_STATE;
+ state = STATE_ERROR;
}
}
else
@@ -242,35 +291,39 @@ static void setUpdatesDir()
logger->log("Error: %s can't be made, but doesn't exist!",
newDir.c_str());
errorMessage = _("Error creating updates directory!");
- state = ERROR_STATE;
+ state = STATE_ERROR;
}
#else
logger->log("Error: %s/%s can't be made, but doesn't exist!",
homeDir.c_str(), updatesDir.c_str());
errorMessage = _("Error creating updates directory!");
- state = ERROR_STATE;
+ state = STATE_ERROR;
#endif
}
}
}
/**
- * Do all initialization stuff
+ * Initializes the home directory. On UNIX and FreeBSD, ~/.tmw is used. On
+ * Windows and other systems we use the current working directory.
*/
-static void init_engine(const Options &options)
+static void initHomeDir()
{
- homeDir = std::string(PHYSFS_getUserDir()) + "/.aethyra";
+ homeDir = std::string(PHYSFS_getUserDir()) +
+ "/." +
+ branding.getValue("appShort", "tmw");
#if defined WIN32
if (!CreateDirectory(homeDir.c_str(), 0) &&
GetLastError() != ERROR_ALREADY_EXISTS)
#elif defined __APPLE__
- // Use Application Directory instead of .aethyra
+ // Use Application Directory instead of .tmw
homeDir = std::string(PHYSFS_getUserDir()) +
- "/Library/Application Support/Aethyra";
+ "/Library/Application Support/" +
+ branding.getValue("appName", "The Mana World");
if ((mkdir(homeDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) &&
(errno != EEXIST))
#else
- // Checking if /home/user/.Aethyra folder exists.
+ // Checking if /home/user/.tmw folder exists.
if ((mkdir(homeDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) &&
(errno != EEXIST))
#endif
@@ -280,20 +333,76 @@ static void init_engine(const Options &options)
<< std::endl;
exit(1);
}
+}
+
+/**
+ * Initialize configuration.
+ */
+static void initConfiguration(const Options &options)
+{
+ // Fill configuration with defaults
+ logger->log("Initializing configuration...");
+ std::string defaultHost = branding.getValue("defaultServer",
+ "server.themanaworld.org");
+ config.setValue("host", defaultHost);
+#ifdef TWMSERV_SUPPORT
+ int defaultPort = (int)branding.getValue("defaultPort", 9601);
+#else
+ int defaultPort = (int)branding.getValue("defaultPort", 6901);
+#endif
+ config.setValue("port", defaultPort);
+ config.setValue("hwaccel", 0);
+#if (defined __APPLE__ || defined WIN32) && defined USE_OPENGL
+ config.setValue("opengl", 1);
+#else
+ config.setValue("opengl", 0);
+#endif
+ config.setValue("screen", 0);
+ config.setValue("sound", 1);
+ config.setValue("guialpha", 0.8f);
+ config.setValue("remember", 1);
+ config.setValue("sfxVolume", 100);
+ config.setValue("musicVolume", 60);
+ config.setValue("fpslimit", 0);
+ std::string defaultUpdateHost = branding.getValue("defaultUpdateHost",
+ "http://updates.themanaworld.org");
+ config.setValue("updatehost", defaultUpdateHost);
+ config.setValue("customcursor", 1);
+ config.setValue("ChatLogLength", 128);
+
+ // Checking if the configuration file exists... otherwise create it with
+ // default options.
+ FILE *configFile = 0;
+ std::string configPath = options.configPath;
+
+ if (configPath.empty())
+ configPath = homeDir + "/config.xml";
- // Set log file
- logger->setLogFile(homeDir + std::string("/aethyra.log"));
+ configFile = fopen(configPath.c_str(), "r");
- #ifdef PACKAGE_VERSION
- logger->log("Starting Aethyra Version %s", PACKAGE_VERSION);
- #else
- logger->log("Starting Aethyra - Version not defined"));
- #endif
+ // If we can't read it, it doesn't exist !
+ if (configFile == NULL) {
+ // We reopen the file in write mode and we create it
+ configFile = fopen(configPath.c_str(), "wt");
+ }
+ if (configFile == NULL) {
+ std::cout << "Can't create " << configPath << ". "
+ << "Using Defaults." << std::endl;
+ } else {
+ fclose(configFile);
+ config.init(configPath);
+ }
+}
+/**
+ * Do all initialization stuff.
+ */
+static void initEngine(const Options &options)
+{
// Initialize SDL
logger->log("Initializing SDL...");
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) {
- std::cerr << _("Could not initialize SDL: ") <<
+ std::cerr << "Could not initialize SDL: " <<
SDL_GetError() << std::endl;
exit(1);
}
@@ -302,11 +411,13 @@ static void init_engine(const Options &options)
SDL_EnableUNICODE(1);
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+ SDL_WM_SetCaption(branding.getValue("appName", "The Mana World").c_str(), NULL);
+
ResourceManager *resman = ResourceManager::getInstance();
if (!resman->setWriteDir(homeDir)) {
std::cout << homeDir
- << _(" couldn't be set as home directory! Exiting.")
+ << " couldn't be set as home directory! Exiting."
<< std::endl;
exit(1);
}
@@ -326,7 +437,7 @@ static void init_engine(const Options &options)
if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path,
PATH_MAX))
{
- fprintf(stderr, _("Can't find Resources directory\n"));
+ fprintf(stderr, "Can't find Resources directory\n");
}
CFRelease(resourcesURL);
strncat(path, "/data", PATH_MAX - 1);
@@ -335,51 +446,6 @@ static void init_engine(const Options &options)
resman->addToSearchPath(PKG_DATADIR "data", true);
#endif
- // Fill configuration with defaults
- logger->log("Initializing configuration...");
- config.setValue("host", "www.aethyra.org");
- config.setValue("port", 21001);
- config.setValue("hwaccel", 0);
-#if (defined __APPLE__ || defined WIN32) && defined USE_OPENGL
- config.setValue("opengl", 1);
-#else
- config.setValue("opengl", 0);
-#endif
- config.setValue("screen", 0);
- config.setValue("sound", 1);
- config.setValue("guialpha", 0.8f);
- config.setValue("remember", 1);
- config.setValue("sfxVolume", 100);
- config.setValue("musicVolume", 60);
- config.setValue("fpslimit", 0);
- config.setValue("updatehost", "http://www.aethyra.org/updates");
- config.setValue("customcursor", 1);
- config.setValue("ChatLogLength", 128);
-
- // Checking if the configuration file exists... otherwise creates it with
- // default options !
- FILE *configFile = 0;
- std::string configPath = options.configPath;
-
- if (configPath.empty())
- configPath = homeDir + "/config.xml";
-
- configFile = fopen(configPath.c_str(), "r");
-
- // If we can't read it, it doesn't exist !
- if (configFile == NULL) {
- // We reopen the file in write mode and we create it
- configFile = fopen(configPath.c_str(), "wt");
- }
- if (configFile == NULL) {
- std::cout << "Can't create " << configPath << ". "
- "Using Defaults." << std::endl;
- } else {
- fclose(configFile);
- config.init(configPath);
- }
-
- SDL_WM_SetCaption("Aethyra", NULL);
#ifdef WIN32
static SDL_SysWMinfo pInfo;
SDL_GetWMInfo(&pInfo);
@@ -389,7 +455,7 @@ static void init_engine(const Options &options)
SetClassLong(pInfo.window, GCL_HICON, (LONG) icon);
}
#else
- icon = IMG_Load(PKG_DATADIR "data/icons/aethyra.png");
+ icon = IMG_Load(resman->getPath(branding.getValue("appIcon", "data/icons/tmw.png")).c_str());
if (icon)
{
SDL_SetAlpha(icon, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
@@ -404,10 +470,10 @@ static void init_engine(const Options &options)
Image::setLoadAsOpenGL(useOpenGL);
// Create the graphics context
- graphics = useOpenGL ? new OpenGLGraphics() : new Graphics();
+ graphics = useOpenGL ? new OpenGLGraphics : new Graphics;
#else
// Create the graphics context
- graphics = new Graphics();
+ graphics = new Graphics;
#endif
const int width = (int) config.getValue("screenwidth", defaultScreenWidth);
@@ -429,13 +495,17 @@ static void init_engine(const Options &options)
graphics->_beginDraw();
// Initialize the item shortcuts.
- itemShortcut = new ItemShortcut();
+ itemShortcut = new ItemShortcut;
// Initialize the emote shortcuts.
- emoteShortcut = new EmoteShortcut();
+ emoteShortcut = new EmoteShortcut;
gui = new Gui(graphics);
- state = LOGIN_STATE; /**< Initial game state */
+#ifdef TMWSERV_SUPPORT
+ state = STATE_CHOOSE_SERVER; /**< Initial game state */
+#else
+ state = STATE_LOGIN; /**< Initial game state */
+#endif
// Initialize sound engine
try
@@ -450,7 +520,7 @@ static void init_engine(const Options &options)
}
catch (const char *err)
{
- state = ERROR_STATE;
+ state = STATE_ERROR;
errorMessage = err;
logger->log("Warning: %s", err);
}
@@ -463,7 +533,7 @@ static void init_engine(const Options &options)
}
/** Clear the engine */
-static void exit_engine()
+static void exitEngine()
{
// Before config.write() since it writes the shortcuts to the config
delete itemShortcut;
@@ -486,9 +556,9 @@ static void exit_engine()
ItemDB::unload();
MonsterDB::unload();
NPCDB::unload();
+ StatusEffect::unload();
ResourceManager::deleteInstance();
- delete logger;
SDL_FreeSurface(icon);
}
@@ -496,16 +566,19 @@ static void exit_engine()
static void printHelp()
{
std::cout
- << _("aethyra") << std::endl << std::endl
+ << _("tmw") << std::endl << std::endl
<< _("Options: ") << std::endl
<< _(" -C --configfile : Configuration file to use") << std::endl
<< _(" -d --data : Directory to load game data from") << std::endl
<< _(" -D --default : Bypass the login process with default settings")
<< std::endl
<< _(" -h --help : Display this help") << std::endl
+ << _(" -S --homedir : Directory to use as home directory") << std::endl
<< _(" -H --updatehost : Use this update host") << std::endl
- << _(" -p --playername : Login with this player") << std::endl
<< _(" -P --password : Login with this password") << std::endl
+ << _(" -c --character : Login with this character") << std::endl
+ << _(" -o --port : Login Server Port") << std::endl
+ << _(" -s --server : Login Server name or IP") << std::endl
<< _(" -u --skipupdate : Skip the update downloads") << std::endl
<< _(" -U --username : Login with this username") << std::endl
<< _(" -v --version : Display the version") << std::endl;
@@ -514,26 +587,28 @@ static void printHelp()
static void printVersion()
{
#ifdef PACKAGE_VERSION
- std::cout << _("Aethyra version ") << PACKAGE_VERSION <<
- std::endl;
+ std::cout << _("The Mana World version ") << PACKAGE_VERSION << std::endl;
#else
- std::cout << _("Aethyra version ") <<
+ std::cout << _("The Mana World version ") <<
_("(local build?, PACKAGE_VERSION is not defined)") << std::endl;
#endif
}
static void parseOptions(int argc, char *argv[], Options &options)
{
- const char *optstring = "hvud:U:P:Dp:C:H:";
+ const char *optstring = "hvud:U:P:Dc:s:o:C:H:S:";
const struct option long_options[] = {
{ "configfile", required_argument, 0, 'C' },
{ "data", required_argument, 0, 'd' },
{ "default", no_argument, 0, 'D' },
- { "playername", required_argument, 0, 'p' },
{ "password", required_argument, 0, 'P' },
+ { "character", required_argument, 0, 'c' },
{ "help", no_argument, 0, 'h' },
+ { "homedir", required_argument, 0, 'S' },
{ "updatehost", required_argument, 0, 'H' },
+ { "port", required_argument, 0, 'o' },
+ { "server", required_argument, 0, 's' },
{ "skipupdate", no_argument, 0, 'u' },
{ "username", required_argument, 0, 'U' },
{ "version", no_argument, 0, 'v' },
@@ -566,12 +641,18 @@ static void parseOptions(int argc, char *argv[], Options &options)
case 'H':
options.updateHost = optarg;
break;
- case 'p':
- options.playername = optarg;
+ case 'c':
+ options.character = optarg;
break;
case 'P':
options.password = optarg;
break;
+ case 's':
+ options.serverName = optarg;
+ break;
+ case 'o':
+ options.serverPort = (short)atoi(optarg);
+ break;
case 'u':
options.skipUpdate = true;
break;
@@ -581,6 +662,9 @@ static void parseOptions(int argc, char *argv[], Options &options)
case 'v':
options.printVersion = true;
break;
+ case 'S':
+ homeDir = optarg;
+ break;
}
}
}
@@ -610,20 +694,64 @@ struct ErrorListener : public gcn::ActionListener
{
void action(const gcn::ActionEvent &event)
{
- state = loginData.registerLogin ? REGISTER_STATE : LOGIN_STATE;
+#ifdef TMWSERV_SUPPORT
+ state = STATE_CHOOSE_SERVER;
+#else
+ state = loginData.registerLogin ? STATE_REGISTER : STATE_LOGIN;
+#endif
}
} errorListener;
+#ifdef TMWSERV_SUPPORT
+struct AccountListener : public gcn::ActionListener
+{
+ void action(const gcn::ActionEvent &event)
+ {
+ state = STATE_CHAR_SELECT;
+ }
+} accountListener;
+
+struct LoginListener : public gcn::ActionListener
+{
+ void action(const gcn::ActionEvent &event)
+ {
+ state = STATE_LOGIN;
+ }
+} loginListener;
+#endif
+
+} // namespace
+
// TODO Find some nice place for these functions
+#ifdef TMWSERV_SUPPORT
+static void accountLogin(LoginData *loginData)
+#else
static void accountLogin(Network *network, LoginData *loginData)
+#endif
{
+#ifdef EATHENA_SUPPORT
logger->log("Trying to connect to account server...");
+#endif
logger->log("Username is %s", loginData->username.c_str());
+#ifdef EATHENA_SUPPORT
network->connect(loginData->hostname, loginData->port);
network->registerHandler(&loginHandler);
+#endif
loginHandler.setLoginData(loginData);
+#ifdef TMWSERV_SUPPORT
+ Net::registerHandler(&loginHandler);
+
+ charServerHandler.setCharInfo(&charInfo);
+ Net::registerHandler(&charServerHandler);
+#endif
// Send login infos
+#ifdef TMWSERV_SUPPORT
+ Net::AccountServer::login(accountServerConnection,
+ 0, // client version
+ loginData->username,
+ loginData->password);
+#else
MessageOut outMsg(network);
outMsg.writeInt16(0x0064);
outMsg.writeInt32(0); // client version
@@ -637,16 +765,19 @@ static void accountLogin(Network *network, LoginData *loginData)
* 0 here.
*/
outMsg.writeInt8(0x01);
+#endif
// Clear the password, avoids auto login when returning to login
loginData->password = "";
+#ifdef EATHENA_SUPPORT
// Remove _M or _F from username after a login for registration purpose
if (loginData->registerLogin)
{
loginData->username =
loginData->username.substr(0, loginData->username.length() - 2);
}
+#endif
// TODO This is not the best place to save the config, but at least better
// than the login gui window
@@ -658,16 +789,13 @@ static void accountLogin(Network *network, LoginData *loginData)
config.setValue("remember", loginData->remember);
}
-inline int MIN(int x, int y)
-{
- return x < y ? x : y;
-}
+#ifdef EATHENA_SUPPORT
static void positionDialog(Window *dialog, int screenWidth, int screenHeight)
{
dialog->setPosition(
- MIN(screenWidth * 5 / 8, screenWidth - dialog->getWidth()),
- MIN(screenHeight * 5 / 8, screenHeight - dialog->getHeight()));
+ (screenWidth - dialog->getWidth()) / 2,
+ (screenHeight - dialog->getHeight()) / 2);
}
static void charLogin(Network *network, LoginData *loginData)
@@ -719,7 +847,143 @@ static void mapLogin(Network *network, LoginData *loginData)
network->skip(4);
}
-} // namespace
+#else
+
+static void accountRegister(LoginData *loginData)
+{
+ logger->log("Username is %s", loginData->username.c_str());
+
+ Net::registerHandler(&loginHandler);
+
+ charServerHandler.setCharInfo(&charInfo);
+ Net::registerHandler(&charServerHandler);
+
+ Net::AccountServer::registerAccount(accountServerConnection,
+ 0, // client version
+ loginData->username,
+ loginData->password,
+ loginData->email);
+}
+
+static void accountUnRegister(LoginData *loginData)
+{
+ Net::registerHandler(&logoutHandler);
+
+ Net::AccountServer::Account::unregister(loginData->username,
+ loginData->password);
+
+}
+
+static void accountChangePassword(LoginData *loginData)
+{
+ Net::registerHandler(&loginHandler);
+
+ Net::AccountServer::Account::changePassword(loginData->username,
+ loginData->password,
+ loginData->newPassword);
+}
+
+static void accountChangeEmail(LoginData *loginData)
+{
+ Net::registerHandler(&loginHandler);
+
+ Net::AccountServer::Account::changeEmail(loginData->newEmail);
+}
+
+static void switchCharacter(std::string *passToken)
+{
+ Net::registerHandler(&logoutHandler);
+
+ logoutHandler.reset();
+ logoutHandler.setScenario(LOGOUT_SWITCH_CHARACTER, passToken);
+
+ Net::GameServer::logout(true);
+ Net::ChatServer::logout();
+}
+
+static void switchAccountServer()
+{
+ Net::registerHandler(&logoutHandler);
+
+ logoutHandler.reset();
+ logoutHandler.setScenario(LOGOUT_SWITCH_ACCOUNTSERVER);
+
+ //Can't logout if we were not logged in ...
+ if (accountServerConnection->isConnected())
+ {
+ Net::AccountServer::logout();
+ }
+ else
+ {
+ logoutHandler.setAccountLoggedOut();
+ }
+
+ if (gameServerConnection->isConnected())
+ {
+ Net::GameServer::logout(false);
+ }
+ else
+ {
+ logoutHandler.setGameLoggedOut();
+ }
+
+ if (chatServerConnection->isConnected())
+ {
+ Net::ChatServer::logout();
+ }
+ else
+ {
+ logoutHandler.setChatLoggedOut();
+ }
+}
+
+static void logoutThenExit()
+{
+ Net::registerHandler(&logoutHandler);
+
+ logoutHandler.reset();
+ logoutHandler.setScenario(LOGOUT_EXIT);
+
+ // Can't logout if we were not logged in ...
+ if (accountServerConnection->isConnected())
+ {
+ Net::AccountServer::logout();
+ }
+ else
+ {
+ logoutHandler.setAccountLoggedOut();
+ }
+
+ if (gameServerConnection->isConnected())
+ {
+ Net::GameServer::logout(false);
+ }
+ else
+ {
+ logoutHandler.setGameLoggedOut();
+ }
+
+ if (chatServerConnection->isConnected())
+ {
+ Net::ChatServer::logout();
+ }
+ else
+ {
+ logoutHandler.setChatLoggedOut();
+ }
+}
+
+static void reconnectAccount(const std::string &passToken)
+{
+ Net::registerHandler(&loginHandler);
+
+ charServerHandler.setCharInfo(&charInfo);
+ Net::registerHandler(&charServerHandler);
+
+ Net::AccountServer::reconnectAccount(accountServerConnection, passToken);
+}
+
+#endif
static void initInternationalization()
{
@@ -737,17 +1001,30 @@ static void initInternationalization()
#endif
}
+static void xmlNullLogger(void *ctx, const char *msg, ...)
+{
+ // Does nothing, that's the whole point of it
+}
+
+// Initialize libxml2 and check for potential ABI mismatches between
+// compiled version and the shared library actually used.
+static void initXML()
+{
+ xmlInitParser();
+ LIBXML_TEST_VERSION;
+
+ // Suppress libxml2 error messages
+ xmlSetGenericErrorFunc(NULL, xmlNullLogger);
+}
+
extern "C" char const *_nl_locale_name_default(void);
/** Main */
int main(int argc, char *argv[])
{
- logger = new Logger();
-
+ // Parse command line options
Options options;
-
parseOptions(argc, argv, options);
-
if (options.printHelp)
{
printHelp();
@@ -761,36 +1038,54 @@ int main(int argc, char *argv[])
initInternationalization();
- // Initialize libxml2 and check for potential ABI mismatches between
- // compiled version and the shared library actually used.
- xmlInitParser();
- LIBXML_TEST_VERSION;
-
- // Redirect libxml errors to /dev/null
- FILE *nullFile = fopen("/dev/null", "w");
- xmlSetGenericErrorFunc(nullFile, NULL);
-
// Initialize PhysicsFS
PHYSFS_init(argv[0]);
- init_engine(options);
+ initXML();
- SDL_Event event;
+ // load branding information
+ branding.init("data/branding.xml");
- unsigned int oldstate = !state; // We start with a status change.
+ initHomeDir();
+ // Configure logger
+ logger = new Logger();
+ logger->setLogFile(homeDir + std::string("/tmw.log"));
+ logger->setLogToStandardOut(config.getValue("logToStandardOut", 0));
+
+ // Log the tmw version
+#ifdef PACKAGE_VERSION
+#ifdef TMWSERV_SUPPORT
+ logger->log("The Mana World v%s TMWServ", PACKAGE_VERSION);
+#else
+ logger->log("The Mana World v%s eAthena", PACKAGE_VERSION);
+#endif
+#else
+ logger->log("The Mana World - version not defined");
+#endif
+
+ initConfiguration(options);
+
+ initEngine(options);
// Needs to be created in main, as the updater uses it
guiPalette = new Palette;
Game *game = NULL;
Window *currentDialog = NULL;
+#ifdef TMWSERV_SUPPORT
+ QuitDialog* quitDialog = NULL;
+#endif
Image *login_wallpaper = NULL;
- setupWindow = new Setup();
+ setupWindow = new Setup;
gcn::Container *top = static_cast<gcn::Container*>(gui->getTop());
#ifdef PACKAGE_VERSION
- gcn::Label *versionLabel = new Label(PACKAGE_VERSION);
- top->add(versionLabel, 2, 2);
+#ifdef TMWSERV_SUPPORT
+ gcn::Label *versionLabel = new Label(strprintf("%s TMWserv", PACKAGE_VERSION));
+#else
+ gcn::Label *versionLabel = new Label(strprintf("%s eAthena", PACKAGE_VERSION));
+#endif
+ top->add(versionLabel, 25, 2);
#endif
ProgressBar *progressBar = new ProgressBar(0.0f, 100, 20, 168, 116, 31);
gcn::Label *progressLabel = new Label();
@@ -802,7 +1097,22 @@ int main(int argc, char *argv[])
setup->setPosition(top->getWidth() - setup->getWidth() - 3, 3);
top->add(setup);
- sound.playMusic("Magick - Real.ogg");
+ sound.playMusic(branding.getValue("loginMusic", ""));
+
+ // Server choice
+ if (options.serverName.empty()) {
+ loginData.hostname = config.getValue("MostUsedServerName0",
+ branding.getValue("defaultServer", "server.themanaworld.org").c_str());
+ }
+ else {
+ loginData.hostname = options.serverName;
+ }
+ if (options.serverPort == 0) {
+ loginData.port = (short)config.getValue("MostUsedServerPort0",
+ branding.getValue("defaultPort", 9601));
+ } else {
+ loginData.port = options.serverPort;
+ }
loginData.username = options.username;
if (loginData.username.empty()) {
@@ -813,18 +1123,30 @@ int main(int argc, char *argv[])
if (!options.password.empty()) {
loginData.password = options.password;
}
- loginData.hostname = config.getValue("host", "www.aethyra.org");
- loginData.port = (short)config.getValue("port", 21001);
+
+#ifdef EATHENA_SUPPORT
+ loginData.hostname = config.getValue("host", "server.themanaworld.org");
+ loginData.port = (short)config.getValue("port", 6901);
+#endif
loginData.remember = config.getValue("remember", 0);
loginData.registerLogin = false;
+#ifdef TMWSERV_SUPPORT
+ Net::initialize();
+ accountServerConnection = Net::getConnection();
+ gameServerConnection = Net::getConnection();
+ chatServerConnection = Net::getConnection();
+#else
SDLNet_Init();
- Network *network = new Network();
+ Network *network = new Network;
+#endif
// Set the most appropriate wallpaper, based on screen width
int screenWidth = (int) config.getValue("screenwidth", defaultScreenWidth);
+#ifdef EATHENA_SUPPORT
int screenHeight = static_cast<int>(config.getValue("screenheight",
defaultScreenHeight));
+#endif
std::string wallpaperName;
wallpaperName = "graphics/images/login_wallpaper.png";
@@ -837,12 +1159,22 @@ int main(int argc, char *argv[])
else if (screenWidth >= 1600)
wallpaperName = "graphics/images/login_wallpaper_1600x1200.png";
- login_wallpaper = ResourceManager::getInstance()-> getImage(wallpaperName);
+ if (!ResourceManager::getInstance()->exists(wallpaperName))
+ wallpaperName = "graphics/images/login_wallpaper.png";
+
+ login_wallpaper = ResourceManager::getInstance()->getImage(wallpaperName);
if (!login_wallpaper)
logger->log("Couldn't load %s as wallpaper", wallpaperName.c_str());
- while (state != EXIT_STATE)
+ unsigned int oldstate = !state; // We start with a status change.
+
+ SDL_Event event;
+#ifdef TMWSERV_SUPPORT
+ while (state != STATE_FORCE_QUIT)
+#else
+ while (state != STATE_EXIT)
+#endif
{
// Handle SDL events
while (SDL_PollEvent(&event))
@@ -850,32 +1182,50 @@ int main(int argc, char *argv[])
switch (event.type)
{
case SDL_QUIT:
- state = EXIT_STATE;
+#ifdef TMWSERV_SUPPORT
+ state = STATE_FORCE_QUIT;
+#else
+ state = STATE_EXIT;
+#endif
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE)
- state = EXIT_STATE;
-
+ {
+#ifdef TMWSERV_SUPPORT
+ if (!quitDialog)
+ quitDialog = new QuitDialog(NULL, &quitDialog);
+ else
+ quitDialog->requestMoveToTop();
+#else
+ state = STATE_EXIT;
+#endif
+ }
break;
}
guiInput->pushInput(event);
}
+#ifdef TMWSERV_SUPPORT
+ Net::flush();
+#else
network->flush();
network->dispatchMessages();
+#endif
gui->logic();
+#ifdef EATHENA_SUPPORT
if (network->getState() == Network::NET_ERROR)
{
- state = ERROR_STATE;
+ state = STATE_ERROR;
if (!network->getError().empty())
errorMessage = network->getError();
else
errorMessage = _("Got disconnected from server!");
}
+#endif
if (progressBar->isVisible())
{
@@ -887,7 +1237,7 @@ int main(int argc, char *argv[])
if (graphics->getWidth() > login_wallpaper->getWidth() ||
graphics->getHeight() > login_wallpaper->getHeight())
{
- graphics->setColor(gcn::Color(255, 255, 255));
+ graphics->setColor(gcn::Color(64, 64, 64));
graphics->fillRectangle(gcn::Rectangle(
0, 0, graphics->getWidth(), graphics->getHeight()));
}
@@ -897,11 +1247,320 @@ int main(int argc, char *argv[])
gui->draw();
graphics->updateScreen();
+#ifdef TMWSERV_SUPPORT
+ // TODO: Add connect timeouts
+ if (state == STATE_CONNECT_ACCOUNT &&
+ accountServerConnection->isConnected())
+ {
+ if (options.skipUpdate) {
+ state = STATE_LOADDATA;
+ } else {
+ state = STATE_UPDATE;
+ }
+ }
+ else if (state == STATE_CONNECT_GAME &&
+ gameServerConnection->isConnected() &&
+ chatServerConnection->isConnected())
+ {
+ accountServerConnection->disconnect();
+ Net::clearHandlers();
+
+ state = STATE_GAME;
+ }
+ else if (state == STATE_RECONNECT_ACCOUNT &&
+ accountServerConnection->isConnected())
+ {
+ reconnectAccount(token);
+ state = STATE_WAIT;
+ }
+
+ if (state != oldstate)
+ {
+ // Load updates after exiting the update state
+ if (oldstate == STATE_UPDATE)
+ {
+ loadUpdates();
+ // Reload the wallpaper in case that it was updated
+ login_wallpaper->decRef();
+ login_wallpaper = ResourceManager::getInstance()->getImage(
+ branding.getValue("loginWallpaper",
+ "graphics/images/login_wallpaper.png"));
+ }
+
+ oldstate = state;
+
+ // Get rid of the dialog of the previous state
+ if (currentDialog) {
+ delete currentDialog;
+ currentDialog = NULL;
+ }
+ // State has changed, while the quitDialog was active, it might
+ // not be correct anymore
+ if (quitDialog) {
+ quitDialog->scheduleDelete();
+ }
+
+ switch (state) {
+ case STATE_CHOOSE_SERVER:
+ logger->log("State: CHOOSE_SERVER");
+
+ // Allow changing this using a server choice dialog
+ // We show the dialog box only if the command-line
+ // options weren't set.
+ if (options.serverName.empty() && options.serverPort == 0) {
+ currentDialog = new ServerDialog(&loginData);
+ } else {
+ state = STATE_CONNECT_ACCOUNT;
+
+ // Reset options so that cancelling or connect
+ // timeout will show the server dialog.
+ options.serverName.clear();
+ options.serverPort = 0;
+ }
+ break;
+
+ case STATE_CONNECT_ACCOUNT:
+ logger->log("State: CONNECT_ACCOUNT");
+ logger->log("Trying to connect to account server...");
+ accountServerConnection->connect(loginData.hostname,
+ loginData.port);
+ currentDialog = new ConnectionDialog(
+ STATE_SWITCH_ACCOUNTSERVER_ATTEMPT);
+ break;
+
+ case STATE_UPDATE:
+ // Determine which source to use for the update host
+ if (!options.updateHost.empty())
+ updateHost = options.updateHost;
+ else
+ updateHost = loginData.updateHost;
+
+ setUpdatesDir();
+ logger->log("State: UPDATE");
+ currentDialog = new UpdaterWindow(updateHost,
+ homeDir + "/" + updatesDir);
+ break;
+
+ case STATE_LOGIN:
+ logger->log("State: LOGIN");
+ if (options.username.empty()
+ || options.password.empty()) {
+ currentDialog = new LoginDialog(&loginData);
+ } else {
+ state = STATE_LOGIN_ATTEMPT;
+ // Clear the password so that when login fails, the
+ // dialog will show up next time.
+ options.password.clear();
+ }
+ break;
+
+ case STATE_LOADDATA:
+ logger->log("State: LOADDATA");
+
+ // Add customdata directory
+ ResourceManager::getInstance()->searchAndAddArchives(
+ "customdata/",
+ "zip",
+ false);
+
+ // Load XML databases
+ ColorDB::load();
+ ItemDB::load();
+ MonsterDB::load();
+ NPCDB::load();
+ EmoteDB::load();
+ Units::loadUnits();
+
+ state = STATE_LOGIN;
+ break;
+
+ case STATE_LOGIN_ATTEMPT:
+ accountLogin(&loginData);
+ break;
+
+ case STATE_LOGIN_ERROR:
+ logger->log("State: LOGIN ERROR");
+ currentDialog = new OkDialog("Error ", errorMessage);
+ currentDialog->addActionListener(&loginListener);
+ currentDialog = NULL; // OkDialog deletes itself
+ break;
+
+ case STATE_SWITCH_ACCOUNTSERVER:
+ logger->log("State: SWITCH_ACCOUNTSERVER");
+
+ gameServerConnection->disconnect();
+ chatServerConnection->disconnect();
+ accountServerConnection->disconnect();
+
+ state = STATE_CHOOSE_SERVER;
+ break;
+
+ case STATE_SWITCH_ACCOUNTSERVER_ATTEMPT:
+ logger->log("State: SWITCH_ACCOUNTSERVER_ATTEMPT");
+ switchAccountServer();
+
+ state = STATE_SWITCH_ACCOUNTSERVER;
+ break;
+
+ case STATE_REGISTER:
+ logger->log("State: REGISTER");
+ currentDialog = new RegisterDialog(&loginData);
+ break;
+
+ case STATE_REGISTER_ATTEMPT:
+ accountRegister(&loginData);
+ break;
+
+ case STATE_CHAR_SELECT:
+ logger->log("State: CHAR_SELECT");
+ currentDialog =
+ new CharSelectDialog(&charInfo, &loginData);
+
+ if (((CharSelectDialog*) currentDialog)->
+ selectByName(options.character)) {
+ ((CharSelectDialog*) currentDialog)->action(
+ gcn::ActionEvent(NULL, "ok"));
+ } else {
+ ((CharSelectDialog*) currentDialog)->selectByName(
+ config.getValue("lastCharacter", ""));
+ }
+
+ break;
+
+ case STATE_CHANGEEMAIL_ATTEMPT:
+ logger->log("State: CHANGE EMAIL ATTEMPT");
+ accountChangeEmail(&loginData);
+ break;
+
+ case STATE_CHANGEEMAIL:
+ logger->log("State: CHANGE EMAIL");
+ currentDialog = new OkDialog("Email Address change",
+ "Email Address changed successfully!");
+ currentDialog->addActionListener(&accountListener);
+ currentDialog = NULL; // OkDialog deletes itself
+ loginData.email = loginData.newEmail;
+ loginData.newEmail = "";
+ break;
+
+ case STATE_CHANGEPASSWORD_ATTEMPT:
+ logger->log("State: CHANGE PASSWORD ATTEMPT");
+ accountChangePassword(&loginData);
+ break;
+
+ case STATE_CHANGEPASSWORD:
+ logger->log("State: CHANGE PASSWORD");
+ currentDialog = new OkDialog("Password change",
+ "Password changed successfully!");
+ currentDialog->addActionListener(&accountListener);
+ currentDialog = NULL; // OkDialog deletes itself
+ loginData.password = loginData.newPassword;
+ loginData.newPassword = "";
+ break;
+
+ case STATE_UNREGISTER_ATTEMPT:
+ logger->log("State: UNREGISTER ATTEMPT");
+ accountUnRegister(&loginData);
+ break;
+
+ case STATE_UNREGISTER:
+ logger->log("State: UNREGISTER");
+ accountServerConnection->disconnect();
+ currentDialog = new OkDialog("Unregister successful",
+ "Farewell, come back any time ....");
+ loginData.clear();
+ //The errorlistener sets the state to STATE_CHOOSE_SERVER
+ currentDialog->addActionListener(&errorListener);
+ currentDialog = NULL; // OkDialog deletes itself
+ break;
+
+ case STATE_ACCOUNTCHANGE_ERROR:
+ logger->log("State: ACCOUNT CHANGE ERROR");
+ currentDialog = new OkDialog("Error ", errorMessage);
+ currentDialog->addActionListener(&accountListener);
+ currentDialog = NULL; // OkDialog deletes itself
+ break;
+
+
+ case STATE_ERROR:
+ logger->log("State: ERROR");
+ currentDialog = new OkDialog("Error", errorMessage);
+ currentDialog->addActionListener(&errorListener);
+ currentDialog = NULL; // OkDialog deletes itself
+ gameServerConnection->disconnect();
+ chatServerConnection->disconnect();
+ Net::clearHandlers();
+ break;
+
+ case STATE_CONNECT_GAME:
+ logger->log("State: CONNECT_GAME");
+ currentDialog = new ConnectionDialog(STATE_SWITCH_ACCOUNTSERVER_ATTEMPT);
+ break;
+
+ case STATE_GAME:
+ logger->log("Memorizing selected character %s",
+ player_node->getName().c_str());
+ config.setValue("lastCharacter", player_node->getName());
+
+ Net::GameServer::connect(gameServerConnection, token);
+ Net::ChatServer::connect(chatServerConnection, token);
+ sound.fadeOutMusic(1000);
+
+#ifdef PACKAGE_VERSION
+ delete versionLabel;
+ versionLabel = NULL;
+#endif
+ currentDialog = NULL;
+
+ logger->log("State: GAME");
+ game = new Game;
+ game->logic();
+ delete game;
+
+ // If the quitdialog didn't set the next state
+ if (state == STATE_GAME)
+ {
+ state = STATE_EXIT;
+ }
+ break;
+
+ case STATE_SWITCH_CHARACTER:
+ logger->log("State: SWITCH_CHARACTER");
+ switchCharacter(&token);
+ break;
+
+ case STATE_RECONNECT_ACCOUNT:
+ logger->log("State: RECONNECT_ACCOUNT");
+
+ // Done with game & chat
+ gameServerConnection->disconnect();
+ chatServerConnection->disconnect();
+
+ accountServerConnection->connect(
+ loginData.hostname,
+ loginData.port);
+ break;
+
+ case STATE_WAIT:
+ break;
+
+ case STATE_EXIT:
+ logger->log("State: EXIT");
+ logoutThenExit();
+ break;
+
+ default:
+ state = STATE_FORCE_QUIT;
+ break;
+ }
+ }
+
+#else // no TMWSERV_SUPPORT
+
if (state != oldstate)
{
switch (oldstate)
{
- case UPDATE_STATE:
+ case STATE_UPDATE:
loadUpdates();
// Reload the wallpaper in case that it was updated
login_wallpaper->decRef();
@@ -910,12 +1569,12 @@ int main(int argc, char *argv[])
break;
// Those states don't cause a network disconnect
- case LOADDATA_STATE:
+ case STATE_LOADDATA:
break;
- case ACCOUNT_STATE:
- case CHAR_CONNECT_STATE:
- case CONNECTING_STATE:
+ case STATE_ACCOUNT:
+ case STATE_CHAR_CONNECT:
+ case STATE_CONNECTING:
progressBar->setVisible(false);
progressLabel->setCaption("");
break;
@@ -928,8 +1587,8 @@ int main(int argc, char *argv[])
oldstate = state;
- if (currentDialog && state != ACCOUNT_STATE &&
- state != CHAR_CONNECT_STATE)
+ if (currentDialog && state != STATE_ACCOUNT &&
+ state != STATE_CHAR_CONNECT)
{
delete currentDialog;
currentDialog = NULL;
@@ -937,7 +1596,7 @@ int main(int argc, char *argv[])
switch (state)
{
- case LOADDATA_STATE:
+ case STATE_LOADDATA:
logger->log("State: LOADDATA");
// Add customdata directory
@@ -952,18 +1611,22 @@ int main(int argc, char *argv[])
MonsterDB::load();
NPCDB::load();
EmoteDB::load();
+ StatusEffect::load();
Being::load(); // Hairstyles
- state = CHAR_CONNECT_STATE;
+ // Load units
+ Units::loadUnits();
+
+ state = STATE_CHAR_CONNECT;
break;
- case LOGIN_STATE:
+ case STATE_LOGIN:
logger->log("State: LOGIN");
if (!loginData.password.empty())
{
loginData.registerLogin = false;
- state = ACCOUNT_STATE;
+ state = STATE_ACCOUNT;
}
else
{
@@ -973,13 +1636,13 @@ int main(int argc, char *argv[])
}
break;
- case REGISTER_STATE:
+ case STATE_REGISTER:
logger->log("State: REGISTER");
currentDialog = new RegisterDialog(&loginData);
positionDialog(currentDialog, screenWidth, screenHeight);
break;
- case CHAR_SERVER_STATE:
+ case STATE_CHAR_SERVER:
logger->log("State: CHAR_SERVER");
if (n_server == 1)
@@ -988,32 +1651,32 @@ int main(int argc, char *argv[])
loginData.hostname = ipToString(si->address);
loginData.port = si->port;
loginData.updateHost = si->updateHost;
- state = UPDATE_STATE;
+ state = STATE_UPDATE;
}
else
{
- int nextState = UPDATE_STATE;
+ int nextState = STATE_UPDATE;
currentDialog = new ServerSelectDialog(&loginData,
nextState);
positionDialog(currentDialog, screenWidth,
screenHeight);
if (options.chooseDefault
- || !options.playername.empty())
+ || !options.character.empty())
{
((ServerSelectDialog*) currentDialog)->action(
gcn::ActionEvent(NULL, "ok"));
}
}
break;
- case CHAR_SELECT_STATE:
+ case STATE_CHAR_SELECT:
logger->log("State: CHAR_SELECT");
currentDialog = new CharSelectDialog(network, &charInfo,
- (loginData.sex == 0) ?
- GENDER_FEMALE : GENDER_MALE);
+ (loginData.sex == 0) ?
+ GENDER_FEMALE : GENDER_MALE);
positionDialog(currentDialog, screenWidth, screenHeight);
if (((CharSelectDialog*) currentDialog)->
- selectByName(options.playername))
+ selectByName(options.character))
options.chooseDefault = true;
else
((CharSelectDialog*) currentDialog)->selectByName(
@@ -1025,7 +1688,7 @@ int main(int argc, char *argv[])
break;
- case GAME_STATE:
+ case STATE_GAME:
sound.fadeOutMusic(1000);
#ifdef PACKAGE_VERSION
@@ -1046,13 +1709,13 @@ int main(int argc, char *argv[])
game = new Game(network);
game->logic();
delete game;
- state = EXIT_STATE;
+ state = STATE_EXIT;
break;
- case UPDATE_STATE:
+ case STATE_UPDATE:
if (options.skipUpdate)
{
- state = LOADDATA_STATE;
+ state = STATE_LOADDATA;
}
else
{
@@ -1072,7 +1735,7 @@ int main(int argc, char *argv[])
}
break;
- case ERROR_STATE:
+ case STATE_ERROR:
logger->log("State: ERROR");
currentDialog = new OkDialog(_("Error"), errorMessage);
positionDialog(currentDialog, screenWidth, screenHeight);
@@ -1082,7 +1745,7 @@ int main(int argc, char *argv[])
network->clearHandlers();
break;
- case CONNECTING_STATE:
+ case STATE_CONNECTING:
logger->log("State: CONNECTING");
progressBar->setVisible(true);
progressLabel->setCaption(
@@ -1091,7 +1754,7 @@ int main(int argc, char *argv[])
mapLogin(network, &loginData);
break;
- case CHAR_CONNECT_STATE:
+ case STATE_CHAR_CONNECT:
progressBar->setVisible(true);
progressLabel->setCaption(
_("Connecting to character server..."));
@@ -1099,7 +1762,7 @@ int main(int argc, char *argv[])
charLogin(network, &loginData);
break;
- case ACCOUNT_STATE:
+ case STATE_ACCOUNT:
progressBar->setVisible(true);
progressLabel->setCaption(
_("Connecting to account server..."));
@@ -1108,10 +1771,11 @@ int main(int argc, char *argv[])
break;
default:
- state = EXIT_STATE;
+ state = STATE_EXIT;
break;
}
}
+#endif
/*
* This loop can really stress the CPU, for no reason since it's
* just constantly redrawing the wallpaper. Added the following
@@ -1129,15 +1793,28 @@ int main(int argc, char *argv[])
delete setup;
delete setupWindow;
+#ifdef TMWSERV_SUPPORT
+ if (accountServerConnection)
+ accountServerConnection->disconnect();
+ if (gameServerConnection)
+ gameServerConnection->disconnect();
+ if (chatServerConnection)
+ chatServerConnection->disconnect();
+
+ delete accountServerConnection;
+ delete gameServerConnection;
+ delete chatServerConnection;
+ Net::finalize();
+#else
delete network;
SDLNet_Quit();
+#endif
- if (nullFile)
- fclose(nullFile);
-
- logger->log("State: EXIT");
- exit_engine();
+ logger->log("Quitting");
+ exitEngine();
PHYSFS_deinit();
+ delete logger;
+
return 0;
}
diff --git a/src/main.h b/src/main.h
index 5f33cab2..7f13740c 100644
--- a/src/main.h
+++ b/src/main.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,6 +22,35 @@
#ifndef MAIN_H
#define MAIN_H
+/**
+ * \mainpage
+ *
+ * \section Introduction Introduction
+ *
+ * This is the documentation for the client of The Mana World
+ * (http://themanaworld.org). It is always a work in progress, with the intent
+ * to make it easier for new developers to grow familiar with the source code.
+ *
+ * \section General General information
+ *
+ * During the game, the current Map is displayed by the main Viewport, which
+ * is the bottom-most widget in the WindowContainer. Aside the viewport, the
+ * window container keeps track of all the \link Window Windows\endlink
+ * displayed during the game. It is the <i>top</i> widget for Guichan.
+ *
+ * A Map is composed of several layers of \link Image Images\endlink (tiles),
+ * a layer with collision information and \link Sprite Sprites\endlink. The
+ * sprites define the visible part of \link Being Beings\endlink and
+ * \link FloorItem FloorItems\endlink, they are drawn from top to bottom
+ * by the map, interleaved with the tiles in the fringe layer.
+ *
+ * The server is split up into an \link Net::AccountServer account
+ * server\endlink, a \link Net::ChatServer chat server\endlink and a \link
+ * Net::GameServer game server\endlink. There may be multiple game servers.
+ * Handling of incoming messages is spread over several \link MessageHandler
+ * MessageHanders\endlink.
+ */
+
#include <string>
#ifdef HAVE_CONFIG_H
@@ -41,20 +69,43 @@
* Client different States
*/
enum {
- EXIT_STATE,
- LOADDATA_STATE,
- LOGIN_STATE,
- ACCOUNT_STATE,
- REGISTER_STATE,
- CHAR_CONNECT_STATE,
- CHAR_SERVER_STATE,
- CHAR_SELECT_STATE,
- CHAR_NEW_STATE,
- CHAR_DEL_STATE,
- GAME_STATE,
- ERROR_STATE,
- UPDATE_STATE,
- CONNECTING_STATE
+ STATE_EXIT,
+ STATE_LOADDATA,
+ STATE_LOGIN,
+ STATE_REGISTER,
+ STATE_CHAR_SELECT,
+ STATE_GAME,
+ STATE_ERROR,
+ STATE_UPDATE,
+#ifdef TMWSERV_SUPPORT
+ STATE_CHOOSE_SERVER,
+ STATE_CONNECT_ACCOUNT,
+ STATE_LOGIN_ATTEMPT,
+ STATE_LOGIN_ERROR,
+ STATE_REGISTER_ATTEMPT,
+ STATE_ACCOUNTCHANGE_ERROR,
+ STATE_CHANGEEMAIL_ATTEMPT,
+ STATE_CHANGEEMAIL,
+ STATE_CHANGEPASSWORD_ATTEMPT,
+ STATE_CHANGEPASSWORD,
+ STATE_UNREGISTER_ATTEMPT,
+ STATE_UNREGISTER,
+ STATE_SWITCH_CHARACTER,
+ STATE_RECONNECT_ACCOUNT,
+ STATE_SWITCH_ACCOUNTSERVER_ATTEMPT,
+ STATE_SWITCH_ACCOUNTSERVER,
+ STATE_LOGOUT_ATTEMPT,
+ STATE_CONNECT_GAME,
+ STATE_WAIT,
+ STATE_FORCE_QUIT
+#else
+ STATE_ACCOUNT,
+ STATE_CHAR_CONNECT,
+ STATE_CHAR_SERVER,
+ STATE_CHAR_NEW,
+ STATE_CHAR_DEL,
+ STATE_CONNECTING
+#endif
};
/* length definitions for several char[]s in order
@@ -77,7 +128,15 @@ const short defaultScreenHeight = 600;
const short defaultSfxVolume = 100;
const short defaultMusicVolume = 60;
+// Defines the number of usable player slots
+const short maxSlot = 2;
+
+#ifdef TMWSERV_SUPPORT
+extern std::string token;
+#else
extern char n_server, n_character;
+#endif
+
extern unsigned char state;
extern std::string errorMessage;
diff --git a/src/map.cpp b/src/map.cpp
index 877a8ba9..551c10f3 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -142,7 +141,11 @@ void MapLayer::draw(Graphics *graphics, int startX, int startY,
// tiles have been drawn
if (mIsFringeLayer)
{
+#ifdef TMWSERV_SUPPORT
+ while (si != sprites.end() && (*si)->getPixelY() <= y * 32)
+#else
while (si != sprites.end() && (*si)->getPixelY() <= y * 32 - 32)
+#endif
{
(*si)->draw(graphics, -scrollX, -scrollY);
si++;
@@ -182,12 +185,21 @@ Map::Map(int width, int height, int tileWidth, int tileHeight):
const int size = mWidth * mHeight;
mMetaTiles = new MetaTile[size];
+ for (int i = 0; i < NB_BLOCKTYPES; i++)
+ {
+ mOccupation[i] = new int[size];
+ memset(mOccupation[i], 0, size * sizeof(int));
+ }
}
Map::~Map()
{
// delete metadata, layers, tilesets and overlays
delete[] mMetaTiles;
+ for (int i = 0; i < NB_BLOCKTYPES; i++)
+ {
+ delete[] mOccupation[i];
+ }
delete_all(mLayers);
delete_all(mTilesets);
delete_all(mOverlays);
@@ -278,6 +290,59 @@ void Map::draw(Graphics *graphics, int scrollX, int scrollY)
(int) config.getValue("OverlayDetail", 2));
}
+void Map::drawCollision(Graphics *graphics, int scrollX, int scrollY)
+{
+ int endPixelY = graphics->getHeight() + scrollY + mTileHeight - 1;
+ int startX = scrollX / mTileWidth;
+ int startY = scrollY / mTileHeight;
+ int endX = (graphics->getWidth() + scrollX + mTileWidth - 1) / mTileWidth;
+ int endY = endPixelY / mTileHeight;
+
+ if (startX < 0) startX = 0;
+ if (startY < 0) startY = 0;
+ if (endX > mWidth) endX = mWidth;
+ if (endY > mHeight) endY = mHeight;
+
+ for (int y = startY; y < endY; y++)
+ {
+ for (int x = startX; x < endX; x++)
+ {
+ graphics->setColor(gcn::Color(0, 0, 0, 64));
+ graphics->drawRectangle(gcn::Rectangle(
+ x * mTileWidth - scrollX,
+ y * mTileWidth - scrollY,
+ 33, 33));
+
+ if (!getWalk(x, y, BLOCKMASK_WALL))
+ {
+ graphics->setColor(gcn::Color(0, 0, 200, 64));
+ graphics->fillRectangle(gcn::Rectangle(
+ x * mTileWidth - scrollX,
+ y * mTileWidth - scrollY,
+ 32, 32));
+ }
+
+ if (!getWalk(x, y, BLOCKMASK_MONSTER))
+ {
+ graphics->setColor(gcn::Color(200, 0, 0, 64));
+ graphics->fillRectangle(gcn::Rectangle(
+ x * mTileWidth - scrollX,
+ y * mTileWidth - scrollY,
+ 32, 32));
+ }
+
+ if (!getWalk(x, y, BLOCKMASK_CHARACTER))
+ {
+ graphics->setColor(gcn::Color(0, 200, 0, 64));
+ graphics->fillRectangle(gcn::Rectangle(
+ x * mTileWidth - scrollX,
+ y * mTileWidth - scrollY,
+ 32, 32));
+ }
+ }
+ }
+}
+
void Map::drawOverlay(Graphics *graphics,
float scrollX, float scrollY, int detail)
{
@@ -334,34 +399,46 @@ Tileset* Map::getTilesetWithGid(int gid) const
containsGid.gid = gid;
Tilesets::const_iterator i = find_if(mTilesets.begin(), mTilesets.end(),
- containsGid);
+ containsGid);
return (i == mTilesets.end()) ? NULL : *i;
}
-void Map::setWalk(int x, int y, bool walkable)
+void Map::blockTile(int x, int y, BlockType type)
{
- mMetaTiles[x + y * mWidth].walkable = walkable;
-}
-
-bool Map::occupied(int x, int y) const
-{
- Beings &beings = beingManager->getAll();
- for (BeingIterator i = beings.begin(); i != beings.end(); i++)
+ if (type == BLOCKTYPE_NONE || !contains(x, y))
+ return;
+
+ int tileNum = x + y * mWidth;
+
+ if ((++mOccupation[type][tileNum]) > 0)
{
- // job 45 is a portal, they don't collide
- if ((*i)->mX == x && (*i)->mY == y && (*i)->mJob != 45)
+ switch (type)
{
- return true;
+ case BLOCKTYPE_WALL:
+ mMetaTiles[tileNum].blockmask |= BLOCKMASK_WALL;
+ break;
+ case BLOCKTYPE_CHARACTER:
+ mMetaTiles[tileNum].blockmask |= BLOCKMASK_CHARACTER;
+ break;
+ case BLOCKTYPE_MONSTER:
+ mMetaTiles[tileNum].blockmask |= BLOCKMASK_MONSTER;
+ break;
+ default:
+ // shut up!
+ break;
}
}
-
- return false;
}
-bool Map::tileCollides(int x, int y) const
+bool Map::getWalk(int x, int y, char walkmask) const
{
- return !(contains(x, y) && mMetaTiles[x + y * mWidth].walkable);
+ // You can't walk outside of the map
+ if (!contains(x, y))
+ return false;
+
+ // Check if the tile is walkable
+ return !(mMetaTiles[x + y * mWidth].blockmask & walkmask);
}
bool Map::contains(int x, int y) const
@@ -369,7 +446,7 @@ bool Map::contains(int x, int y) const
return x >= 0 && y >= 0 && x < mWidth && y < mHeight;
}
-MetaTile* Map::getMetaTile(int x, int y)
+MetaTile* Map::getMetaTile(int x, int y) const
{
return &mMetaTiles[x + y * mWidth];
}
@@ -385,7 +462,9 @@ void Map::removeSprite(SpriteIterator iterator)
mSprites.erase(iterator);
}
-Path Map::findPath(int startX, int startY, int destX, int destY)
+static int const basicCost = 100;
+
+Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char walkmask, int maxCost)
{
// Path to be built up (empty by default)
Path path;
@@ -393,6 +472,9 @@ Path Map::findPath(int startX, int startY, int destX, int destY)
// Declare open list, a list with open tiles sorted on F cost
std::priority_queue<Location> openList;
+ // Return when destination not walkable
+ if (!getWalk(destX, destY, walkmask)) return path;
+
// Reset starting tile's G cost to 0
MetaTile *startTile = getMetaTile(startX, startY);
startTile->Gcost = 0;
@@ -437,35 +519,55 @@ Path Map::findPath(int startX, int startY, int destX, int destY)
MetaTile *newTile = getMetaTile(x, y);
- // Skip if the tile is on the closed list or collides unless
- // its the destination tile
+ // Skip if the tile is on the closed list or is not walkable
+ // unless its the destination tile
if (newTile->whichList == mOnClosedList ||
- (tileCollides(x, y) && !(x == destX && y == destY)))
+ ((newTile->blockmask & walkmask) && !(x == destX && y == destY)))
{
continue;
}
// When taking a diagonal step, verify that we can skip the
- // corner. We allow skipping past beings but not past non-
- // walkable tiles.
+ // corner.
if (dx != 0 && dy != 0)
{
MetaTile *t1 = getMetaTile(curr.x, curr.y + dy);
MetaTile *t2 = getMetaTile(curr.x + dx, curr.y);
- if (!(t1->walkable && t2->walkable))
+ if (t1->blockmask & walkmask && !(t2->blockmask & walkmask)) // I hope I didn't fuck this line up
{
continue;
}
}
- // Calculate G cost for this route, 10 for moving straight and
- // 14 for moving diagonal (sqrt(200) = 14.1421...)
- int Gcost = curr.tile->Gcost + ((dx == 0 || dy == 0) ? 10 : 14);
+ // Calculate G cost for this route, ~sqrt(2) for moving diagonal
+ int Gcost = curr.tile->Gcost +
+ (dx == 0 || dy == 0 ? basicCost : basicCost * 362 / 256);
+
+ /* Demote an arbitrary direction to speed pathfinding by
+ adding a defect (TODO: change depending on the desired
+ visual effect, e.g. a cross-product defect toward
+ destination).
+ Important: as long as the total defect along any path is
+ less than the basicCost, the pathfinder will still find one
+ of the shortest paths! */
+ if (dx == 0 || dy == 0)
+ {
+ // Demote horizontal and vertical directions, so that two
+ // consecutive directions cannot have the same Fcost.
+ ++Gcost;
+ }
+
+ // It costs extra to walk through a being (needs to be enough
+ // to make it more attractive to walk around).
+ if (!getWalk(x, y, BLOCKMASK_CHARACTER | BLOCKMASK_MONSTER))
+ {
+ Gcost += 3 * basicCost;
+ }
// Skip if Gcost becomes too much
// Warning: probably not entirely accurate
- if (Gcost > 200)
+ if (Gcost > maxCost * basicCost)
{
continue;
}
@@ -473,8 +575,14 @@ Path Map::findPath(int startX, int startY, int destX, int destY)
if (newTile->whichList != mOnOpenList)
{
// Found a new tile (not on open nor on closed list)
- // Update Hcost of the new tile using Manhatten distance
- newTile->Hcost = 10 * (abs(x - destX) + abs(y - destY));
+
+ /* Update Hcost of the new tile. The pathfinder does not
+ work reliably if the heuristic cost is higher than the
+ real cost. In particular, using Manhattan distance is
+ forbidden here. */
+ int dx = std::abs(x - destX), dy = std::abs(y - destY);
+ newTile->Hcost = std::abs(dx - dy) * basicCost +
+ std::min(dx, dy) * (basicCost * 362 / 256);
// Set the current tile as the parent of the new tile
newTile->parentX = curr.x;
diff --git a/src/map.h b/src/map.h
index eebdade1..09bed293 100644
--- a/src/map.h
+++ b/src/map.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -54,7 +53,7 @@ struct MetaTile
/**
* Constructor.
*/
- MetaTile():whichList(0) {};
+ MetaTile():whichList(0), blockmask(0) {};
// Pathfinding members
int Fcost; /**< Estimation of total path cost */
@@ -63,7 +62,7 @@ struct MetaTile
int whichList; /**< No list, open list or closed list */
int parentX; /**< X coordinate of parent tile */
int parentY; /**< Y coordinate of parent tile */
- bool walkable; /**< Can beings walk on this tile */
+ unsigned char blockmask; /**< Blocking properties of this tile */
};
/**
@@ -144,6 +143,15 @@ class MapLayer
class Map : public Properties
{
public:
+ enum BlockType
+ {
+ BLOCKTYPE_NONE = -1,
+ BLOCKTYPE_WALL,
+ BLOCKTYPE_CHARACTER,
+ BLOCKTYPE_MONSTER,
+ NB_BLOCKTYPES
+ };
+
/**
* Constructor, taking map and tile size as parameters.
*/
@@ -176,6 +184,11 @@ class Map : public Properties
void draw(Graphics *graphics, int scrollX, int scrollY);
/**
+ * Visualizes collision layer for debugging
+ */
+ void drawCollision(Graphics *graphics, int scrollX, int scrollY);
+
+ /**
* Adds a layer to this map. The map takes ownership of the layer.
*/
void addLayer(MapLayer *layer);
@@ -193,17 +206,18 @@ class Map : public Properties
/**
* Get tile reference.
*/
- MetaTile *getMetaTile(int x, int y);
+ MetaTile *getMetaTile(int x, int y) const;
/**
- * Set walkability flag for a tile.
+ * Marks a tile as occupied
*/
- void setWalk(int x, int y, bool walkable);
+ void blockTile(int x, int y, BlockType type);
/**
- * Tell if a tile collides, not including a check on beings.
+ * Gets walkability for a tile with a blocking bitmask. When called
+ * without walkmask, only blocks against colliding tiles.
*/
- bool tileCollides(int x, int y) const;
+ bool getWalk(int x, int y, char walkmask = BLOCKMASK_WALL) const;
/**
* Returns the width of this map.
@@ -228,7 +242,8 @@ class Map : public Properties
/**
* Find a path from one location to the next.
*/
- Path findPath(int startX, int startY, int destX, int destY);
+ Path findPath(int startX, int startY, int destX, int destY,
+ unsigned char walkmask, int maxCost = 20);
/**
* Adds a sprite to the map.
@@ -269,14 +284,17 @@ class Map : public Properties
int detail);
/**
- * Tells whether a tile is occupied by a being.
+ * Tells whether the given coordinates fall within the map boundaries.
*/
- bool occupied(int x, int y) const;
+ bool contains(int x, int y) const;
/**
- * Tells whether the given coordinates fall within the map boundaries.
+ * Blockmasks for different entities
*/
- bool contains(int x, int y) const;
+ static const unsigned char BLOCKMASK_WALL = 0x80; // = bin 1000 0000
+ static const unsigned char BLOCKMASK_CHARACTER = 0x01;// = bin 0000 0001
+ static const unsigned char BLOCKMASK_MONSTER = 0x02; // = bin 0000 0010
+ int *mOccupation[NB_BLOCKTYPES];
int mWidth, mHeight;
int mTileWidth, mTileHeight;
diff --git a/src/monster.cpp b/src/monster.cpp
index f71457df..eaea6225 100644
--- a/src/monster.cpp
+++ b/src/monster.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -40,7 +39,7 @@ Monster::Monster(int id, Uint16 job, Map *map):
Being(id, job, map),
mText(0)
{
- const MonsterInfo& info = MonsterDB::get(job - 1002);
+ const MonsterInfo& info = getInfo();
// Setup Monster sprites
int c = BASE_SPRITE;
@@ -82,11 +81,12 @@ Monster::~Monster()
delete mText;
}
+#ifdef EATHENA_SUPPORT
void Monster::logic()
{
if (mAction != STAND)
{
- mFrame = (get_elapsed_time(mWalkTime) * 4) / mWalkSpeed;
+ mFrame = (get_elapsed_time(mWalkTime) * 4) / getWalkSpeed();
if (mFrame >= 4 && mAction != DEAD)
{
@@ -96,13 +96,14 @@ void Monster::logic()
Being::logic();
}
+#endif
Being::Type Monster::getType() const
{
return MONSTER;
}
-void Monster::setAction(Action action)
+void Monster::setAction(Action action, int attackType)
{
SpriteAction currentAction = ACTION_INVALID;
int rotation = 0;
@@ -118,11 +119,11 @@ void Monster::setAction(Action action)
sound.playSfx(getInfo().getSound(MONSTER_EVENT_DIE));
break;
case ATTACK:
- currentAction = ACTION_ATTACK;
+ currentAction = getInfo().getAttackAction(attackType);
mSprites[BASE_SPRITE]->reset();
//attack particle effect
- particleEffect = getInfo().getAttackParticleEffect();
+ particleEffect = getInfo().getAttackParticleEffect(attackType);
if (!particleEffect.empty() && mParticleEffects)
{
switch (mDirection)
@@ -163,6 +164,22 @@ void Monster::setAction(Action action)
}
}
+#ifdef TMWSERV_SUPPORT
+
+void Monster::handleAttack()
+{
+ Being::handleAttack();
+
+ const MonsterInfo &mi = getInfo();
+
+ // TODO: It's not possible to determine hit or miss here, so this stuff
+ // probably needs to be moved somewhere else. We may lose synchronization
+ // between attack animation and the sound, unless we adapt the protocol...
+ sound.playSfx(mi.getSound(MONSTER_EVENT_HIT));
+}
+
+#else
+
void Monster::handleAttack(Being *victim, int damage, AttackType type)
{
Being::handleAttack(victim, damage, type);
@@ -172,6 +189,8 @@ void Monster::handleAttack(Being *victim, int damage, AttackType type)
MONSTER_EVENT_HIT : MONSTER_EVENT_MISS));
}
+#endif
+
void Monster::takeDamage(Being *attacker, int amount, AttackType type)
{
if (amount > 0) sound.playSfx(getInfo().getSound(MONSTER_EVENT_HURT));
@@ -185,15 +204,17 @@ Being::TargetCursorSize Monster::getTargetCursorSize() const
const MonsterInfo &Monster::getInfo() const
{
+#ifdef TMWSERV_SUPPORT
+ return MonsterDB::get(mJob);
+#else
return MonsterDB::get(mJob - 1002);
+#endif
}
-void Monster::showName(bool show)
+void Monster::setShowName(bool show)
{
- if (mText)
- {
- delete mText;
- }
+ delete mText;
+
if (show)
{
mText = new Text(getInfo().getName(), mPx + NAME_X_OFFSET,
diff --git a/src/monster.h b/src/monster.h
index afb55769..cd2a8f0c 100644
--- a/src/monster.h
+++ b/src/monster.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,9 +34,11 @@ class Monster : public Being
~Monster();
+#ifdef EATHENA_SUPPORT
virtual void logic();
+#endif
- virtual void setAction(Action action);
+ virtual void setAction(Action action, int attackType = 0);
virtual Type getType() const;
@@ -52,7 +53,11 @@ class Monster : public Being
* @param damage the amount of damage dealt (0 means miss)
* @param type the attack type
*/
+#ifdef TMWSERV_SUPPORT
+ virtual void handleAttack();
+#else
virtual void handleAttack(Being *victim, int damage, AttackType type);
+#endif
/**
* Puts a damage bubble above this monster and plays the hurt sound
@@ -71,10 +76,22 @@ class Monster : public Being
/**
* Determine whether the mob should show it's name
*/
- void showName(bool show);
+ void setShowName(bool show);
+
+ /**
+ * Gets the way the monster is blocked by other objects
+ */
+ virtual unsigned char getWalkMask() const
+ { return 0x83; } // blocked by walls, other monsters and players ( bin 1000 0011)
protected:
/**
+ * Gets the way the monster blocks pathfinding for other objects
+ */
+ virtual Map::BlockType getBlockType() const
+ { return Map::BLOCKTYPE_MONSTER; }
+
+ /**
* Update the text when the monster moves
*/
void updateCoords();
diff --git a/src/net/beinghandler.cpp b/src/net/ea/beinghandler.cpp
index d1810537..237c9f1f 100644
--- a/src/net/beinghandler.cpp
+++ b/src/net/ea/beinghandler.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,21 +19,27 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "net/ea/beinghandler.h"
+
+#include "net/ea/protocol.h"
+
+#include "net/messagein.h"
+
+#include "being.h"
+#include "beingmanager.h"
+#include "effectmanager.h"
+#include "game.h"
+#include "localplayer.h"
+#include "log.h"
+#include "npc.h"
+#include "player_relations.h"
+
+#include "gui/npc_text.h"
+
#include <iostream>
#include <SDL_types.h>
-#include "beinghandler.h"
-#include "messagein.h"
-#include "protocol.h"
-
-#include "../being.h"
-#include "../beingmanager.h"
-#include "../effectmanager.h"
-#include "../game.h"
-#include "../localplayer.h"
-#include "../log.h"
-#include "../npc.h"
-#include "../player_relations.h"
+extern NpcTextDialog *npcTextDialog;
const int EMOTION_TIME = 150; /**< Duration of emotion icon */
@@ -58,35 +63,39 @@ BeingHandler::BeingHandler(bool enableSync):
SMSG_PLAYER_STOP,
SMSG_PLAYER_MOVE_TO_ATTACK,
0x0119,
+ 0x0196,
0
};
handledMessages = _messages;
}
-void BeingHandler::handleMessage(MessageIn *msg)
+void BeingHandler::handleMessage(MessageIn &msg)
{
int id;
Uint16 job, speed;
Uint16 headTop, headMid, headBottom;
- Uint16 shoes, gloves, cape, misc1, misc2;
+ Uint16 shoes, gloves;
Uint16 weapon, shield;
Uint16 gmstatus;
int param1;
+ int stunMode;
+ Uint32 statusEffects;
int type;
+ Uint16 status;
Being *srcBeing, *dstBeing;
- int hairStyle, hairColor;
+ int hairStyle, hairColor, flag;
- switch (msg->getId())
+ switch (msg.getId())
{
case SMSG_BEING_VISIBLE:
case SMSG_BEING_MOVE:
// Information about a being in range
- id = msg->readInt32();
- speed = msg->readInt16();
- msg->readInt16(); // opt1
- msg->readInt16(); // opt2
- msg->readInt16(); // option
- job = msg->readInt16(); // class
+ id = msg.readInt32();
+ speed = msg.readInt16();
+ stunMode = msg.readInt16(); // opt1
+ statusEffects = msg.readInt16(); // opt2
+ statusEffects |= ((Uint32)msg.readInt16()) << 16; // option
+ job = msg.readInt16(); // class
dstBeing = beingManager->findBeing(id);
@@ -101,7 +110,7 @@ void BeingHandler::handleMessage(MessageIn *msg)
dstBeing = beingManager->createBeing(id, job);
}
- else if (msg->getId() == 0x0078)
+ else if (msg.getId() == 0x0078)
{
dstBeing->clearPath();
dstBeing->mFrame = 0;
@@ -109,34 +118,35 @@ void BeingHandler::handleMessage(MessageIn *msg)
dstBeing->setAction(Being::STAND);
}
+
// Prevent division by 0 when calculating frame
if (speed == 0) { speed = 150; }
dstBeing->setWalkSpeed(speed);
dstBeing->mJob = job;
- hairStyle = msg->readInt16();
- dstBeing->setSprite(Being::WEAPON_SPRITE, msg->readInt16());
- headBottom = msg->readInt16();
+ hairStyle = msg.readInt16();
+ dstBeing->setSprite(Being::WEAPON_SPRITE, msg.readInt16());
+ headBottom = msg.readInt16();
- if (msg->getId() == SMSG_BEING_MOVE)
+ if (msg.getId() == SMSG_BEING_MOVE)
{
- msg->readInt32(); // server tick
+ msg.readInt32(); // server tick
}
- dstBeing->setSprite(Being::SHIELD_SPRITE, msg->readInt16());
- headTop = msg->readInt16();
- headMid = msg->readInt16();
- hairColor = msg->readInt16();
- shoes = msg->readInt16();
- gloves = msg->readInt16();
- msg->readInt16(); // guild
- msg->readInt16(); // unknown
- msg->readInt16(); // unknown
- msg->readInt16(); // manner
- msg->readInt16(); // karma
- msg->readInt8(); // unknown
+ dstBeing->setSprite(Being::SHIELD_SPRITE, msg.readInt16());
+ headTop = msg.readInt16();
+ headMid = msg.readInt16();
+ hairColor = msg.readInt16();
+ shoes = msg.readInt16(); // clothes color - "abused" as shoes
+ gloves = msg.readInt16(); // head dir - "abused" as gloves
+ msg.readInt16(); // guild
+ msg.readInt16(); // unknown
+ msg.readInt16(); // unknown
+ msg.readInt16(); // manner
+ dstBeing->setStatusEffectBlock(32, msg.readInt16()); // opt3
+ msg.readInt8(); // karma
dstBeing->setGender(
- (msg->readInt8() == 0) ? GENDER_FEMALE : GENDER_MALE);
+ (msg.readInt8() == 0) ? GENDER_FEMALE : GENDER_MALE);
// Set these after the gender, as the sprites may be gender-specific
dstBeing->setSprite(Being::BOTTOMCLOTHES_SPRITE, headBottom);
@@ -146,10 +156,10 @@ void BeingHandler::handleMessage(MessageIn *msg)
dstBeing->setSprite(Being::GLOVES_SPRITE, gloves);
dstBeing->setHairStyle(hairStyle, hairColor);
- if (msg->getId() == SMSG_BEING_MOVE)
+ if (msg.getId() == SMSG_BEING_MOVE)
{
Uint16 srcX, srcY, dstX, dstY;
- msg->readCoordinatePair(srcX, srcY, dstX, dstY);
+ msg.readCoordinatePair(srcX, srcY, dstX, dstY);
dstBeing->setAction(Being::STAND);
dstBeing->mX = srcX;
dstBeing->mY = srcY;
@@ -158,13 +168,17 @@ void BeingHandler::handleMessage(MessageIn *msg)
else
{
Uint8 dir;
- msg->readCoordinates(dstBeing->mX, dstBeing->mY, dir);
+ msg.readCoordinates(dstBeing->mX, dstBeing->mY, dir);
dstBeing->setDirection(dir);
}
- msg->readInt8(); // unknown
- msg->readInt8(); // unknown
- msg->readInt8(); // unknown / sit
+ msg.readInt8(); // unknown
+ msg.readInt8(); // unknown
+ msg.readInt8(); // unknown / sit
+
+ dstBeing->setStunMode(stunMode);
+ dstBeing->setStatusEffectBlock(0, (statusEffects >> 16) & 0xffff);
+ dstBeing->setStatusEffectBlock(16, statusEffects & 0xffff);
break;
case SMSG_BEING_MOVE2:
@@ -173,11 +187,11 @@ void BeingHandler::handleMessage(MessageIn *msg)
* later versions of eAthena for both mobs and
* players
*/
- dstBeing = beingManager->findBeing(msg->readInt32());
+ dstBeing = beingManager->findBeing(msg.readInt32());
Uint16 srcX, srcY, dstX, dstY;
- msg->readCoordinatePair(srcX, srcY, dstX, dstY);
- msg->readInt32(); // Server tick
+ msg.readCoordinatePair(srcX, srcY, dstX, dstY);
+ msg.readInt32(); // Server tick
/*
* This packet doesn't have enough info to actually
@@ -196,11 +210,12 @@ void BeingHandler::handleMessage(MessageIn *msg)
case SMSG_BEING_REMOVE:
// A being should be removed or has died
- id = msg->readInt32();
- dstBeing = beingManager->findBeing(id);
+ id = msg.readInt32();
if (id == current_npc)
- current_npc = 0;
+ npcTextDialog->showCloseButton();
+
+ dstBeing = beingManager->findBeing(id);
if (!dstBeing)
break;
@@ -209,7 +224,7 @@ void BeingHandler::handleMessage(MessageIn *msg)
if (dstBeing == player_node->getTarget())
player_node->stopAttack();
- if (msg->readInt8() == 1)
+ if (msg.readInt8() == 1)
dstBeing->setAction(Being::DEAD);
else
beingManager->destroyBeing(dstBeing);
@@ -217,15 +232,15 @@ void BeingHandler::handleMessage(MessageIn *msg)
break;
case SMSG_BEING_ACTION:
- srcBeing = beingManager->findBeing(msg->readInt32());
- dstBeing = beingManager->findBeing(msg->readInt32());
- msg->readInt32(); // server tick
- msg->readInt32(); // src speed
- msg->readInt32(); // dst speed
- param1 = msg->readInt16();
- msg->readInt16(); // param 2
- type = msg->readInt8();
- msg->readInt16(); // param 3
+ srcBeing = beingManager->findBeing(msg.readInt32());
+ dstBeing = beingManager->findBeing(msg.readInt32());
+ msg.readInt32(); // server tick
+ msg.readInt32(); // src speed
+ msg.readInt32(); // dst speed
+ param1 = msg.readInt16();
+ msg.readInt16(); // param 2
+ type = msg.readInt8();
+ msg.readInt16(); // param 3
switch (type)
{
@@ -261,11 +276,11 @@ void BeingHandler::handleMessage(MessageIn *msg)
break;
case SMSG_BEING_SELFEFFECT: {
- id = (Uint32)msg->readInt32();
+ id = (Uint32)msg.readInt32();
if (!beingManager->findBeing(id))
break;
- int effectType = msg->readInt32();
+ int effectType = msg.readInt32();
Being* being = beingManager->findBeing(id);
effectManager->trigger(effectType, being);
@@ -274,13 +289,13 @@ void BeingHandler::handleMessage(MessageIn *msg)
}
case SMSG_BEING_EMOTION:
- if (!(dstBeing = beingManager->findBeing(msg->readInt32())))
+ if (!(dstBeing = beingManager->findBeing(msg.readInt32())))
{
break;
}
if (player_relations.hasPermission(dstBeing, PlayerRelation::EMOTE))
- dstBeing->setEmote(msg->readInt8(), EMOTION_TIME);
+ dstBeing->setEmote(msg.readInt8(), EMOTION_TIME);
break;
@@ -299,20 +314,20 @@ void BeingHandler::handleMessage(MessageIn *msg)
* 16 bit value will be 0.
*/
- if (!(dstBeing = beingManager->findBeing(msg->readInt32())))
+ if (!(dstBeing = beingManager->findBeing(msg.readInt32())))
{
break;
}
- int type = msg->readInt8();
+ int type = msg.readInt8();
int id = 0;
int id2 = 0;
- if (msg->getId() == SMSG_BEING_CHANGE_LOOKS) {
- id = msg->readInt8();
+ if (msg.getId() == SMSG_BEING_CHANGE_LOOKS) {
+ id = msg.readInt8();
} else { // SMSG_BEING_CHANGE_LOOKS2
- id = msg->readInt16();
- id2 = msg->readInt16();
+ id = msg.readInt16();
+ id2 = msg.readInt16();
}
switch (type) {
@@ -362,9 +377,9 @@ void BeingHandler::handleMessage(MessageIn *msg)
break;
case SMSG_BEING_NAME_RESPONSE:
- if ((dstBeing = beingManager->findBeing(msg->readInt32())))
+ if ((dstBeing = beingManager->findBeing(msg.readInt32())))
{
- dstBeing->setName(msg->readString(24));
+ dstBeing->setName(msg.readString(24));
}
break;
@@ -372,12 +387,13 @@ void BeingHandler::handleMessage(MessageIn *msg)
case SMSG_PLAYER_UPDATE_2:
case SMSG_PLAYER_MOVE:
// An update about a player, potentially including movement.
- id = msg->readInt32();
- speed = msg->readInt16();
- cape = msg->readInt16();
- misc1 = msg->readInt16();
- misc2 = msg->readInt16();
- job = msg->readInt16();
+ id = msg.readInt32();
+ speed = msg.readInt16();
+ stunMode = msg.readInt16(); // opt1; Aethyra use this as cape
+ statusEffects = msg.readInt16(); // opt2; Aethyra use this as misc1
+ statusEffects |= ((Uint32) msg.readInt16())
+ << 16; // status.options; Aethyra uses this as misc2
+ job = msg.readInt16();
dstBeing = beingManager->findBeing(id);
@@ -388,27 +404,28 @@ void BeingHandler::handleMessage(MessageIn *msg)
dstBeing->setWalkSpeed(speed);
dstBeing->mJob = job;
- hairStyle = msg->readInt16();
- weapon = msg->readInt16();
- shield = msg->readInt16();
- headBottom = msg->readInt16();
+ hairStyle = msg.readInt16();
+ weapon = msg.readInt16();
+ shield = msg.readInt16();
+ headBottom = msg.readInt16();
- if (msg->getId() == SMSG_PLAYER_MOVE)
+ if (msg.getId() == SMSG_PLAYER_MOVE)
{
- msg->readInt32(); // server tick
+ msg.readInt32(); // server tick
}
- headTop = msg->readInt16();
- headMid = msg->readInt16();
- hairColor = msg->readInt16();
- shoes = msg->readInt16();
- gloves = msg->readInt16();
- msg->readInt32(); // guild
- msg->readInt32(); // emblem
- msg->readInt16(); // manner
- msg->readInt8(); // karma
+ headTop = msg.readInt16();
+ headMid = msg.readInt16();
+ hairColor = msg.readInt16();
+ msg.readInt16(); // clothes color - Aethyra-"abused" as shoes, we ignore it
+ msg.readInt16(); // head dir - Aethyra-"abused" as gloves, we ignore it
+ msg.readInt32(); // guild
+ msg.readInt16(); // emblem
+ msg.readInt16(); // manner
+ dstBeing->setStatusEffectBlock(32, msg.readInt16()); // opt3
+ msg.readInt8(); // karma
dstBeing->setGender(
- (msg->readInt8() == 0) ? GENDER_FEMALE : GENDER_MALE);
+ (msg.readInt8() == 0) ? GENDER_FEMALE : GENDER_MALE);
// Set these after the gender, as the sprites may be gender-specific
dstBeing->setSprite(Being::WEAPON_SPRITE, weapon);
@@ -416,19 +433,15 @@ void BeingHandler::handleMessage(MessageIn *msg)
dstBeing->setSprite(Being::BOTTOMCLOTHES_SPRITE, headBottom);
dstBeing->setSprite(Being::TOPCLOTHES_SPRITE, headMid);
dstBeing->setSprite(Being::HAT_SPRITE, headTop);
- dstBeing->setSprite(Being::SHOE_SPRITE, shoes);
- // Compensation for the unpatched TMW server
- if (gloves > 10)
- dstBeing->setSprite(Being::GLOVES_SPRITE, gloves);
- dstBeing->setSprite(Being::CAPE_SPRITE, cape);
- dstBeing->setSprite(Being::MISC1_SPRITE, misc1);
- dstBeing->setSprite(Being::MISC2_SPRITE, misc2);
+ //dstBeing->setSprite(Being::CAPE_SPRITE, cape);
+ //dstBeing->setSprite(Being::MISC1_SPRITE, misc1);
+ //dstBeing->setSprite(Being::MISC2_SPRITE, misc2);
dstBeing->setHairStyle(hairStyle, hairColor);
- if (msg->getId() == SMSG_PLAYER_MOVE)
+ if (msg.getId() == SMSG_PLAYER_MOVE)
{
Uint16 srcX, srcY, dstX, dstY;
- msg->readCoordinatePair(srcX, srcY, dstX, dstY);
+ msg.readCoordinatePair(srcX, srcY, dstX, dstY);
dstBeing->mX = srcX;
dstBeing->mY = srcY;
dstBeing->setDestination(dstX, dstY);
@@ -436,33 +449,37 @@ void BeingHandler::handleMessage(MessageIn *msg)
else
{
Uint8 dir;
- msg->readCoordinates(dstBeing->mX, dstBeing->mY, dir);
+ msg.readCoordinates(dstBeing->mX, dstBeing->mY, dir);
dstBeing->setDirection(dir);
}
- gmstatus = msg->readInt16();
+ gmstatus = msg.readInt16();
if (gmstatus & 0x80)
dstBeing->setGM();
- if (msg->getId() == SMSG_PLAYER_UPDATE_1)
+ if (msg.getId() == SMSG_PLAYER_UPDATE_1)
{
- switch (msg->readInt8())
+ switch (msg.readInt8())
{
case 2:
dstBeing->setAction(Being::SIT);
break;
}
}
- else if (msg->getId() == SMSG_PLAYER_MOVE)
+ else if (msg.getId() == SMSG_PLAYER_MOVE)
{
- msg->readInt8(); // unknown
+ msg.readInt8(); // unknown
}
- msg->readInt8(); // Lv
- msg->readInt8(); // unknown
+ msg.readInt8(); // Lv
+ msg.readInt8(); // unknown
dstBeing->mWalkTime = tick_time;
dstBeing->mFrame = 0;
+
+ dstBeing->setStunMode(stunMode);
+ dstBeing->setStatusEffectBlock(0, (statusEffects >> 16) & 0xffff);
+ dstBeing->setStatusEffectBlock(16, statusEffects & 0xffff);
break;
case SMSG_PLAYER_STOP:
@@ -478,12 +495,12 @@ void BeingHandler::handleMessage(MessageIn *msg)
* of the config setting.
*/
- id = msg->readInt32();
+ id = msg.readInt32();
if (mSync || id != player_node->getId()) {
dstBeing = beingManager->findBeing(id);
if (dstBeing) {
- dstBeing->mX = msg->readInt16();
- dstBeing->mY = msg->readInt16();
+ dstBeing->mX = msg.readInt16();
+ dstBeing->mY = msg.readInt16();
if (dstBeing->mAction == Being::WALK) {
dstBeing->mFrame = 0;
dstBeing->setAction(Being::STAND);
@@ -502,10 +519,30 @@ void BeingHandler::handleMessage(MessageIn *msg)
break;
case 0x0119:
- // Change in players look
- logger->log("0x0119 %i %i %i %x %i", msg->readInt32(),
- msg->readInt16(), msg->readInt16(), msg->readInt16(),
- msg->readInt8());
+ // Change in players' flags
+ id = msg.readInt32();
+ dstBeing = beingManager->findBeing(id);
+ stunMode = msg.readInt16();
+ statusEffects = msg.readInt16();
+ statusEffects |= ((Uint32) msg.readInt16()) << 16;
+ msg.readInt8();
+
+ if (dstBeing) {
+ dstBeing->setStunMode(stunMode);
+ dstBeing->setStatusEffectBlock(0, (statusEffects >> 16) & 0xffff);
+ dstBeing->setStatusEffectBlock(16, statusEffects & 0xffff);
+ }
+ break;
+
+ case 0x0196:
+ // Status change
+ status = msg.readInt16();
+ id = msg.readInt32();
+ flag = msg.readInt8(); // 0: stop, 1: start
+
+ dstBeing = beingManager->findBeing(id);
+ if (dstBeing)
+ dstBeing->setStatusEffect(status, flag);
break;
}
}
diff --git a/src/net/beinghandler.h b/src/net/ea/beinghandler.h
index 5fbb57ce..1246f1c1 100644
--- a/src/net/beinghandler.h
+++ b/src/net/ea/beinghandler.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,21 +19,21 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef NET_BEINGHANDLER_H
-#define NET_BEINGHANDLER_H
+#ifndef NET_EA_BEINGHANDLER_H
+#define NET_EA_BEINGHANDLER_H
-#include "messagehandler.h"
+#include "net/messagehandler.h"
class BeingHandler : public MessageHandler
{
public:
BeingHandler(bool enableSync);
- void handleMessage(MessageIn *msg);
+ void handleMessage(MessageIn &msg);
private:
// Should we honor server "Stop Walking" packets
bool mSync;
};
-#endif
+#endif // NET_EA_BEINGHANDLER_H
diff --git a/src/net/buysellhandler.cpp b/src/net/ea/buysellhandler.cpp
index 287e5400..b99db6a4 100644
--- a/src/net/buysellhandler.cpp
+++ b/src/net/ea/buysellhandler.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,24 +19,26 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <SDL_types.h>
+#include "net/ea/buysellhandler.h"
+
+#include "net/ea/protocol.h"
-#include "buysellhandler.h"
-#include "messagein.h"
-#include "protocol.h"
+#include "net/messagein.h"
-#include "../beingmanager.h"
-#include "../inventory.h"
-#include "../item.h"
-#include "../localplayer.h"
-#include "../npc.h"
+#include "beingmanager.h"
+#include "inventory.h"
+#include "item.h"
+#include "localplayer.h"
+#include "npc.h"
-#include "../gui/buy.h"
-#include "../gui/buysell.h"
-#include "../gui/chat.h"
-#include "../gui/sell.h"
+#include "gui/buy.h"
+#include "gui/buysell.h"
+#include "gui/chat.h"
+#include "gui/sell.h"
-#include "../utils/gettext.h"
+#include "utils/gettext.h"
+
+#include <SDL_types.h>
BuySellHandler::BuySellHandler()
{
@@ -52,51 +53,51 @@ BuySellHandler::BuySellHandler()
handledMessages = _messages;
}
-void BuySellHandler::handleMessage(MessageIn *msg)
+void BuySellHandler::handleMessage(MessageIn &msg)
{
int n_items;
- switch (msg->getId())
+ switch (msg.getId())
{
case SMSG_NPC_BUY_SELL_CHOICE:
buyDialog->setVisible(false);
buyDialog->reset();
sellDialog->setVisible(false);
sellDialog->reset();
- current_npc = msg->readInt32();
+ current_npc = msg.readInt32();
buySellDialog->setVisible(true);
break;
case SMSG_NPC_BUY:
- msg->readInt16(); // length
- n_items = (msg->getLength() - 4) / 11;
+ msg.readInt16(); // length
+ n_items = (msg.getLength() - 4) / 11;
buyDialog->reset();
- buyDialog->setMoney(player_node->mGp);
+ buyDialog->setMoney(player_node->getMoney());
buyDialog->setVisible(true);
for (int k = 0; k < n_items; k++)
{
- int value = msg->readInt32();
- msg->readInt32(); // DCvalue
- msg->readInt8(); // type
- int itemId = msg->readInt16();
- buyDialog->addItem(itemId, value);
+ int value = msg.readInt32();
+ msg.readInt32(); // DCvalue
+ msg.readInt8(); // type
+ int itemId = msg.readInt16();
+ buyDialog->addItem(itemId, 0, value);
}
break;
case SMSG_NPC_SELL:
- msg->readInt16(); // length
- n_items = (msg->getLength() - 4) / 10;
+ msg.readInt16(); // length
+ n_items = (msg.getLength() - 4) / 10;
if (n_items > 0)
{
- sellDialog->setMoney(player_node->mGp);
+ sellDialog->setMoney(player_node->getMoney());
sellDialog->reset();
sellDialog->setVisible(true);
for (int k = 0; k < n_items; k++)
{
- int index = msg->readInt16();
- int value = msg->readInt32();
- msg->readInt32(); // OCvalue
+ int index = msg.readInt16();
+ int value = msg.readInt32();
+ msg.readInt32(); // OCvalue
Item *item = player_node->getInventory()->getItem(index);
@@ -106,30 +107,30 @@ void BuySellHandler::handleMessage(MessageIn *msg)
}
else
{
- chatWindow->chatLog(_("Nothing to sell"), BY_SERVER);
+ localChatTab->chatLog(_("Nothing to sell"), BY_SERVER);
current_npc = 0;
}
break;
case SMSG_NPC_BUY_RESPONSE:
- if (msg->readInt8() == 0)
+ if (msg.readInt8() == 0)
{
- chatWindow->chatLog(_("Thanks for buying"), BY_SERVER);
+ localChatTab->chatLog(_("Thanks for buying"), BY_SERVER);
}
else
{
// Reset player money since buy dialog already assumed purchase
// would go fine
- buyDialog->setMoney(player_node->mGp);
- chatWindow->chatLog(_("Unable to buy"), BY_SERVER);
+ buyDialog->setMoney(player_node->getMoney());
+ localChatTab->chatLog(_("Unable to buy"), BY_SERVER);
}
break;
case SMSG_NPC_SELL_RESPONSE:
- if (msg->readInt8() == 0)
- chatWindow->chatLog(_("Thanks for selling"), BY_SERVER);
+ if (msg.readInt8() == 0)
+ localChatTab->chatLog(_("Thanks for selling"), BY_SERVER);
else
- chatWindow->chatLog(_("Unable to sell"), BY_SERVER);
+ localChatTab->chatLog(_("Unable to sell"), BY_SERVER);
break;
}
diff --git a/src/net/ea/buysellhandler.h b/src/net/ea/buysellhandler.h
new file mode 100644
index 00000000..7b85b65d
--- /dev/null
+++ b/src/net/ea/buysellhandler.h
@@ -0,0 +1,35 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_EA_BUYSELLHANDLER_H
+#define NET_EA_BUYSELLHANDLER_H
+
+#include "net/messagehandler.h"
+
+class BuySellHandler : public MessageHandler
+{
+ public:
+ BuySellHandler();
+
+ void handleMessage(MessageIn &msg);
+};
+
+#endif // NET_EA_BUYSELLHANDLER_H
diff --git a/src/net/charserverhandler.cpp b/src/net/ea/charserverhandler.cpp
index 95555300..d212ebfe 100644
--- a/src/net/charserverhandler.cpp
+++ b/src/net/ea/charserverhandler.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,21 +19,23 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "charserverhandler.h"
-#include "messagein.h"
-#include "protocol.h"
+#include "net/ea/charserverhandler.h"
-#include "../game.h"
-#include "../localplayer.h"
-#include "../log.h"
-#include "../logindata.h"
-#include "../main.h"
+#include "net/ea/protocol.h"
-#include "../gui/char_select.h"
-#include "../gui/ok_dialog.h"
+#include "net/messagein.h"
-#include "../utils/gettext.h"
-#include "../utils/stringutils.h"
+#include "game.h"
+#include "localplayer.h"
+#include "log.h"
+#include "logindata.h"
+#include "main.h"
+
+#include "gui/char_select.h"
+#include "gui/ok_dialog.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
CharServerHandler::CharServerHandler():
mCharCreateDialog(0)
@@ -53,17 +54,17 @@ CharServerHandler::CharServerHandler():
handledMessages = _messages;
}
-void CharServerHandler::handleMessage(MessageIn *msg)
+void CharServerHandler::handleMessage(MessageIn &msg)
{
int slot, flags, code;
LocalPlayer *tempPlayer;
logger->log("CharServerHandler: Packet ID: %x, Length: %d",
- msg->getId(), msg->getLength());
- switch (msg->getId())
+ msg.getId(), msg.getLength());
+ switch (msg.getId())
{
case SMSG_CONNECTION_PROBLEM:
- code = msg->readInt8();
+ code = msg.readInt8();
logger->log("Connection problem: %i", code);
switch (code) {
@@ -86,32 +87,32 @@ void CharServerHandler::handleMessage(MessageIn *msg)
errorMessage = _("Unknown connection error");
break;
}
- state = ERROR_STATE;
+ state = STATE_ERROR;
break;
case 0x006b:
- msg->skip(2); // Length word
- flags = msg->readInt32(); // Aethyra extensions flags
+ msg.skip(2); // Length word
+ flags = msg.readInt32(); // Aethyra extensions flags
logger->log("Server flags are: %x", flags);
- msg->skip(16); // Unused
+ msg.skip(16); // Unused
// Derive number of characters from message length
- n_character = (msg->getLength() - 24) / 106;
+ n_character = (msg.getLength() - 24) / 106;
for (int i = 0; i < n_character; i++)
{
- tempPlayer = readPlayerData(*msg, slot);
+ tempPlayer = readPlayerData(msg, slot);
mCharInfo->select(slot);
mCharInfo->setEntry(tempPlayer);
logger->log("CharServer: Player: %s (%d)",
tempPlayer->getName().c_str(), slot);
}
- state = CHAR_SELECT_STATE;
+ state = STATE_CHAR_SELECT;
break;
case 0x006c:
- switch (msg->readInt8()) {
+ switch (msg.readInt8()) {
case 0:
errorMessage = _("Access denied");
break;
@@ -126,7 +127,7 @@ void CharServerHandler::handleMessage(MessageIn *msg)
break;
case 0x006d:
- tempPlayer = readPlayerData(*msg, slot);
+ tempPlayer = readPlayerData(msg, slot);
mCharInfo->unlock();
mCharInfo->select(slot);
mCharInfo->setEntry(tempPlayer);
@@ -164,10 +165,10 @@ void CharServerHandler::handleMessage(MessageIn *msg)
case 0x0071:
player_node = mCharInfo->getEntry();
slot = mCharInfo->getPos();
- msg->skip(4); // CharID, must be the same as player_node->charID
- map_path = msg->readString(16);
- mLoginData->hostname = ipToString(msg->readInt32());
- mLoginData->port = msg->readInt16();
+ msg.skip(4); // CharID, must be the same as player_node->charID
+ map_path = msg.readString(16);
+ mLoginData->hostname = ipToString(msg.readInt32());
+ mLoginData->port = msg.readInt16();
mCharInfo->unlock();
mCharInfo->select(0);
// Clear unselected players infos
@@ -183,7 +184,7 @@ void CharServerHandler::handleMessage(MessageIn *msg)
} while (mCharInfo->getPos());
mCharInfo->select(slot);
- state = CONNECTING_STATE;
+ state = STATE_CONNECTING;
break;
}
}
@@ -196,7 +197,7 @@ LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
tempPlayer->mCharId = msg.readInt32();
tempPlayer->setXp(msg.readInt32());
- tempPlayer->mGp = msg.readInt32();
+ tempPlayer->setMoney(msg.readInt32());
tempPlayer->mJobXp = msg.readInt32();
tempPlayer->mJobLevel = msg.readInt32();
tempPlayer->setSprite(Being::SHOE_SPRITE, msg.readInt16());
@@ -207,8 +208,8 @@ LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
msg.readInt32(); // karma
msg.readInt32(); // manner
msg.skip(2); // unknown
- tempPlayer->mHp = msg.readInt16();
- tempPlayer->mMaxHp = msg.readInt16();
+ tempPlayer->setHp(msg.readInt16());
+ tempPlayer->setMaxHp(msg.readInt16());
tempPlayer->mMp = msg.readInt16();
tempPlayer->mMaxMp = msg.readInt16();
msg.readInt16(); // speed
@@ -216,7 +217,7 @@ LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
int hairStyle = msg.readInt16();
Uint16 weapon = msg.readInt16();
tempPlayer->setSprite(Being::WEAPON_SPRITE, weapon);
- tempPlayer->mLevel = msg.readInt16();
+ tempPlayer->setLevel(msg.readInt16());
msg.readInt16(); // skill point
tempPlayer->setSprite(Being::BOTTOMCLOTHES_SPRITE, msg.readInt16()); // head bottom
tempPlayer->setSprite(Being::SHIELD_SPRITE, msg.readInt16());
diff --git a/src/net/charserverhandler.h b/src/net/ea/charserverhandler.h
index 2a5331b5..3b5a4cd8 100644
--- a/src/net/charserverhandler.h
+++ b/src/net/ea/charserverhandler.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,12 +19,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef NET_CHARSERVERHANDLER_H
-#define NET_CHARSERVERHANDLER_H
+#ifndef NET_EA_CHARSERVERHANDLER_H
+#define NET_EA_CHARSERVERHANDLER_H
-#include "messagehandler.h"
+#include "net/messagehandler.h"
-#include "../lockedarray.h"
+#include "lockedarray.h"
class CharCreateDialog;
class LocalPlayer;
@@ -39,7 +38,7 @@ class CharServerHandler : public MessageHandler
public:
CharServerHandler();
- void handleMessage(MessageIn *msg);
+ void handleMessage(MessageIn &msg);
void setCharInfo(LockedArray<LocalPlayer*> *charInfo)
{ mCharInfo = charInfo; }
@@ -60,7 +59,7 @@ class CharServerHandler : public MessageHandler
LockedArray<LocalPlayer*> *mCharInfo;
CharCreateDialog *mCharCreateDialog;
- LocalPlayer* readPlayerData(MessageIn &msg, int &slot);
+ LocalPlayer *readPlayerData(MessageIn &msg, int &slot);
};
-#endif
+#endif // NET_EA_CHARSERVERHANDLER_H
diff --git a/src/net/chathandler.cpp b/src/net/ea/chathandler.cpp
index 185ce7d8..14432b28 100644
--- a/src/net/chathandler.cpp
+++ b/src/net/ea/chathandler.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,22 +19,23 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <SDL_types.h>
-#include <string>
+#include "net/ea/chathandler.h"
+
+#include "net/ea/protocol.h"
-#include "chathandler.h"
-#include "messagein.h"
-#include "protocol.h"
+#include "net/messagein.h"
-#include "../being.h"
-#include "../beingmanager.h"
-#include "../game.h"
-#include "../player_relations.h"
+#include "being.h"
+#include "beingmanager.h"
+#include "game.h"
+#include "player_relations.h"
-#include "../gui/chat.h"
+#include "gui/chat.h"
-#include "../utils/gettext.h"
-#include "../utils/stringutils.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <string>
extern Being *player_node;
@@ -56,63 +56,62 @@ ChatHandler::ChatHandler()
handledMessages = _messages;
}
-void ChatHandler::handleMessage(MessageIn *msg)
+void ChatHandler::handleMessage(MessageIn &msg)
{
Being *being;
std::string chatMsg;
std::string nick;
int chatMsgLength;
- switch (msg->getId())
+ switch (msg.getId())
{
case SMSG_WHISPER_RESPONSE:
- switch (msg->readInt8())
+ switch (msg.readInt8())
{
case 0x00:
// comment out since we'll local echo in chat.cpp instead, then only report failures
- //chatWindow->chatLog("Whisper sent", BY_SERVER);
+ //localChatTab->chatLog("Whisper sent", BY_SERVER);
break;
case 0x01:
- chatWindow->chatLog(_("Whisper could not be sent, user is offline"), BY_SERVER);
+ localChatTab->chatLog(_("Whisper could not be sent, user is offline"), BY_SERVER);
break;
case 0x02:
- chatWindow->chatLog(_("Whisper could not be sent, ignored by user"), BY_SERVER);
+ localChatTab->chatLog(_("Whisper could not be sent, ignored by user"), BY_SERVER);
break;
}
break;
// Received whisper
case SMSG_WHISPER:
- chatMsgLength = msg->readInt16() - 28;
- nick = msg->readString(24);
+ chatMsgLength = msg.readInt16() - 28;
+ nick = msg.readString(24);
if (chatMsgLength <= 0)
break;
- chatMsg = msg->readString(chatMsgLength);
- if (nick != SERVER_NAME)
- chatMsg = nick + " : " + chatMsg;
+ chatMsg = msg.readString(chatMsgLength);
- if (nick == SERVER_NAME)
- chatWindow->chatLog(chatMsg, BY_SERVER);
- else {
+ if (nick != SERVER_NAME)
+ {
if (player_relations.hasPermission(nick, PlayerRelation::WHISPER))
- chatWindow->chatLog(chatMsg, ACT_WHISPER);
+ chatWindow->whisper(nick, chatMsg);
+ }
+ else
+ {
+ localChatTab->chatLog(chatMsg, BY_SERVER);
}
break;
// Received speech from being
case SMSG_BEING_CHAT: {
- chatMsgLength = msg->readInt16() - 8;
- being = beingManager->findBeing(msg->readInt32());
+ chatMsgLength = msg.readInt16() - 8;
+ being = beingManager->findBeing(msg.readInt32());
if (!being || chatMsgLength <= 0)
- {
break;
- }
- chatMsg = msg->readString(chatMsgLength);
+ chatMsg = msg.readString(chatMsgLength);
std::string::size_type pos = chatMsg.find(" : ", 0);
std::string sender_name = ((pos == std::string::npos)
@@ -122,7 +121,7 @@ void ChatHandler::handleMessage(MessageIn *msg)
// We use getIgnorePlayer instead of ignoringPlayer here because ignorePlayer' side
// effects are triggered right below for Being::IGNORE_SPEECH_FLOAT.
if (player_relations.checkPermissionSilently(sender_name, PlayerRelation::SPEECH_LOG))
- chatWindow->chatLog(chatMsg, BY_OTHER);
+ localChatTab->chatLog(chatMsg, BY_OTHER);
chatMsg.erase(0, pos + 3);
trim(chatMsg);
@@ -134,19 +133,17 @@ void ChatHandler::handleMessage(MessageIn *msg)
case SMSG_PLAYER_CHAT:
case SMSG_GM_CHAT: {
- chatMsgLength = msg->readInt16() - 4;
+ chatMsgLength = msg.readInt16() - 4;
if (chatMsgLength <= 0)
- {
break;
- }
- chatMsg = msg->readString(chatMsgLength);
+ chatMsg = msg.readString(chatMsgLength);
std::string::size_type pos = chatMsg.find(" : ", 0);
- if (msg->getId() == SMSG_PLAYER_CHAT)
+ if (msg.getId() == SMSG_PLAYER_CHAT)
{
- chatWindow->chatLog(chatMsg, BY_PLAYER);
+ localChatTab->chatLog(chatMsg, BY_PLAYER);
if (pos != std::string::npos)
chatMsg.erase(0, pos + 3);
@@ -157,20 +154,20 @@ void ChatHandler::handleMessage(MessageIn *msg)
}
else
{
- chatWindow->chatLog(chatMsg, BY_GM);
+ localChatTab->chatLog(chatMsg, BY_GM);
}
break;
}
case SMSG_WHO_ANSWER:
- chatWindow->chatLog("Online users: " + toString(msg->readInt32()),
+ localChatTab->chatLog("Online users: " + toString(msg.readInt32()),
BY_SERVER);
break;
case 0x010c:
// Display MVP player
- msg->readInt32(); // id
- chatWindow->chatLog("MVP player", BY_SERVER);
+ msg.readInt32(); // id
+ localChatTab->chatLog("MVP player", BY_SERVER);
break;
}
}
diff --git a/src/net/chathandler.h b/src/net/ea/chathandler.h
index 9a47c633..62a8c663 100644
--- a/src/net/chathandler.h
+++ b/src/net/ea/chathandler.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,17 +19,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef NET_CHATHANDLER_H
-#define NET_CHATHANDLER_H
+#ifndef NET_EA_CHATHANDLER_H
+#define NET_EA_CHATHANDLER_H
-#include "messagehandler.h"
+#include "net/messagehandler.h"
class ChatHandler : public MessageHandler
{
public:
ChatHandler();
- void handleMessage(MessageIn *msg);
+ void handleMessage(MessageIn &msg);
};
-#endif
+#endif // NET_EA_CHATHANDLER_H
diff --git a/src/net/equipmenthandler.cpp b/src/net/ea/equipmenthandler.cpp
index 9a6f424e..7a287bea 100644
--- a/src/net/equipmenthandler.cpp
+++ b/src/net/ea/equipmenthandler.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,19 +19,21 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "equipmenthandler.h"
-#include "messagein.h"
-#include "protocol.h"
+#include "net/ea/equipmenthandler.h"
-#include "../equipment.h"
-#include "../inventory.h"
-#include "../item.h"
-#include "../localplayer.h"
-#include "../log.h"
+#include "net/ea/protocol.h"
-#include "../gui/chat.h"
+#include "net/messagein.h"
-#include "../utils/gettext.h"
+#include "equipment.h"
+#include "inventory.h"
+#include "item.h"
+#include "localplayer.h"
+#include "log.h"
+
+#include "gui/chat.h"
+
+#include "utils/gettext.h"
EquipmentHandler::EquipmentHandler()
{
@@ -47,7 +48,7 @@ EquipmentHandler::EquipmentHandler()
handledMessages = _messages;
}
-void EquipmentHandler::handleMessage(MessageIn *msg)
+void EquipmentHandler::handleMessage(MessageIn &msg)
{
int itemCount;
int index, equipPoint, itemId;
@@ -56,23 +57,23 @@ void EquipmentHandler::handleMessage(MessageIn *msg)
Item *item;
Inventory *inventory = player_node->getInventory();
- switch (msg->getId())
+ switch (msg.getId())
{
case SMSG_PLAYER_EQUIPMENT:
- msg->readInt16(); // length
- itemCount = (msg->getLength() - 4) / 20;
+ msg.readInt16(); // length
+ itemCount = (msg.getLength() - 4) / 20;
for (int loop = 0; loop < itemCount; loop++)
{
- index = msg->readInt16();
- itemId = msg->readInt16();
- msg->readInt8(); // type
- msg->readInt8(); // identify flag
- msg->readInt16(); // equip type
- equipPoint = msg->readInt16();
- msg->readInt8(); // attribute
- msg->readInt8(); // refine
- msg->skip(8); // card
+ index = msg.readInt16();
+ itemId = msg.readInt16();
+ msg.readInt8(); // type
+ msg.readInt8(); // identify flag
+ msg.readInt16(); // equip type
+ equipPoint = msg.readInt16();
+ msg.readInt8(); // attribute
+ msg.readInt8(); // refine
+ msg.skip(8); // card
inventory->setItem(index, itemId, 1, true);
@@ -92,14 +93,14 @@ void EquipmentHandler::handleMessage(MessageIn *msg)
break;
case SMSG_PLAYER_EQUIP:
- index = msg->readInt16();
- equipPoint = msg->readInt16();
- type = msg->readInt8();
+ index = msg.readInt16();
+ equipPoint = msg.readInt16();
+ type = msg.readInt8();
logger->log("Equipping: %i %i %i", index, equipPoint, type);
if (!type) {
- chatWindow->chatLog(_("Unable to equip."), BY_SERVER);
+ localChatTab->chatLog(_("Unable to equip."), BY_SERVER);
break;
}
@@ -132,12 +133,12 @@ void EquipmentHandler::handleMessage(MessageIn *msg)
break;
case SMSG_PLAYER_UNEQUIP:
- index = msg->readInt16();
- equipPoint = msg->readInt16();
- type = msg->readInt8();
+ index = msg.readInt16();
+ equipPoint = msg.readInt16();
+ type = msg.readInt8();
if (!type) {
- chatWindow->chatLog(_("Unable to unequip."), BY_SERVER);
+ localChatTab->chatLog(_("Unable to unequip."), BY_SERVER);
break;
}
@@ -170,11 +171,11 @@ void EquipmentHandler::handleMessage(MessageIn *msg)
break;
case SMSG_PLAYER_ATTACK_RANGE:
- player_node->setAttackRange(msg->readInt16());
+ player_node->setAttackRange(msg.readInt16());
break;
case SMSG_PLAYER_ARROW_EQUIP:
- index = msg->readInt16();
+ index = msg.readInt16();
if (index <= 1)
break;
diff --git a/src/net/equipmenthandler.h b/src/net/ea/equipmenthandler.h
index 08de3b36..2bb73c97 100644
--- a/src/net/equipmenthandler.h
+++ b/src/net/ea/equipmenthandler.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,17 +19,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef NET_EQUIPMENTHANDLER_H
-#define NET_EQUIPMENTHANDLER_H
+#ifndef NET_EA_EQUIPMENTHANDLER_H
+#define NET_EA_EQUIPMENTHANDLER_H
-#include "messagehandler.h"
+#include "net/messagehandler.h"
class EquipmentHandler : public MessageHandler
{
public:
EquipmentHandler();
- void handleMessage(MessageIn *msg);
+ void handleMessage(MessageIn &msg);
};
-#endif
+#endif // NET_EA_EQUIPMENTHANDLER_H
diff --git a/src/net/inventoryhandler.cpp b/src/net/ea/inventoryhandler.cpp
index 9fcfedf1..21ae6dcb 100644
--- a/src/net/inventoryhandler.cpp
+++ b/src/net/ea/inventoryhandler.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,27 +19,29 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <SDL_types.h>
+#include "net/ea/inventoryhandler.h"
+
+#include "net/ea/protocol.h"
-#include "inventoryhandler.h"
-#include "messagein.h"
-#include "protocol.h"
+#include "net/messagein.h"
-#include "../configuration.h"
-#include "../inventory.h"
-#include "../item.h"
-#include "../itemshortcut.h"
-#include "../localplayer.h"
-#include "../log.h"
+#include "configuration.h"
+#include "inventory.h"
+#include "item.h"
+#include "itemshortcut.h"
+#include "localplayer.h"
+#include "log.h"
-#include "../gui/chat.h"
-#include "../gui/storagewindow.h"
+#include "gui/chat.h"
+#include "gui/storagewindow.h"
-#include "../resources/iteminfo.h"
+#include "resources/iteminfo.h"
-#include "../utils/gettext.h"
-#include "../utils/strprintf.h"
-#include "../utils/stringutils.h"
+#include "utils/gettext.h"
+#include "utils/strprintf.h"
+#include "utils/stringutils.h"
+
+#include <SDL_types.h>
InventoryHandler::InventoryHandler()
{
@@ -61,7 +62,7 @@ InventoryHandler::InventoryHandler()
handledMessages = _messages;
}
-void InventoryHandler::handleMessage(MessageIn *msg)
+void InventoryHandler::handleMessage(MessageIn &msg)
{
int number;
int index, amount, itemId, equipType, arrow;
@@ -69,11 +70,11 @@ void InventoryHandler::handleMessage(MessageIn *msg)
Inventory *inventory = player_node->getInventory();
Inventory *storage = player_node->getStorage();
- switch (msg->getId())
+ switch (msg.getId())
{
case SMSG_PLAYER_INVENTORY:
case SMSG_PLAYER_STORAGE_ITEMS:
- switch (msg->getId()) {
+ switch (msg.getId()) {
case SMSG_PLAYER_INVENTORY:
// Clear inventory - this will be a complete refresh
inventory->clear();
@@ -91,20 +92,20 @@ void InventoryHandler::handleMessage(MessageIn *msg)
logger->log("HOW DID WE GET HERE?");
return;
}
- msg->readInt16(); // length
- number = (msg->getLength() - 4) / 18;
+ msg.readInt16(); // length
+ number = (msg.getLength() - 4) / 18;
for (int loop = 0; loop < number; loop++) {
- index = msg->readInt16();
- itemId = msg->readInt16();
- itemType = msg->readInt8();
- identified = msg->readInt8();
- amount = msg->readInt16();
- arrow = msg->readInt16();
+ index = msg.readInt16();
+ itemId = msg.readInt16();
+ itemType = msg.readInt8();
+ identified = msg.readInt8();
+ amount = msg.readInt16();
+ arrow = msg.readInt16();
for (int i = 0; i < 4; i++)
- cards[i] = msg->readInt16();
+ cards[i] = msg.readInt16();
- if (msg->getId() == SMSG_PLAYER_INVENTORY) {
+ if (msg.getId() == SMSG_PLAYER_INVENTORY) {
inventory->setItem(index, itemId, amount, false);
// Trick because arrows are not considered equipment
@@ -121,21 +122,21 @@ void InventoryHandler::handleMessage(MessageIn *msg)
break;
case SMSG_PLAYER_STORAGE_EQUIP:
- msg->readInt16(); // length
- number = (msg->getLength() - 4) / 20;
+ msg.readInt16(); // length
+ number = (msg.getLength() - 4) / 20;
for (int loop = 0; loop < number; loop++) {
- index = msg->readInt16();
- itemId = msg->readInt16();
- itemType = msg->readInt8();
- identified = msg->readInt8();
+ index = msg.readInt16();
+ itemId = msg.readInt16();
+ itemType = msg.readInt8();
+ identified = msg.readInt8();
amount = 1;
- msg->readInt16(); // Equip Point?
- msg->readInt16(); // Another Equip Point?
- msg->readInt8(); // Attribute (broken)
- msg->readInt8(); // Refine level
+ msg.readInt16(); // Equip Point?
+ msg.readInt16(); // Another Equip Point?
+ msg.readInt8(); // Attribute (broken)
+ msg.readInt8(); // Refine level
for (int i = 0; i < 4; i++)
- cards[i] = msg->readInt16();
+ cards[i] = msg.readInt16();
logger->log("Index:%d, ID:%d, Type:%d, Identified:%d, Qty:%d, Cards:%d, %d, %d, %d",
index, itemId, itemType, identified, amount, cards[0], cards[1], cards[2], cards[3]);
@@ -144,27 +145,27 @@ void InventoryHandler::handleMessage(MessageIn *msg)
break;
case SMSG_PLAYER_INVENTORY_ADD:
- index = msg->readInt16();
- amount = msg->readInt16();
- itemId = msg->readInt16();
- identified = msg->readInt8();
- msg->readInt8(); // attribute
- msg->readInt8(); // refine
+ index = msg.readInt16();
+ amount = msg.readInt16();
+ itemId = msg.readInt16();
+ identified = msg.readInt8();
+ msg.readInt8(); // attribute
+ msg.readInt8(); // refine
for (int i = 0; i < 4; i++)
- cards[i] = msg->readInt16();
- equipType = msg->readInt16();
- itemType = msg->readInt8();
+ cards[i] = msg.readInt16();
+ equipType = msg.readInt16();
+ itemType = msg.readInt8();
- if (msg->readInt8() > 0) {
+ if (msg.readInt8() > 0) {
if (config.getValue("showpickupchat", true)) {
- chatWindow->chatLog(_("Unable to pick up item"), BY_SERVER);
+ localChatTab->chatLog(_("Unable to pick up item"), BY_SERVER);
}
} else {
const ItemInfo &itemInfo = ItemDB::get(itemId);
const std::string amountStr =
(amount > 1) ? toString(amount) : "a";
if (config.getValue("showpickupchat", true)) {
- chatWindow->chatLog(strprintf(_("You picked up %s [%s]"),
+ localChatTab->chatLog(strprintf(_("You picked up %s [%s]"),
amountStr.c_str(), itemInfo.getName().c_str()),
BY_SERVER);
}
@@ -182,8 +183,8 @@ void InventoryHandler::handleMessage(MessageIn *msg)
break;
case SMSG_PLAYER_INVENTORY_REMOVE:
- index = msg->readInt16();
- amount = msg->readInt16();
+ index = msg.readInt16();
+ amount = msg.readInt16();
if (Item *item = inventory->getItem(index)) {
item->increaseQuantity(-amount);
if (item->getQuantity() == 0)
@@ -192,22 +193,22 @@ void InventoryHandler::handleMessage(MessageIn *msg)
break;
case SMSG_PLAYER_INVENTORY_USE:
- index = msg->readInt16();
- msg->readInt16(); // item id
- msg->readInt32(); // id
- amount = msg->readInt16();
- msg->readInt8(); // type
+ index = msg.readInt16();
+ msg.readInt16(); // item id
+ msg.readInt32(); // id
+ amount = msg.readInt16();
+ msg.readInt8(); // type
if (Item *item = inventory->getItem(index))
item->setQuantity(amount);
break;
case SMSG_ITEM_USE_RESPONSE:
- index = msg->readInt16();
- amount = msg->readInt16();
+ index = msg.readInt16();
+ amount = msg.readInt16();
- if (msg->readInt8() == 0) {
- chatWindow->chatLog(_("Failed to use item"), BY_SERVER);
+ if (msg.readInt8() == 0) {
+ localChatTab->chatLog(_("Failed to use item"), BY_SERVER);
} else {
if (Item *item = inventory->getItem(index))
item->setQuantity(amount);
@@ -218,25 +219,25 @@ void InventoryHandler::handleMessage(MessageIn *msg)
/*
* This is the closest we get to an "Open Storage" packet from the
* server. It always comes after the two SMSG_PLAYER_STORAGE_...
- * packets that update storage contents..
+ * packets that update storage contents.
*/
player_node->setInStorage(true);
- msg->readInt16(); // Storage capacity
- msg->readInt16(); // Used count
+ msg.readInt16(); // Storage capacity
+ msg.readInt16(); // Used count
break;
case SMSG_PLAYER_STORAGE_ADD:
/*
* Move an item into storage
*/
- index = msg->readInt16();
- amount = msg->readInt32();
- itemId = msg->readInt16();
- identified = msg->readInt8();
- msg->readInt8(); // attribute
- msg->readInt8(); // refine
+ index = msg.readInt16();
+ amount = msg.readInt32();
+ itemId = msg.readInt16();
+ identified = msg.readInt8();
+ msg.readInt8(); // attribute
+ msg.readInt8(); // refine
for (int i = 0; i < 4; i++)
- cards[i] = msg->readInt16();
+ cards[i] = msg.readInt16();
if (Item *item = storage->getItem(index)) {
item->setId(itemId);
@@ -250,8 +251,8 @@ void InventoryHandler::handleMessage(MessageIn *msg)
/*
* Move an item out of storage
*/
- index = msg->readInt16();
- amount = msg->readInt16();
+ index = msg.readInt16();
+ amount = msg.readInt16();
if (Item *item = storage->getItem(index)) {
item->increaseQuantity(-amount);
if (item->getQuantity() == 0)
diff --git a/src/net/ea/inventoryhandler.h b/src/net/ea/inventoryhandler.h
new file mode 100644
index 00000000..7374fed9
--- /dev/null
+++ b/src/net/ea/inventoryhandler.h
@@ -0,0 +1,35 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_EA_INVENTORYHANDLER_H
+#define NET_EA_INVENTORYHANDLER_H
+
+#include "net/messagehandler.h"
+
+class InventoryHandler : public MessageHandler
+{
+ public:
+ InventoryHandler();
+
+ void handleMessage(MessageIn &msg);
+};
+
+#endif // NET_EA_INVENTORYHANDLER_H
diff --git a/src/net/itemhandler.cpp b/src/net/ea/itemhandler.cpp
index d9d84248..427b29bd 100644
--- a/src/net/itemhandler.cpp
+++ b/src/net/ea/itemhandler.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,12 +19,14 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "itemhandler.h"
-#include "messagein.h"
-#include "protocol.h"
+#include "net/ea/itemhandler.h"
-#include "../engine.h"
-#include "../flooritemmanager.h"
+#include "net/ea/protocol.h"
+
+#include "net/messagein.h"
+
+#include "engine.h"
+#include "flooritemmanager.h"
ItemHandler::ItemHandler()
{
@@ -38,29 +39,29 @@ ItemHandler::ItemHandler()
handledMessages = _messages;
}
-void ItemHandler::handleMessage(MessageIn *msg)
+void ItemHandler::handleMessage(MessageIn &msg)
{
Uint32 id;
Uint16 x, y;
int itemId;
- switch (msg->getId())
+ switch (msg.getId())
{
case SMSG_ITEM_VISIBLE:
case SMSG_ITEM_DROPPED:
- id = msg->readInt32();
- itemId = msg->readInt16();
- msg->readInt8(); // identify flag
- x = msg->readInt16();
- y = msg->readInt16();
- msg->skip(4); // amount,subX,subY / subX,subY,amount
+ id = msg.readInt32();
+ itemId = msg.readInt16();
+ msg.readInt8(); // identify flag
+ x = msg.readInt16();
+ y = msg.readInt16();
+ msg.skip(4); // amount,subX,subY / subX,subY,amount
floorItemManager->create(id, itemId, x, y, engine->getCurrentMap());
break;
case SMSG_ITEM_REMOVE:
FloorItem *item;
- item = floorItemManager->findById(msg->readInt32());
+ item = floorItemManager->findById(msg.readInt32());
if (item)
floorItemManager->destroy(item);
break;
diff --git a/src/net/ea/itemhandler.h b/src/net/ea/itemhandler.h
new file mode 100644
index 00000000..42a9e4e7
--- /dev/null
+++ b/src/net/ea/itemhandler.h
@@ -0,0 +1,35 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_EA_ITEMHANDLER_H
+#define NET_EA_ITEMHANDLER_H
+
+#include "net/messagehandler.h"
+
+class ItemHandler : public MessageHandler
+{
+ public:
+ ItemHandler();
+
+ void handleMessage(MessageIn &msg);
+};
+
+#endif // NET_EA_ITEMHANDLER_H
diff --git a/src/net/loginhandler.cpp b/src/net/ea/loginhandler.cpp
index cf45dbd4..06bdb4bc 100644
--- a/src/net/loginhandler.cpp
+++ b/src/net/ea/loginhandler.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,18 +19,20 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "loginhandler.h"
-#include "messagein.h"
-#include "protocol.h"
+#include "net/ea/loginhandler.h"
-#include "../log.h"
-#include "../logindata.h"
-#include "../main.h"
-#include "../serverinfo.h"
+#include "net/ea/protocol.h"
-#include "../utils/gettext.h"
-#include "../utils/strprintf.h"
-#include "../utils/stringutils.h"
+#include "net/messagein.h"
+
+#include "log.h"
+#include "logindata.h"
+#include "main.h"
+#include "serverinfo.h"
+
+#include "utils/gettext.h"
+#include "utils/strprintf.h"
+#include "utils/stringutils.h"
extern SERVER_INFO **server_info;
@@ -47,14 +48,14 @@ LoginHandler::LoginHandler()
handledMessages = _messages;
}
-void LoginHandler::handleMessage(MessageIn *msg)
+void LoginHandler::handleMessage(MessageIn &msg)
{
int code;
- switch (msg->getId())
+ switch (msg.getId())
{
case SMSG_CONNECTION_PROBLEM:
- code = msg->readInt8();
+ code = msg.readInt8();
logger->log("Connection problem: %i", code);
switch (code) {
@@ -71,14 +72,14 @@ void LoginHandler::handleMessage(MessageIn *msg)
errorMessage = _("Unknown connection error");
break;
}
- state = ERROR_STATE;
+ state = STATE_ERROR;
break;
case SMSG_UPDATE_HOST:
int len;
- len = msg->readInt16() - 4;
- mUpdateHost = msg->readString(len);
+ len = msg.readInt16() - 4;
+ mUpdateHost = msg.readString(len);
logger->log("Received update host \"%s\" from login server",
mUpdateHost.c_str());
@@ -86,39 +87,39 @@ void LoginHandler::handleMessage(MessageIn *msg)
case 0x0069:
// Skip the length word
- msg->skip(2);
+ msg.skip(2);
- n_server = (msg->getLength() - 47) / 32;
+ n_server = (msg.getLength() - 47) / 32;
server_info =
(SERVER_INFO**) malloc(sizeof(SERVER_INFO*) * n_server);
- mLoginData->session_ID1 = msg->readInt32();
- mLoginData->account_ID = msg->readInt32();
- mLoginData->session_ID2 = msg->readInt32();
- msg->skip(30); // unknown
- mLoginData->sex = msg->readInt8();
+ mLoginData->session_ID1 = msg.readInt32();
+ mLoginData->account_ID = msg.readInt32();
+ mLoginData->session_ID2 = msg.readInt32();
+ msg.skip(30); // unknown
+ mLoginData->sex = msg.readInt8();
for (int i = 0; i < n_server; i++)
{
server_info[i] = new SERVER_INFO;
- server_info[i]->address = msg->readInt32();
- server_info[i]->port = msg->readInt16();
- server_info[i]->name = msg->readString(20);
- server_info[i]->online_users = msg->readInt32();
+ server_info[i]->address = msg.readInt32();
+ server_info[i]->port = msg.readInt16();
+ server_info[i]->name = msg.readString(20);
+ server_info[i]->online_users = msg.readInt32();
server_info[i]->updateHost = mUpdateHost;
- msg->skip(2); // unknown
+ msg.skip(2); // unknown
logger->log("Network: Server: %s (%s:%d)",
server_info[i]->name.c_str(),
ipToString(server_info[i]->address),
server_info[i]->port);
}
- state = CHAR_SERVER_STATE;
+ state = STATE_CHAR_SERVER;
break;
case 0x006a:
- code = msg->readInt8();
+ code = msg.readInt8();
logger->log("Login::error code: %i", code);
switch (code) {
@@ -144,7 +145,7 @@ void LoginHandler::handleMessage(MessageIn *msg)
"banned from the game until "
"%s.\n Please contact the GM "
"team via the forums."),
- msg->readString(20).c_str());
+ msg.readString(20).c_str());
break;
case 9:
errorMessage = _("This user name is already taken");
@@ -153,7 +154,7 @@ void LoginHandler::handleMessage(MessageIn *msg)
errorMessage = _("Unknown error");
break;
}
- state = ERROR_STATE;
+ state = STATE_ERROR;
break;
}
}
diff --git a/src/net/loginhandler.h b/src/net/ea/loginhandler.h
index 6b938627..074bc9e2 100644
--- a/src/net/loginhandler.h
+++ b/src/net/ea/loginhandler.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,12 +19,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef NET_LOGINHANDLER_H
-#define NET_LOGINHANDLER_H
+#ifndef NET_EA_LOGINHANDLER_H
+#define NET_EA_LOGINHANDLER_H
-#include <string>
+#include "net/messagehandler.h"
-#include "messagehandler.h"
+#include <string>
struct LoginData;
@@ -34,13 +33,13 @@ class LoginHandler : public MessageHandler
public:
LoginHandler();
- void handleMessage(MessageIn *msg);
+ void handleMessage(MessageIn &msg);
- void setLoginData(LoginData *loginData) { mLoginData = loginData; };
+ void setLoginData(LoginData *loginData) { mLoginData = loginData; }
private:
LoginData *mLoginData;
std::string mUpdateHost;
};
-#endif
+#endif // NET_EA_LOGINHANDLER_H
diff --git a/src/net/maploginhandler.cpp b/src/net/ea/maploginhandler.cpp
index bcd3dd62..78f021b0 100644
--- a/src/net/maploginhandler.cpp
+++ b/src/net/ea/maploginhandler.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,15 +19,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "maploginhandler.h"
-#include "messagein.h"
-#include "protocol.h"
+#include "net/ea/maploginhandler.h"
-#include "../localplayer.h"
-#include "../log.h"
-#include "../main.h"
+#include "net/ea/protocol.h"
-#include "../utils/gettext.h"
+#include "net/messagein.h"
+
+#include "localplayer.h"
+#include "log.h"
+#include "main.h"
+
+#include "utils/gettext.h"
MapLoginHandler::MapLoginHandler()
{
@@ -40,15 +41,15 @@ MapLoginHandler::MapLoginHandler()
handledMessages = _messages;
}
-void MapLoginHandler::handleMessage(MessageIn *msg)
+void MapLoginHandler::handleMessage(MessageIn &msg)
{
int code;
unsigned char direction;
- switch (msg->getId())
+ switch (msg.getId())
{
case SMSG_CONNECTION_PROBLEM:
- code = msg->readInt8();
+ code = msg.readInt8();
logger->log("Connection problem: %i", code);
switch (code) {
@@ -62,16 +63,16 @@ void MapLoginHandler::handleMessage(MessageIn *msg)
errorMessage = _("Unknown connection error");
break;
}
- state = ERROR_STATE;
+ state = STATE_ERROR;
break;
case SMSG_LOGIN_SUCCESS:
- msg->readInt32(); // server tick
- msg->readCoordinates(player_node->mX, player_node->mY, direction);
- msg->skip(2); // unknown
+ msg.readInt32(); // server tick
+ msg.readCoordinates(player_node->mX, player_node->mY, direction);
+ msg.skip(2); // unknown
logger->log("Protocol: Player start position: (%d, %d), Direction: %d",
player_node->mX, player_node->mY, direction);
- state = GAME_STATE;
+ state = STATE_GAME;
break;
}
}
diff --git a/src/net/maploginhandler.h b/src/net/ea/maploginhandler.h
index fb083b51..40f8e7bc 100644
--- a/src/net/maploginhandler.h
+++ b/src/net/ea/maploginhandler.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,17 +19,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef NET_MAPLOGINHANDLER_H
-#define NET_MAPLOGINHANDLER_H
+#ifndef NET_EA_MAPLOGINHANDLER_H
+#define NET_EA_MAPLOGINHANDLER_H
-#include "messagehandler.h"
+#include "net/messagehandler.h"
class MapLoginHandler : public MessageHandler
{
public:
MapLoginHandler();
- void handleMessage(MessageIn *msg);
+ void handleMessage(MessageIn &msg);
};
-#endif
+#endif // NET_EA_MAPLOGINHANDLER_H
diff --git a/src/net/network.cpp b/src/net/ea/network.cpp
index 0126ad6d..e17b8f3b 100644
--- a/src/net/network.cpp
+++ b/src/net/ea/network.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,14 +19,15 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <sstream>
+#include "net/ea/network.h"
+
+#include "net/messagehandler.h"
+#include "net/messagein.h"
-#include "messagehandler.h"
-#include "messagein.h"
-#include "network.h"
+#include "log.h"
+#include "utils/stringutils.h"
-#include "../log.h"
-#include "../utils/stringutils.h"
+#include <sstream>
/** Warning: buffers and other variables are shared,
so there can be only one connection active at a time */
@@ -208,7 +208,7 @@ void Network::dispatchMessages()
MessageHandlerIterator iter = mMessageHandlers.find(msg.getId());
if (iter != mMessageHandlers.end())
- iter->second->handleMessage(&msg);
+ iter->second->handleMessage(msg);
else
logger->log("Unhandled packet: %x", msg.getId());
@@ -420,7 +420,7 @@ void Network::receive()
SDLNet_FreeSocketSet(set);
}
-void Network::setError(const std::string& error)
+void Network::setError(const std::string &error)
{
logger->log("Network error: %s", error.c_str());
mError = error;
diff --git a/src/net/network.h b/src/net/ea/network.h
index e264f8a5..651b1182 100644
--- a/src/net/network.h
+++ b/src/net/ea/network.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,8 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef NETWORK_
-#define NETWORK_
+#ifndef EA_NETWORK_H
+#define EA_NETWORK_H
#include <map>
#include <SDL_net.h>
@@ -61,7 +60,7 @@ class Network
int getState() const { return mState; }
- const std::string& getError() const { return mError; }
+ const std::string &getError() const { return mError; }
bool isConnected() const { return mState == CONNECTED; }
@@ -87,7 +86,7 @@ class Network
};
protected:
- void setError(const std::string& error);
+ void setError(const std::string &error);
Uint16 readWord(int pos);
diff --git a/src/net/npchandler.cpp b/src/net/ea/npchandler.cpp
index 60a77af1..165cc2d3 100644
--- a/src/net/npchandler.cpp
+++ b/src/net/ea/npchandler.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,20 +19,22 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <SDL_types.h>
+#include "net/ea/npchandler.h"
+
+#include "net/ea/protocol.h"
-#include "messagein.h"
-#include "npchandler.h"
-#include "protocol.h"
+#include "net/messagein.h"
-#include "../beingmanager.h"
-#include "../localplayer.h"
-#include "../npc.h"
+#include "beingmanager.h"
+#include "localplayer.h"
+#include "npc.h"
-#include "../gui/npc_text.h"
-#include "../gui/npcintegerdialog.h"
-#include "../gui/npclistdialog.h"
-#include "../gui/npcstringdialog.h"
+#include "gui/npc_text.h"
+#include "gui/npcintegerdialog.h"
+#include "gui/npclistdialog.h"
+#include "gui/npcstringdialog.h"
+
+#include <SDL_types.h>
NPCHandler::NPCHandler()
{
@@ -49,51 +50,61 @@ NPCHandler::NPCHandler()
handledMessages = _messages;
}
-void NPCHandler::handleMessage(MessageIn *msg)
+void NPCHandler::handleMessage(MessageIn &msg)
{
int id;
- switch (msg->getId())
+ switch (msg.getId())
{
case SMSG_NPC_CHOICE:
- msg->readInt16(); // length
- current_npc = msg->readInt32();
+ msg.readInt16(); // length
+ current_npc = msg.readInt32();
player_node->setAction(LocalPlayer::STAND);
- npcListDialog->parseItems(msg->readString(msg->getLength() - 8));
+ npcListDialog->parseItems(msg.readString(msg.getLength() - 8));
npcListDialog->requestFocus();
break;
case SMSG_NPC_MESSAGE:
- msg->readInt16(); // length
- current_npc = msg->readInt32();
+ msg.readInt16(); // length
+ current_npc = msg.readInt32();
player_node->setAction(LocalPlayer::STAND);
- npcTextDialog->addText(msg->readString(msg->getLength() - 8));
+ npcTextDialog->addText(msg.readString(msg.getLength() - 8));
npcTextDialog->requestFocus();
break;
case SMSG_NPC_CLOSE:
- id = msg->readInt32();
- if (current_npc == id)
- current_npc = 0;
- npcTextDialog->closeDialog(id);
+ id = msg.readInt32();
+ // If we're talking to that NPC, show the close button
+ if (id == current_npc)
+ npcTextDialog->showCloseButton();
+ // Otherwise, move on as an empty dialog doesn't help
+ else
+ npcTextDialog->closeDialog(id);
break;
case SMSG_NPC_NEXT:
- // Next button in NPC dialog, currently unused
+ id = msg.readInt32();
+ // If we're talking to that NPC, show the next button
+ if (id == current_npc)
+ npcTextDialog->showNextButton();
+ // Otherwise, move on as an empty dialog doesn't help
+ else
+ npcTextDialog->nextDialog(id);
break;
case SMSG_NPC_INT_INPUT:
// Request for an integer
- current_npc = msg->readInt32();
+ current_npc = msg.readInt32();
player_node->setAction(LocalPlayer::STAND);
npcIntegerDialog->setRange(0, 2147483647);
+ npcIntegerDialog->setDefaultValue(0);
npcIntegerDialog->setVisible(true);
npcIntegerDialog->requestFocus();
break;
case SMSG_NPC_STR_INPUT:
// Request for a string
- current_npc = msg->readInt32();
+ current_npc = msg.readInt32();
player_node->setAction(LocalPlayer::STAND);
npcStringDialog->setValue("");
npcStringDialog->setVisible(true);
diff --git a/src/net/ea/npchandler.h b/src/net/ea/npchandler.h
new file mode 100644
index 00000000..8c252175
--- /dev/null
+++ b/src/net/ea/npchandler.h
@@ -0,0 +1,35 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_EA_NPCHANDLER_H
+#define NET_EA_NPCHANDLER_H
+
+#include "net/messagehandler.h"
+
+class NPCHandler : public MessageHandler
+{
+ public:
+ NPCHandler();
+
+ void handleMessage(MessageIn &msg);
+};
+
+#endif // NET_EA_NPCHANDLER_H
diff --git a/src/net/partyhandler.cpp b/src/net/ea/partyhandler.cpp
index b65ff2c9..d903976e 100644
--- a/src/net/partyhandler.cpp
+++ b/src/net/ea/partyhandler.cpp
@@ -1,8 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 Lloyd Bryant <lloyd_bryant@netzero.net>
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,21 +15,20 @@
* 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <guichan/actionlistener.hpp>
+#include "net/ea/partyhandler.h"
-#include "partyhandler.h"
-#include "protocol.h"
-#include "messagein.h"
+#include "net/ea/protocol.h"
-#include "../gui/chat.h"
-#include "../gui/confirm_dialog.h"
+#include "net/messagein.h"
-#include "../beingmanager.h"
-#include "../party.h"
+#include "gui/chat.h"
+
+#include "beingmanager.h"
+#include "party.h"
PartyHandler::PartyHandler(Party *party) : mParty(party)
{
@@ -49,25 +48,25 @@ PartyHandler::PartyHandler(Party *party) : mParty(party)
handledMessages = _messages;
}
-void PartyHandler::handleMessage(MessageIn *msg)
+void PartyHandler::handleMessage(MessageIn &msg)
{
- switch (msg->getId())
+ switch (msg.getId())
{
case SMSG_PARTY_CREATE:
- mParty->createResponse(msg->readInt8());
+ mParty->createResponse(msg.readInt8());
break;
case SMSG_PARTY_INFO:
break;
case SMSG_PARTY_INVITE:
{
- std::string nick = msg->readString(24);
- int status = msg->readInt8();
+ std::string nick = msg.readString(24);
+ int status = msg.readInt8();
mParty->inviteResponse(nick, status);
break;
}
case SMSG_PARTY_INVITED:
{
- int id = msg->readInt32();
+ int id = msg.readInt32();
Being *being = beingManager->findBeing(id);
if (!being)
{
@@ -84,7 +83,7 @@ void PartyHandler::handleMessage(MessageIn *msg)
{
nick = being->getName();
gender = being->getGender();
- partyName = msg->readString(24);
+ partyName = msg.readString(24);
}
mParty->invitedAsk(nick, gender, partyName);
break;
@@ -95,9 +94,9 @@ void PartyHandler::handleMessage(MessageIn *msg)
break;
case SMSG_PARTY_LEAVE:
{
- /*int id = */msg->readInt32();
- std::string nick = msg->readString(24);
- /*int fail = */msg->readInt8();
+ /*int id = */msg.readInt32();
+ std::string nick = msg.readString(24);
+ /*int fail = */msg.readInt8();
mParty->leftResponse(nick);
break;
}
@@ -107,14 +106,14 @@ void PartyHandler::handleMessage(MessageIn *msg)
break;
case SMSG_PARTY_MESSAGE:
{ // new block to enable local variables
- int msgLength = msg->readInt16() - 8;
+ int msgLength = msg.readInt16() - 8;
if (msgLength <= 0)
{
return;
}
- int id = msg->readInt32();
+ int id = msg.readInt32();
Being *being = beingManager->findBeing(id);
- std::string chatMsg = msg->readString(msgLength);
+ std::string chatMsg = msg.readString(msgLength);
mParty->receiveChat(being, chatMsg);
}
break;
diff --git a/src/net/partyhandler.h b/src/net/ea/partyhandler.h
index 158e89e6..851c4ae3 100644
--- a/src/net/partyhandler.h
+++ b/src/net/ea/partyhandler.h
@@ -1,8 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 Lloyd Bryant <lloyd_bryant@netzero.net>
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,14 +15,14 @@
* 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
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PARTYHANDLER_H
-#define PARTYHANDLER_H
+#ifndef NET_EA_PARTYHANDLER_H
+#define NET_EA_PARTYHANDLER_H
-#include "messagehandler.h"
+#include "net/messagehandler.h"
class Party;
@@ -31,9 +31,10 @@ class PartyHandler : public MessageHandler
public:
PartyHandler(Party *party);
- void handleMessage(MessageIn *msg);
+ void handleMessage(MessageIn &msg);
+
private:
Party *mParty;
};
-#endif
+#endif // NET_EA_PARTYHANDLER_H
diff --git a/src/net/playerhandler.cpp b/src/net/ea/playerhandler.cpp
index 3dd2bad2..00230ea3 100644
--- a/src/net/playerhandler.cpp
+++ b/src/net/ea/playerhandler.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,31 +19,34 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "messagein.h"
-#include "playerhandler.h"
-#include "protocol.h"
-
-#include "../engine.h"
-#include "../localplayer.h"
-#include "../log.h"
-#include "../npc.h"
-
-#include "../gui/buy.h"
-#include "../gui/buysell.h"
-#include "../gui/chat.h"
-#include "../gui/gui.h"
-#include "../gui/npc_text.h"
-#include "../gui/npcintegerdialog.h"
-#include "../gui/npclistdialog.h"
-#include "../gui/npcstringdialog.h"
-#include "../gui/ok_dialog.h"
-#include "../gui/sell.h"
-#include "../gui/skill.h"
-#include "../gui/storagewindow.h"
-#include "../gui/viewport.h"
-
-#include "../utils/stringutils.h"
-#include "../utils/gettext.h"
+#include "net/ea/playerhandler.h"
+
+#include "net/ea/protocol.h"
+
+#include "net/messagein.h"
+
+#include "engine.h"
+#include "localplayer.h"
+#include "log.h"
+#include "npc.h"
+#include "units.h"
+
+#include "gui/buy.h"
+#include "gui/buysell.h"
+#include "gui/chat.h"
+#include "gui/gui.h"
+#include "gui/npc_text.h"
+#include "gui/npcintegerdialog.h"
+#include "gui/npclistdialog.h"
+#include "gui/npcstringdialog.h"
+#include "gui/ok_dialog.h"
+#include "gui/sell.h"
+#include "gui/skill.h"
+#include "gui/storagewindow.h"
+#include "gui/viewport.h"
+
+#include "utils/stringutils.h"
+#include "utils/gettext.h"
// TODO Move somewhere else
OkDialog *weightNotice = NULL;
@@ -54,11 +56,12 @@ OkDialog *deathNotice = NULL;
// everything beyond will reset the port hard.
static const int MAP_TELEPORT_SCROLL_DISTANCE = 8;
-/**
- * Listener used for handling the overweigth message.
- */
// TODO Move somewhere else
namespace {
+
+ /**
+ * Listener used for handling the overweigth message.
+ */
struct WeightListener : public gcn::ActionListener
{
void action(const gcn::ActionEvent &event)
@@ -66,13 +69,10 @@ namespace {
weightNotice = NULL;
}
} weightListener;
-}
-/**
- * Listener used for handling death message.
- */
-// TODO Move somewhere else
-namespace {
+ /**
+ * Listener used for handling death message.
+ */
struct DeathListener : public gcn::ActionListener
{
void action(const gcn::ActionEvent &event)
@@ -90,10 +90,59 @@ namespace {
buyDialog->setVisible(false);
sellDialog->setVisible(false);
buySellDialog->setVisible(false);
+
if (storageWindow->isVisible()) storageWindow->close();
- current_npc = 0;
}
} deathListener;
+
+} // anonymous namespace
+
+static const char *randomDeathMessage()
+{
+ static char const *const deadMsg[] =
+ {
+ N_("You are dead."),
+ N_("We regret to inform you that your character was killed in "
+ "battle."),
+ N_("You are not that alive anymore."),
+ N_("The cold hands of the grim reaper are grabbing for your soul."),
+ N_("Game Over!"),
+ N_("Insert coin to continue"),
+ N_("No, kids. Your character did not really die. It... "
+ "err... went to a better place."),
+ N_("Your plan of breaking your enemies weapon by "
+ "bashing it with your throat failed."),
+ N_("I guess this did not run too well."),
+ // NetHack reference:
+ N_("Do you want your possessions identified?"),
+ // Secret of Mana reference:
+ N_("Sadly, no trace of you was ever found..."),
+ // Final Fantasy VI reference:
+ N_("Annihilated."),
+ // Earthbound reference:
+ N_("Looks like you got your head handed to you."),
+ // Leisure Suit Larry 1 reference:
+ N_("You screwed up again, dump your body down the tubes "
+ "and get you another one."),
+ // Monty Python references (Dead Parrot sketch mostly):
+ N_("You're not dead yet. You're just resting."),
+ N_("You are no more."),
+ N_("You have ceased to be."),
+ N_("You've expired and gone to meet your maker."),
+ N_("You're a stiff."),
+ N_("Bereft of life, you rest in peace."),
+ N_("If you weren't so animated, you'd be pushing up the daisies."),
+ N_("Your metabolic processes are now history."),
+ N_("You're off the twig."),
+ N_("You've kicked the bucket."),
+ N_("You've shuffled off your mortal coil, run down the "
+ "curtain and joined the bleedin' choir invisibile."),
+ N_("You are an ex-player."),
+ N_("You're pining for the fjords.")
+ };
+
+ const int random = rand() % (sizeof(deadMsg) / sizeof(deadMsg[0]));
+ return gettext(deadMsg[random]);
}
PlayerHandler::PlayerHandler()
@@ -113,9 +162,9 @@ PlayerHandler::PlayerHandler()
handledMessages = _messages;
}
-void PlayerHandler::handleMessage(MessageIn *msg)
+void PlayerHandler::handleMessage(MessageIn &msg)
{
- switch (msg->getId())
+ switch (msg.getId())
{
case SMSG_WALK_RESPONSE:
/*
@@ -127,10 +176,10 @@ void PlayerHandler::handleMessage(MessageIn *msg)
case SMSG_PLAYER_WARP:
{
- std::string mapPath = msg->readString(16);
+ std::string mapPath = msg.readString(16);
bool nearby;
- Uint16 x = msg->readInt16();
- Uint16 y = msg->readInt16();
+ Uint16 x = msg.readInt16();
+ Uint16 y = msg.readInt16();
logger->log("Warping to %s (%d, %d)", mapPath.c_str(), x, y);
@@ -145,8 +194,6 @@ void PlayerHandler::handleMessage(MessageIn *msg)
// Switch the actual map, deleting the previous one if necessary
engine->changeMap(mapPath);
- current_npc = 0;
-
float scrollOffsetX = 0.0f;
float scrollOffsetY = 0.0f;
@@ -173,30 +220,30 @@ void PlayerHandler::handleMessage(MessageIn *msg)
case SMSG_PLAYER_STAT_UPDATE_1:
{
- int type = msg->readInt16();
- int value = msg->readInt32();
+ int type = msg.readInt16();
+ int value = msg.readInt32();
switch (type)
{
//case 0x0000:
- // player_node->setWalkSpeed(msg->readInt32());
+ // player_node->setWalkSpeed(msg.readInt32());
// break;
- case 0x0005: player_node->mHp = value; break;
- case 0x0006: player_node->mMaxHp = value; break;
+ case 0x0005: player_node->setHp(value); break;
+ case 0x0006: player_node->setMaxHp(value); break;
case 0x0007: player_node->mMp = value; break;
case 0x0008: player_node->mMaxMp = value; break;
case 0x0009:
player_node->mStatsPointsToAttribute = value;
break;
- case 0x000b: player_node->mLevel = value; break;
+ case 0x000b: player_node->setLevel(value); break;
case 0x000c:
player_node->mSkillPoint = value;
skillDialog->update();
break;
case 0x0018:
- if (value >= player_node->mMaxWeight / 2 &&
- player_node->mTotalWeight <
- player_node->mMaxWeight / 2)
+ if (value >= player_node->getMaxWeight() / 2 &&
+ player_node->getTotalWeight() <
+ player_node->getMaxWeight() / 2)
{
weightNotice = new OkDialog(_("Message"),
_("You are carrying more than "
@@ -205,9 +252,9 @@ void PlayerHandler::handleMessage(MessageIn *msg)
weightNotice->addActionListener(
&weightListener);
}
- player_node->mTotalWeight = value;
+ player_node->setTotalWeight(value);
break;
- case 0x0019: player_node->mMaxWeight = value; break;
+ case 0x0019: player_node->setMaxWeight(value); break;
case 0x0029: player_node->ATK = value; break;
case 0x002b: player_node->MATK = value; break;
case 0x002d: player_node->DEF = value; break;
@@ -219,54 +266,10 @@ void PlayerHandler::handleMessage(MessageIn *msg)
case 0x0037: player_node->mJobLevel = value; break;
}
- if (player_node->mHp == 0 && !deathNotice)
+ if (player_node->getHp() == 0 && !deathNotice)
{
- static char const *const deadMsg[] =
- {
- _("You are dead."),
- _("We regret to inform you that your character was "
- "killed in battle."),
- _("You are not that alive anymore."),
- _("The cold hands of the grim reaper are grabbing for "
- "your soul."),
- _("Game Over!"),
- _("Insert coin to continue"),
- _("No, kids. Your character did not really die. It... "
- "err... went to a better place."),
- _("Your plan of breaking your enemies weapon by "
- "bashing it with your throat failed."),
- _("I guess this did not run too well."),
- // NetHack reference:
- _("Do you want your possessions identified?"),
- // Secret of Mana reference:
- _("Sadly, no trace of you was ever found..."),
- // Final Fantasy VI reference:
- _("Annihilated."),
- // Earthbound reference:
- _("Looks like you got your head handed to you."),
- // Leisure Suit Larry 1 reference:
- _("You screwed up again, dump your body down the tubes "
- "and get you another one."),
- // Monty Python references (Dead Parrot sketch mostly):
- _("You're not dead yet. You're just resting."),
- _("You are no more."),
- _("You have ceased to be."),
- _("You've expired and gone to meet your maker."),
- _("You're a stiff."),
- _("Bereft of life, you rest in peace."),
- _("If you weren't so animated, you'd be pushing up the "
- "daisies."),
- _("Your metabolic processes are now history."),
- _("You're off the twig."),
- _("You've kicked the bucket."),
- _("You've shuffled off your mortal coil, run down the "
- "curtain and joined the bleedin' choir invisibile."),
- _("You are an ex-player."),
- _("You're pining for the fjords.")
- };
- std::string message(deadMsg[rand()%27]);
-
- deathNotice = new OkDialog(_("Message"), message);
+ deathNotice = new OkDialog(_("Message"),
+ randomDeathMessage());
deathNotice->addActionListener(&deathListener);
player_node->setAction(Being::DEAD);
}
@@ -274,36 +277,36 @@ void PlayerHandler::handleMessage(MessageIn *msg)
break;
case SMSG_PLAYER_STAT_UPDATE_2:
- switch (msg->readInt16()) {
+ switch (msg.readInt16()) {
case 0x0001:
- player_node->setXp(msg->readInt32());
+ player_node->setXp(msg.readInt32());
break;
case 0x0002:
- player_node->mJobXp = msg->readInt32();
+ player_node->mJobXp = msg.readInt32();
break;
case 0x0014: {
- Uint32 curGp = player_node->mGp;
- player_node->mGp = msg->readInt32();
- if (player_node->mGp > curGp)
- chatWindow->chatLog(_("You picked up ") +
- toString(player_node->mGp - curGp) + " GP",
- BY_SERVER);
+ int curGp = player_node->getMoney();
+ player_node->setMoney(msg.readInt32());
+ if (player_node->getMoney() > curGp)
+ localChatTab->chatLog(_("You picked up ") +
+ Units::formatCurrency(player_node->getMoney()
+ - curGp), BY_SERVER);
}
break;
case 0x0016:
- player_node->mXpForNextLevel = msg->readInt32();
+ player_node->mXpForNextLevel = msg.readInt32();
break;
case 0x0017:
- player_node->mJobXpForNextLevel = msg->readInt32();
+ player_node->mJobXpForNextLevel = msg.readInt32();
break;
}
break;
case SMSG_PLAYER_STAT_UPDATE_3:
{
- int type = msg->readInt32();
- int base = msg->readInt32();
- int bonus = msg->readInt32();
+ int type = msg.readInt32();
+ int base = msg.readInt32();
+ int bonus = msg.readInt32();
int total = base + bonus;
switch (type) {
@@ -325,9 +328,9 @@ void PlayerHandler::handleMessage(MessageIn *msg)
case SMSG_PLAYER_STAT_UPDATE_4:
{
- int type = msg->readInt16();
- int fail = msg->readInt8();
- int value = msg->readInt8();
+ int type = msg.readInt16();
+ int fail = msg.readInt8();
+ int value = msg.readInt8();
if (fail != 1)
break;
@@ -351,64 +354,64 @@ void PlayerHandler::handleMessage(MessageIn *msg)
// Updates stats and status points
case SMSG_PLAYER_STAT_UPDATE_5:
- player_node->mStatsPointsToAttribute = msg->readInt16();
- player_node->mAttr[LocalPlayer::STR] = msg->readInt8();
- player_node->mAttrUp[LocalPlayer::STR] = msg->readInt8();
- player_node->mAttr[LocalPlayer::AGI] = msg->readInt8();
- player_node->mAttrUp[LocalPlayer::AGI] = msg->readInt8();
- player_node->mAttr[LocalPlayer::VIT] = msg->readInt8();
- player_node->mAttrUp[LocalPlayer::VIT] = msg->readInt8();
- player_node->mAttr[LocalPlayer::INT] = msg->readInt8();
- player_node->mAttrUp[LocalPlayer::INT] = msg->readInt8();
- player_node->mAttr[LocalPlayer::DEX] = msg->readInt8();
- player_node->mAttrUp[LocalPlayer::DEX] = msg->readInt8();
- player_node->mAttr[LocalPlayer::LUK] = msg->readInt8();
- player_node->mAttrUp[LocalPlayer::LUK] = msg->readInt8();
- player_node->ATK = msg->readInt16(); // ATK
- player_node->ATK_BONUS = msg->readInt16(); // ATK bonus
- player_node->MATK = msg->readInt16(); // MATK max
- player_node->MATK_BONUS = msg->readInt16(); // MATK min
- player_node->DEF = msg->readInt16(); // DEF
- player_node->DEF_BONUS = msg->readInt16(); // DEF bonus
- player_node->MDEF = msg->readInt16(); // MDEF
- player_node->MDEF_BONUS = msg->readInt16(); // MDEF bonus
- player_node->HIT = msg->readInt16(); // HIT
- player_node->FLEE = msg->readInt16(); // FLEE
- player_node->FLEE_BONUS = msg->readInt16(); // FLEE bonus
- msg->readInt16(); // critical
- msg->readInt16(); // unknown
+ player_node->mStatsPointsToAttribute = msg.readInt16();
+ player_node->mAttr[LocalPlayer::STR] = msg.readInt8();
+ player_node->mAttrUp[LocalPlayer::STR] = msg.readInt8();
+ player_node->mAttr[LocalPlayer::AGI] = msg.readInt8();
+ player_node->mAttrUp[LocalPlayer::AGI] = msg.readInt8();
+ player_node->mAttr[LocalPlayer::VIT] = msg.readInt8();
+ player_node->mAttrUp[LocalPlayer::VIT] = msg.readInt8();
+ player_node->mAttr[LocalPlayer::INT] = msg.readInt8();
+ player_node->mAttrUp[LocalPlayer::INT] = msg.readInt8();
+ player_node->mAttr[LocalPlayer::DEX] = msg.readInt8();
+ player_node->mAttrUp[LocalPlayer::DEX] = msg.readInt8();
+ player_node->mAttr[LocalPlayer::LUK] = msg.readInt8();
+ player_node->mAttrUp[LocalPlayer::LUK] = msg.readInt8();
+ player_node->ATK = msg.readInt16(); // ATK
+ player_node->ATK_BONUS = msg.readInt16(); // ATK bonus
+ player_node->MATK = msg.readInt16(); // MATK max
+ player_node->MATK_BONUS = msg.readInt16(); // MATK min
+ player_node->DEF = msg.readInt16(); // DEF
+ player_node->DEF_BONUS = msg.readInt16(); // DEF bonus
+ player_node->MDEF = msg.readInt16(); // MDEF
+ player_node->MDEF_BONUS = msg.readInt16(); // MDEF bonus
+ player_node->HIT = msg.readInt16(); // HIT
+ player_node->FLEE = msg.readInt16(); // FLEE
+ player_node->FLEE_BONUS = msg.readInt16(); // FLEE bonus
+ msg.readInt16(); // critical
+ msg.readInt16(); // unknown
break;
case SMSG_PLAYER_STAT_UPDATE_6:
- switch (msg->readInt16()) {
+ switch (msg.readInt16()) {
case 0x0020:
- player_node->mAttrUp[LocalPlayer::STR] = msg->readInt8();
+ player_node->mAttrUp[LocalPlayer::STR] = msg.readInt8();
break;
case 0x0021:
- player_node->mAttrUp[LocalPlayer::AGI] = msg->readInt8();
+ player_node->mAttrUp[LocalPlayer::AGI] = msg.readInt8();
break;
case 0x0022:
- player_node->mAttrUp[LocalPlayer::VIT] = msg->readInt8();
+ player_node->mAttrUp[LocalPlayer::VIT] = msg.readInt8();
break;
case 0x0023:
- player_node->mAttrUp[LocalPlayer::INT] = msg->readInt8();
+ player_node->mAttrUp[LocalPlayer::INT] = msg.readInt8();
break;
case 0x0024:
- player_node->mAttrUp[LocalPlayer::DEX] = msg->readInt8();
+ player_node->mAttrUp[LocalPlayer::DEX] = msg.readInt8();
break;
case 0x0025:
- player_node->mAttrUp[LocalPlayer::LUK] = msg->readInt8();
+ player_node->mAttrUp[LocalPlayer::LUK] = msg.readInt8();
break;
}
break;
case SMSG_PLAYER_ARROW_MESSAGE:
{
- int type = msg->readInt16();
+ int type = msg.readInt16();
switch (type) {
case 0:
- chatWindow->chatLog(_("Equip arrows first"),
+ localChatTab->chatLog(_("Equip arrows first"),
BY_SERVER);
break;
default:
diff --git a/src/net/playerhandler.h b/src/net/ea/playerhandler.h
index 0500ae44..9fb2c982 100644
--- a/src/net/playerhandler.h
+++ b/src/net/ea/playerhandler.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,17 +19,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef NET_PLAYERHANDLER_H
-#define NET_PLAYERHANDLER_H
+#ifndef NET_EA_PLAYERHANDLER_H
+#define NET_EA_PLAYERHANDLER_H
-#include "messagehandler.h"
+#include "net/messagehandler.h"
class PlayerHandler : public MessageHandler
{
public:
PlayerHandler();
- void handleMessage(MessageIn *msg);
+ void handleMessage(MessageIn &msg);
};
-#endif
+#endif // NET_EA_PLAYERHANDLER_H
diff --git a/src/net/protocol.cpp b/src/net/ea/protocol.cpp
index 563c1cc4..9d9db56f 100644
--- a/src/net/protocol.cpp
+++ b/src/net/ea/protocol.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "protocol.h"
+#include "net/ea/protocol.h"
#define LOBYTE(w) ((unsigned char)(w))
#define HIBYTE(w) ((unsigned char)(((unsigned short)(w)) >> 8))
diff --git a/src/net/protocol.h b/src/net/ea/protocol.h
index 645d667f..c96ff7b6 100644
--- a/src/net/protocol.h
+++ b/src/net/ea/protocol.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,8 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PROTOCOL_
-#define PROTOCOL_
+#ifndef EA_PROTOCOL_H
+#define EA_PROTOCOL_H
/*********************************
* Packets from server to client *
diff --git a/src/net/ea/skillhandler.cpp b/src/net/ea/skillhandler.cpp
new file mode 100644
index 00000000..fcc0f4b2
--- /dev/null
+++ b/src/net/ea/skillhandler.cpp
@@ -0,0 +1,208 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/ea/skillhandler.h"
+
+#include "net/ea/protocol.h"
+
+#include "net/messagein.h"
+
+#include "log.h"
+
+#include "gui/chat.h"
+#include "gui/skill.h"
+
+#include "utils/gettext.h"
+
+/** job dependend identifiers (?) */
+#define SKILL_BASIC 0x0001
+#define SKILL_WARP 0x001b
+#define SKILL_STEAL 0x0032
+#define SKILL_ENVENOM 0x0034
+
+/** basic skills identifiers */
+#define BSKILL_TRADE 0x0000
+#define BSKILL_EMOTE 0x0001
+#define BSKILL_SIT 0x0002
+#define BSKILL_CREATECHAT 0x0003
+#define BSKILL_JOINPARTY 0x0004
+#define BSKILL_SHOUT 0x0005
+#define BSKILL_PK 0x0006 // ??
+#define BSKILL_SETALLIGN 0x0007 // ??
+
+/** reasons why action failed */
+#define RFAIL_SKILLDEP 0x00
+#define RFAIL_INSUFHP 0x01
+#define RFAIL_INSUFSP 0x02
+#define RFAIL_NOMEMO 0x03
+#define RFAIL_SKILLDELAY 0x04
+#define RFAIL_ZENY 0x05
+#define RFAIL_WEAPON 0x06
+#define RFAIL_REDGEM 0x07
+#define RFAIL_BLUEGEM 0x08
+#define RFAIL_OVERWEIGHT 0x09
+#define RFAIL_GENERIC 0x0a
+
+/** should always be zero if failed */
+#define SKILL_FAILED 0x00
+
+SkillHandler::SkillHandler()
+{
+ static const Uint16 _messages[] = {
+ SMSG_PLAYER_SKILLS,
+ SMSG_SKILL_FAILED,
+ 0
+ };
+ handledMessages = _messages;
+}
+
+void SkillHandler::handleMessage(MessageIn &msg)
+{
+ int skillCount;
+
+ switch (msg.getId())
+ {
+ case SMSG_PLAYER_SKILLS:
+ msg.readInt16(); // length
+ skillCount = (msg.getLength() - 4) / 37;
+ skillDialog->cleanList();
+
+ for (int k = 0; k < skillCount; k++)
+ {
+ int skillId = msg.readInt16();
+ msg.readInt16(); // target type
+ msg.readInt16(); // unknown
+ int level = msg.readInt16();
+ int sp = msg.readInt16();
+ msg.readInt16(); // range
+ std::string skillName = msg.readString(24);
+ int up = msg.readInt8();
+
+ if (level != 0 || up != 0)
+ {
+ if (skillDialog->hasSkill(skillId)) {
+ skillDialog->setSkill(skillId, level, sp);
+ }
+ else {
+ skillDialog->addSkill(skillId, level, sp);
+ }
+ }
+ }
+ skillDialog->update();
+ break;
+
+ case SMSG_SKILL_FAILED:
+ // Action failed (ex. sit because you have not reached the
+ // right level)
+ short skill = msg.readInt16();
+ short bskill = msg.readInt16();
+ msg.readInt16(); // unknown
+ char success = msg.readInt8();
+ char reason = msg.readInt8();
+ if (success != SKILL_FAILED && bskill == BSKILL_EMOTE)
+ {
+ logger->log("Action: %d/%d", bskill, success);
+ }
+
+ std::string msg;
+ if (success == SKILL_FAILED && skill == SKILL_BASIC)
+ {
+ switch (bskill)
+ {
+ case BSKILL_TRADE:
+ msg = _("Trade failed!");
+ break;
+ case BSKILL_EMOTE:
+ msg = _("Emote failed!");
+ break;
+ case BSKILL_SIT:
+ msg = _("Sit failed!");
+ break;
+ case BSKILL_CREATECHAT:
+ msg = _("Chat creating failed!");
+ break;
+ case BSKILL_JOINPARTY:
+ msg = _("Could not join party!");
+ break;
+ case BSKILL_SHOUT:
+ msg = _("Cannot shout!");
+ break;
+ }
+
+ msg += " ";
+
+ switch (reason)
+ {
+ case RFAIL_SKILLDEP:
+ msg += _("You have not yet reached a high enough lvl!");
+ break;
+ case RFAIL_INSUFHP:
+ msg += _("Insufficient HP!");
+ break;
+ case RFAIL_INSUFSP:
+ msg += _("Insufficient SP!");
+ break;
+ case RFAIL_NOMEMO:
+ msg += _("You have no memos!");
+ break;
+ case RFAIL_SKILLDELAY:
+ msg += _("You cannot do that right now!");
+ break;
+ case RFAIL_ZENY:
+ msg += _("Seems you need more money... ;-)");
+ break;
+ case RFAIL_WEAPON:
+ msg += _("You cannot use this skill with that kind of weapon!");
+ break;
+ case RFAIL_REDGEM:
+ msg += _("You need another red gem!");
+ break;
+ case RFAIL_BLUEGEM:
+ msg += _("You need another blue gem!");
+ break;
+ case RFAIL_OVERWEIGHT:
+ msg += _("You're carrying to much to do this!");
+ break;
+ default:
+ msg += _("Huh? What's that?");
+ break;
+ }
+ }
+ else
+ {
+ switch (skill)
+ {
+ case SKILL_WARP :
+ msg = _("Warp failed...");
+ break;
+ case SKILL_STEAL :
+ msg = _("Could not steal anything...");
+ break;
+ case SKILL_ENVENOM :
+ msg = _("Poison had no effect...");
+ break;
+ }
+ }
+
+ localChatTab->chatLog(msg);
+ break;
+ }
+}
diff --git a/src/net/skillhandler.h b/src/net/ea/skillhandler.h
index 689e42dc..f2c950c9 100644
--- a/src/net/skillhandler.h
+++ b/src/net/ea/skillhandler.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,17 +19,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef NET_SKILLHANDLER_H
-#define NET_SKILLHANDLER_H
+#ifndef NET_EA_SKILLHANDLER_H
+#define NET_EA_SKILLHANDLER_H
-#include "messagehandler.h"
+#include "net/messagehandler.h"
class SkillHandler : public MessageHandler
{
public:
SkillHandler();
- void handleMessage(MessageIn *msg);
+ void handleMessage(MessageIn &msg);
};
-#endif
+#endif // NET_EA_SKILLHANDLER_H
diff --git a/src/net/tradehandler.cpp b/src/net/ea/tradehandler.cpp
index fd772d01..ea41ed70 100644
--- a/src/net/tradehandler.cpp
+++ b/src/net/ea/tradehandler.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,20 +19,22 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "messagein.h"
-#include "protocol.h"
-#include "tradehandler.h"
+#include "net/ea/tradehandler.h"
-#include "../inventory.h"
-#include "../item.h"
-#include "../localplayer.h"
-#include "../player_relations.h"
+#include "net/ea/protocol.h"
-#include "../gui/chat.h"
-#include "../gui/confirm_dialog.h"
-#include "../gui/trade.h"
+#include "net/messagein.h"
-#include "../utils/gettext.h"
+#include "inventory.h"
+#include "item.h"
+#include "localplayer.h"
+#include "player_relations.h"
+
+#include "gui/chat.h"
+#include "gui/confirm_dialog.h"
+#include "gui/trade.h"
+
+#include "utils/gettext.h"
std::string tradePartnerName;
@@ -46,7 +47,7 @@ namespace {
void action(const gcn::ActionEvent &event)
{
player_node->tradeReply(event.getId() == "yes");
- };
+ }
} listener;
}
@@ -66,9 +67,9 @@ TradeHandler::TradeHandler()
}
-void TradeHandler::handleMessage(MessageIn *msg)
+void TradeHandler::handleMessage(MessageIn &msg)
{
- switch (msg->getId())
+ switch (msg.getId())
{
case SMSG_TRADE_REQUEST:
// If a trade window or request window is already open, send a
@@ -77,7 +78,7 @@ void TradeHandler::handleMessage(MessageIn *msg)
// Note that it would be nice if the server would prevent this
// situation, and that the requesting player would get a
// special message about the player being occupied.
- tradePartnerName = msg->readString(24);
+ tradePartnerName = msg.readString(24);
if (player_relations.hasPermission(tradePartnerName, PlayerRelation::TRADE))
{
@@ -102,18 +103,18 @@ void TradeHandler::handleMessage(MessageIn *msg)
break;
case SMSG_TRADE_RESPONSE:
- switch (msg->readInt8())
+ switch (msg.readInt8())
{
case 0: // Too far away
- chatWindow->chatLog(_("Trading isn't possible. Trade partner is too far away."),
+ localChatTab->chatLog(_("Trading isn't possible. Trade partner is too far away."),
BY_SERVER);
break;
case 1: // Character doesn't exist
- chatWindow->chatLog(_("Trading isn't possible. Character doesn't exist."),
+ localChatTab->chatLog(_("Trading isn't possible. Character doesn't exist."),
BY_SERVER);
break;
case 2: // Invite request check failed...
- chatWindow->chatLog(_("Trade cancelled due to an unknown reason."),
+ localChatTab->chatLog(_("Trade cancelled due to an unknown reason."),
BY_SERVER);
break;
case 3: // Trade accepted
@@ -125,7 +126,7 @@ void TradeHandler::handleMessage(MessageIn *msg)
case 4: // Trade cancelled
if (player_relations.hasPermission(tradePartnerName,
PlayerRelation::SPEECH_LOG))
- chatWindow->chatLog(_("Trade with ") + tradePartnerName +
+ localChatTab->chatLog(_("Trade with ") + tradePartnerName +
_(" cancelled"), BY_SERVER);
// otherwise ignore silently
@@ -133,7 +134,7 @@ void TradeHandler::handleMessage(MessageIn *msg)
player_node->setTrading(false);
break;
default: // Shouldn't happen as well, but to be sure
- chatWindow->chatLog(_("Unhandled trade cancel packet"),
+ localChatTab->chatLog(_("Unhandled trade cancel packet"),
BY_SERVER);
break;
}
@@ -141,16 +142,16 @@ void TradeHandler::handleMessage(MessageIn *msg)
case SMSG_TRADE_ITEM_ADD:
{
- int amount = msg->readInt32();
- int type = msg->readInt16();
- msg->readInt8(); // identified flag
- msg->readInt8(); // attribute
- msg->readInt8(); // refine
- msg->skip(8); // card (4 shorts)
+ int amount = msg.readInt32();
+ int type = msg.readInt16();
+ msg.readInt8(); // identified flag
+ msg.readInt8(); // attribute
+ msg.readInt8(); // refine
+ msg.skip(8); // card (4 shorts)
// TODO: handle also identified, etc
if (type == 0) {
- tradeWindow->addMoney(amount);
+ tradeWindow->setMoney(amount);
} else {
tradeWindow->addItem(type, false, amount, false);
}
@@ -160,16 +161,16 @@ void TradeHandler::handleMessage(MessageIn *msg)
case SMSG_TRADE_ITEM_ADD_RESPONSE:
// Trade: New Item add response (was 0x00ea, now 01b1)
{
- const int index = msg->readInt16();
+ const int index = msg.readInt16();
Item *item = player_node->getInventory()->getItem(index);
if (!item)
{
tradeWindow->receivedOk(true);
return;
}
- int quantity = msg->readInt16();
+ int quantity = msg.readInt16();
- switch (msg->readInt8())
+ switch (msg.readInt8())
{
case 0:
// Successfully added item
@@ -183,16 +184,16 @@ void TradeHandler::handleMessage(MessageIn *msg)
break;
case 1:
// Add item failed - player overweighted
- chatWindow->chatLog(_("Failed adding item. Trade partner is over weighted."),
+ localChatTab->chatLog(_("Failed adding item. Trade partner is over weighted."),
BY_SERVER);
break;
case 2:
// Add item failed - player has no free slot
- chatWindow->chatLog(_("Failed adding item. Trade partner has no free slot."),
+ localChatTab->chatLog(_("Failed adding item. Trade partner has no free slot."),
BY_SERVER);
break;
default:
- chatWindow->chatLog(_("Failed adding item for unknown reason."),
+ localChatTab->chatLog(_("Failed adding item for unknown reason."),
BY_SERVER);
break;
}
@@ -201,18 +202,18 @@ void TradeHandler::handleMessage(MessageIn *msg)
case SMSG_TRADE_OK:
// 0 means ok from myself, 1 means ok from other;
- tradeWindow->receivedOk(msg->readInt8() == 0);
+ tradeWindow->receivedOk(msg.readInt8() == 0);
break;
case SMSG_TRADE_CANCEL:
- chatWindow->chatLog(_("Trade canceled."), BY_SERVER);
+ localChatTab->chatLog(_("Trade canceled."), BY_SERVER);
tradeWindow->setVisible(false);
tradeWindow->reset();
player_node->setTrading(false);
break;
case SMSG_TRADE_COMPLETE:
- chatWindow->chatLog(_("Trade completed."), BY_SERVER);
+ localChatTab->chatLog(_("Trade completed."), BY_SERVER);
tradeWindow->setVisible(false);
tradeWindow->reset();
player_node->setTrading(false);
diff --git a/src/net/tradehandler.h b/src/net/ea/tradehandler.h
index 8f108248..e141f6b5 100644
--- a/src/net/tradehandler.h
+++ b/src/net/ea/tradehandler.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,19 +19,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef NET_TRADEHANDLER_H
-#define NET_TRADEHANDLER_H
+#ifndef NET_EA_TRADEHANDLER_H
+#define NET_EA_TRADEHANDLER_H
-#include "messagehandler.h"
-
-class Network;
+#include "net/messagehandler.h"
class TradeHandler : public MessageHandler
{
public:
TradeHandler();
- void handleMessage(MessageIn *msg);
+ void handleMessage(MessageIn &msg);
};
-#endif
+#endif // NET_EA_TRADEHANDLER_H
diff --git a/src/net/messagehandler.cpp b/src/net/messagehandler.cpp
index f45000be..4cb6af0b 100644
--- a/src/net/messagehandler.cpp
+++ b/src/net/messagehandler.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,24 +19,37 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <cassert>
+#include "net/messagehandler.h"
+
+#ifdef TMWSERV_SUPPORT
+#include "net/tmwserv/network.h"
+#else
+#include "net/ea/network.h"
+#endif
-#include "messagehandler.h"
-#include "network.h"
+#include <cassert>
-MessageHandler::MessageHandler():
- mNetwork(0)
+MessageHandler::MessageHandler()
+#ifdef EATHENA_SUPPORT
+ : mNetwork(0)
+#endif
{
}
MessageHandler::~MessageHandler()
{
+#ifdef TMWSERV_SUPPORT
+ Net::unregisterHandler(this);
+#else
if (mNetwork)
mNetwork->unregisterHandler(this);
+#endif
}
+#ifdef EATHENA_SUPPORT
void MessageHandler::setNetwork(Network *network)
{
assert(!(network && mNetwork));
mNetwork = network;
}
+#endif
diff --git a/src/net/messagehandler.h b/src/net/messagehandler.h
index 7ff5194b..261a8351 100644
--- a/src/net/messagehandler.h
+++ b/src/net/messagehandler.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,8 +25,13 @@
#include <SDL_types.h>
class MessageIn;
+#ifdef EATHENA_SUPPORT
class Network;
+#endif
+/**
+ * \ingroup Network
+ */
class MessageHandler
{
public:
@@ -36,12 +40,14 @@ class MessageHandler
MessageHandler();
virtual ~MessageHandler();
- virtual void handleMessage(MessageIn *msg) =0;
+ virtual void handleMessage(MessageIn &msg) = 0;
+#ifdef EATHENA_SUPPORT
void setNetwork(Network *network);
protected:
Network *mNetwork;
+#endif
};
#endif
diff --git a/src/net/messagein.cpp b/src/net/messagein.cpp
index f1ff4013..f365bb7f 100644
--- a/src/net/messagein.cpp
+++ b/src/net/messagein.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,11 +19,16 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <cassert>
+#include "net/messagein.h"
+
+#ifdef TMWSERV_SUPPORT
+#include <enet/enet.h>
+#else
#include <SDL.h>
#include <SDL_endian.h>
+#endif
-#include "messagein.h"
+#include <cassert>
#define MAKEWORD(low,high) \
((unsigned short)(((unsigned char)(low)) | \
@@ -39,32 +43,68 @@ MessageIn::MessageIn(const char *data, unsigned int length):
mId = readInt16();
}
-Sint8 MessageIn::readInt8()
+int MessageIn::readInt8()
{
- assert(mPos < mLength);
- return mData[mPos++];
+ int value = -1;
+ if (mPos < mLength)
+ {
+ value = (unsigned char) mData[mPos];
+ }
+ mPos += 1;
+ return value;
}
-Sint16 MessageIn::readInt16()
+int MessageIn::readInt16()
{
- assert(mPos + 2 <= mLength);
- mPos += 2;
+ int value = -1;
+ if (mPos + 2 <= mLength)
+ {
+#ifdef TMWSERV_SUPPORT
+ uint16_t t;
+ memcpy(&t, mData + mPos, 2);
+ value = (unsigned short) ENET_NET_TO_HOST_16(t);
+#else
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- return SDL_Swap16(*(Sint16*)(mData + (mPos - 2)));
+ value = SDL_Swap16(*(Sint16*)(mData + mPos));
#else
- return (*(Sint16*)(mData + (mPos - 2)));
+ value = (*(Sint16*)(mData + mPos));
#endif
+#endif // TMWSERV_SUPPORT
+ }
+ mPos += 2;
+ return value;
}
-Sint32 MessageIn::readInt32()
+int MessageIn::readInt32()
{
- assert(mPos + 4 <= mLength);
- mPos += 4;
+ int value = -1;
+ if (mPos + 4 <= mLength)
+ {
+#ifdef TMWSERV_SUPPORT
+ uint32_t t;
+ memcpy(&t, mData + mPos, 4);
+ value = ENET_NET_TO_HOST_32(t);
+#else
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- return SDL_Swap32(*(Sint32*)(mData + (mPos - 4)));
+ value = SDL_Swap32(*(Sint32*)(mData + mPos));
#else
- return (*(Sint32*)(mData + (mPos - 4)));
+ value = (*(Sint32*)(mData + mPos));
#endif
+#endif // TMWSERV_SUPPORT
+ }
+ mPos += 4;
+ return value;
+}
+
+void MessageIn::readCoordinates(Uint16 &x, Uint16 &y)
+{
+ if (mPos + 3 <= mLength)
+ {
+ unsigned char const *p = reinterpret_cast< unsigned char const * >(mData + mPos);
+ x = p[0] | ((p[1] & 0x07) << 8);
+ y = (p[1] >> 3) | ((p[2] & 0x3F) << 5);
+ }
+ mPos += 3;
}
void MessageIn::readCoordinates(Uint16 &x, Uint16 &y, Uint8 &direction)
@@ -165,21 +205,3 @@ std::string MessageIn::readString(int length)
mPos += length;
return readString;
}
-
-Sint8& operator<<(Sint8 &lhs, MessageIn &msg)
-{
- lhs = msg.readInt8();
- return lhs;
-}
-
-Sint16& operator<<(Sint16 &lhs, MessageIn &msg)
-{
- lhs = msg.readInt16();
- return lhs;
-}
-
-Sint32& operator<<(Sint32 &lhs, MessageIn &msg)
-{
- lhs = msg.readInt32();
- return lhs;
-}
diff --git a/src/net/messagein.h b/src/net/messagein.h
index 94f2bee7..0d0e9981 100644
--- a/src/net/messagein.h
+++ b/src/net/messagein.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,13 +27,11 @@
/**
* Used for parsing an incoming message.
+ *
+ * \ingroup Network
*/
class MessageIn
{
- friend Sint8& operator<<(Sint8 &lhs, MessageIn &msg);
- friend Sint16& operator<<(Sint16 &lhs, MessageIn &msg);
- friend Sint32& operator<<(Sint32 &lhs, MessageIn &msg);
-
public:
/**
* Constructor.
@@ -44,16 +41,27 @@ class MessageIn
/**
* Returns the message ID.
*/
- short getId() { return mId; }
+ int getId() const { return mId; }
/**
* Returns the message length.
*/
- unsigned int getLength() { return mLength; }
+ unsigned int getLength() const { return mLength; }
+
+ /**
+ * Returns the length of unread data.
+ */
+ unsigned int getUnreadLength() const { return mLength - mPos; }
- Sint8 readInt8(); /**< Reads a byte. */
- Sint16 readInt16(); /**< Reads a short. */
- Sint32 readInt32(); /**< Reads a long. */
+ int readInt8(); /**< Reads a byte. */
+ int readInt16(); /**< Reads a short. */
+ int readInt32(); /**< Reads a long. */
+
+ /**
+ * Reads a 3-byte block containing tile-based coordinates. Used by
+ * tmwserv.
+ */
+ void readCoordinates(Uint16 &x, Uint16 &y);
/**
* Reads a special 3 byte block used by eAthena, containing x and y
@@ -83,8 +91,14 @@ class MessageIn
private:
const char* mData; /**< The message data. */
unsigned int mLength; /**< The length of the data. */
- unsigned int mPos; /**< The position in the data. */
- short mId; /**< The message ID. */
+ unsigned short mId; /**< The message ID. */
+
+ /**
+ * Actual position in the packet. From 0 to packet->length.
+ * A value bigger than packet->length means EOP was reached when
+ * reading it.
+ */
+ unsigned int mPos;
};
#endif
diff --git a/src/net/messageout.cpp b/src/net/messageout.cpp
index ab17f537..4cb4dc36 100644
--- a/src/net/messageout.cpp
+++ b/src/net/messageout.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,95 +19,132 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <cstring>
+#include "net/messageout.h"
+
+#ifdef TMWSERV_SUPPORT
+#include <enet/enet.h>
+#else
+#include "net/ea/network.h"
+
#include <SDL.h>
#include <SDL_endian.h>
-#include <string>
+#endif
-#include "messageout.h"
-#include "network.h"
+#include <cstring>
+#include <string>
+#ifdef TMWSERV_SUPPORT
+MessageOut::MessageOut(short id):
+ mData(0),
+#else
MessageOut::MessageOut(Network *network):
mNetwork(network),
- mData(0),
+#endif
mDataSize(0),
mPos(0)
{
+#ifdef TMWSERV_SUPPORT
+ writeInt16(id);
+#else
mData = mNetwork->mOutBuffer + mNetwork->mOutSize;
+#endif
}
+#ifdef TMWSERV_SUPPORT
+MessageOut::~MessageOut()
+{
+ free(mData);
+}
+
+void MessageOut::expand(size_t bytes)
+{
+ mData = (char*)realloc(mData, bytes);
+ mDataSize = bytes;
+}
+#endif
+
void MessageOut::writeInt8(Sint8 value)
{
+#ifdef TMWSERV_SUPPORT
+ expand(mPos + 1);
+#else
+ mNetwork->mOutSize += 1;
+#endif
mData[mPos] = value;
- mPos += sizeof(Sint8);
- mNetwork->mOutSize+= sizeof(Sint8);
+ mPos += 1;
}
void MessageOut::writeInt16(Sint16 value)
{
+#ifdef TMWSERV_SUPPORT
+ expand(mPos + 2);
+ uint16_t t = ENET_HOST_TO_NET_16(value);
+ memcpy(mData + mPos, &t, 2);
+#else
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
(*(Sint16 *)(mData + mPos)) = SDL_Swap16(value);
#else
(*(Sint16 *)(mData + mPos)) = value;
#endif
- mPos += sizeof(Sint16);
- mNetwork->mOutSize += sizeof(Sint16);
+ mNetwork->mOutSize += 2;
+#endif // TMWSERV_SUPPORT
+ mPos += 2;
}
void MessageOut::writeInt32(Sint32 value)
{
+#ifdef TMWSERV_SUPPORT
+ expand(mPos + 4);
+ uint32_t t = ENET_HOST_TO_NET_32(value);
+ memcpy(mData + mPos, &t, 4);
+#else
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
(*(Sint32 *)(mData + mPos)) = SDL_Swap32(value);
#else
(*(Sint32 *)(mData + mPos)) = value;
#endif
- mPos += sizeof(Sint32);
- mNetwork->mOutSize += sizeof(Sint32);
+ mNetwork->mOutSize += 4;
+#endif // TMWSERV_SUPPORT
+ mPos += 4;
}
void MessageOut::writeString(const std::string &string, int length)
{
- std::string toWrite = string;
-
+ int stringLength = string.length();
if (length < 0)
{
// Write the length at the start if not fixed
- writeInt16(string.length());
+ writeInt16(stringLength);
+ length = stringLength;
}
- else
+ else if (length < stringLength)
{
// Make sure the length of the string is no longer than specified
- toWrite = string.substr(0, length);
+ stringLength = length;
}
+#ifdef TMWSERV_SUPPORT
+ expand(mPos + length);
+#else
+ mNetwork->mOutSize += length;
+#endif
// Write the actual string
- memcpy(&mData[mPos], (void*)toWrite.c_str(), toWrite.length());
- mPos += toWrite.length();
- mNetwork->mOutSize += toWrite.length();
+ memcpy(mData + mPos, string.c_str(), stringLength);
// Pad remaining space with zeros
- if (length > (int)toWrite.length())
+ if (length > stringLength)
{
- memset(&mData[mPos], '\0', length - toWrite.length());
- mPos += length - toWrite.length();
- mNetwork->mOutSize += length - toWrite.length();
+ memset(mData + mPos + stringLength, '\0', length - stringLength);
}
+ mPos += length;
}
-MessageOut& operator<<(MessageOut &msg, const Sint8 &rhs)
-{
- msg.writeInt8(rhs);
- return msg;
-}
-
-MessageOut& operator<<(MessageOut &msg, const Sint16 &rhs)
+char *MessageOut::getData() const
{
- msg.writeInt16(rhs);
- return msg;
+ return mData;
}
-MessageOut& operator<<(MessageOut &msg, const Sint32 &rhs)
+unsigned int MessageOut::getDataSize() const
{
- msg.writeInt32(rhs);
- return msg;
+ return mDataSize;
}
diff --git a/src/net/messageout.h b/src/net/messageout.h
index 93f1c2e8..bc701b92 100644
--- a/src/net/messageout.h
+++ b/src/net/messageout.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,26 +25,38 @@
#include <iosfwd>
#include <SDL_types.h>
+#ifdef EATHENA_SUPPORT
class Network;
+#endif
/**
* Used for building an outgoing message.
+ *
+ * With tmwserv, the message is sent using Net::Connection::send() when
+ * finished.
+ *
+ * \ingroup Network
*/
class MessageOut
{
- friend MessageOut& operator<<(MessageOut &msg, const Sint8 &rhs);
- friend MessageOut& operator<<(MessageOut &msg, const Sint16 &rhs);
- friend MessageOut& operator<<(MessageOut &msg, const Sint32 &rhs);
-
public:
/**
* Constructor.
*/
+#ifdef TMWSERV_SUPPORT
+ MessageOut(short id);
+
+ /**
+ * Destructor.
+ */
+ ~MessageOut();
+#else
MessageOut(Network *network);
+#endif
void writeInt8(Sint8 value); /**< Writes a byte. */
void writeInt16(Sint16 value); /**< Writes a short. */
- void writeInt32(Sint32 value); /**< Writes a long. */
+ void writeInt32(Sint32 value); /**< Writes a long. */
/**
* Writes a string. If a fixed length is not given (-1), it is stored
@@ -53,8 +64,29 @@ class MessageOut
*/
void writeString(const std::string &string, int length = -1);
+ /**
+ * Returns the content of the message.
+ */
+ char *getData() const;
+
+ /**
+ * Returns the length of the data.
+ */
+ unsigned int getDataSize() const;
+
private:
+#ifdef TMWSERV_SUPPORT
+ /**
+ * Expand the packet data to be able to hold more data.
+ *
+ * NOTE: For performance enhancements this method could allocate extra
+ * memory in advance instead of expanding size every time more data is
+ * added.
+ */
+ void expand(size_t size);
+#else
Network *mNetwork;
+#endif
char *mData; /**< Data building up. */
unsigned int mDataSize; /**< Size of data. */
diff --git a/src/net/skillhandler.cpp b/src/net/skillhandler.cpp
deleted file mode 100644
index be757d7c..00000000
--- a/src/net/skillhandler.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Aethyra
- * Copyright (C) 2004 The Mana World Development Team
- *
- * This file is part of Aethyra based on original code
- * from The Mana World.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "messagein.h"
-#include "protocol.h"
-#include "skillhandler.h"
-
-#include "../log.h"
-
-#include "../gui/chat.h"
-#include "../gui/skill.h"
-
-SkillHandler::SkillHandler()
-{
- static const Uint16 _messages[] = {
- SMSG_PLAYER_SKILLS,
- SMSG_SKILL_FAILED,
- 0
- };
- handledMessages = _messages;
-}
-
-void SkillHandler::handleMessage(MessageIn *msg)
-{
- int skillCount;
-
- switch (msg->getId())
- {
- case SMSG_PLAYER_SKILLS:
- msg->readInt16(); // length
- skillCount = (msg->getLength() - 4) / 37;
- skillDialog->cleanList();
-
- for (int k = 0; k < skillCount; k++)
- {
- int skillId = msg->readInt16();
- msg->readInt16(); // target type
- msg->readInt16(); // unknown
- int level = msg->readInt16();
- int sp = msg->readInt16();
- msg->readInt16(); // range
- std::string skillName = msg->readString(24);
- int up = msg->readInt8();
-
- if (level != 0 || up != 0)
- {
- if (skillDialog->hasSkill(skillId)) {
- skillDialog->setSkill(skillId, level, sp);
- }
- else {
- skillDialog->addSkill(skillId, level, sp);
- }
- }
- }
- skillDialog->update();
- break;
-
- case SMSG_SKILL_FAILED:
- // Action failed (ex. sit because you have not reached the
- // right level)
- CHATSKILL action;
- action.skill = msg->readInt16();
- action.bskill = msg->readInt16();
- action.unused = msg->readInt16(); // unknown
- action.success = msg->readInt8();
- action.reason = msg->readInt8();
- if (action.success != SKILL_FAILED &&
- action.bskill == BSKILL_EMOTE)
- {
- logger->log("Action: %d/%d", action.bskill, action.success);
- }
- chatWindow->chatLog(action);
- break;
- }
-}
diff --git a/src/net/tmwserv/accountserver/account.cpp b/src/net/tmwserv/accountserver/account.cpp
new file mode 100644
index 00000000..e6c1830b
--- /dev/null
+++ b/src/net/tmwserv/accountserver/account.cpp
@@ -0,0 +1,108 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "account.h"
+
+#include "internal.h"
+
+#include "net/tmwserv/connection.h"
+#include "net/tmwserv/protocol.h"
+
+#include "net/messageout.h"
+
+#include "utils/sha256.h"
+
+#include <string>
+
+void Net::AccountServer::Account::createCharacter(
+ const std::string &name, char hairStyle, char hairColor, char gender,
+ short strength, short agility, short vitality,
+ short intelligence, short dexterity, short willpower)
+{
+ MessageOut msg(PAMSG_CHAR_CREATE);
+
+ msg.writeString(name);
+ msg.writeInt8(hairStyle);
+ msg.writeInt8(hairColor);
+ msg.writeInt8(gender);
+ msg.writeInt16(strength);
+ msg.writeInt16(agility);
+ msg.writeInt16(vitality);
+ msg.writeInt16(intelligence);
+ msg.writeInt16(dexterity);
+ msg.writeInt16(willpower);
+
+ Net::AccountServer::connection->send(msg);
+}
+
+void Net::AccountServer::Account::deleteCharacter(char slot)
+{
+ MessageOut msg(PAMSG_CHAR_DELETE);
+
+ msg.writeInt8(slot);
+
+ Net::AccountServer::connection->send(msg);
+}
+
+void Net::AccountServer::Account::selectCharacter(char slot)
+{
+ MessageOut msg(PAMSG_CHAR_SELECT);
+
+ msg.writeInt8(slot);
+
+ Net::AccountServer::connection->send(msg);
+}
+
+void Net::AccountServer::Account::unregister(const std::string &username,
+ const std::string &password)
+{
+ MessageOut msg(PAMSG_UNREGISTER);
+
+ msg.writeString(username);
+ msg.writeString(sha256(username + password));
+
+ Net::AccountServer::connection->send(msg);
+}
+
+void Net::AccountServer::Account::changeEmail(const std::string &email)
+{
+ MessageOut msg(PAMSG_EMAIL_CHANGE);
+
+ // Email is sent clearly so the server can validate the data.
+ // Encryption is assumed server-side.
+ msg.writeString(email);
+
+ Net::AccountServer::connection->send(msg);
+}
+
+void Net::AccountServer::Account::changePassword(
+ const std::string &username,
+ const std::string &oldPassword,
+ const std::string &newPassword)
+{
+ MessageOut msg(PAMSG_PASSWORD_CHANGE);
+
+ // Change password using SHA2 encryption
+ msg.writeString(sha256(username + oldPassword));
+ msg.writeString(sha256(username + newPassword));
+
+ Net::AccountServer::connection->send(msg);
+}
diff --git a/src/net/tmwserv/accountserver/account.h b/src/net/tmwserv/accountserver/account.h
new file mode 100644
index 00000000..03e83881
--- /dev/null
+++ b/src/net/tmwserv/accountserver/account.h
@@ -0,0 +1,54 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_ACCOUNTSERVER_CHARACTER_H
+#define NET_ACCOUNTSERVER_CHARACTER_H
+
+#include <iosfwd>
+
+namespace Net
+{
+ namespace AccountServer
+ {
+ namespace Account
+ {
+ void createCharacter(const std::string &name,
+ char hairStyle, char hairColor, char gender,
+ short strength, short agility, short vitality,
+ short intelligence, short dexterity, short willpower);
+
+ void deleteCharacter(char slot);
+
+ void selectCharacter(char slot);
+
+ void unregister(const std::string &username,
+ const std::string &password);
+
+ void changeEmail(const std::string &email);
+
+ void changePassword(const std::string &username,
+ const std::string &oldPassword,
+ const std::string &newPassword);
+ }
+ }
+}
+
+#endif
diff --git a/src/net/tmwserv/accountserver/accountserver.cpp b/src/net/tmwserv/accountserver/accountserver.cpp
new file mode 100644
index 00000000..83895377
--- /dev/null
+++ b/src/net/tmwserv/accountserver/accountserver.cpp
@@ -0,0 +1,82 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "accountserver.h"
+
+#include "internal.h"
+
+#include "net/tmwserv/connection.h"
+#include "net/tmwserv/protocol.h"
+
+#include "net/messageout.h"
+
+#include "utils/sha256.h"
+
+#include <string>
+
+void Net::AccountServer::login(Net::Connection *connection, int version,
+ const std::string &username, const std::string &password)
+{
+ Net::AccountServer::connection = connection;
+
+ MessageOut msg(PAMSG_LOGIN);
+
+ msg.writeInt32(version);
+ msg.writeString(username);
+ msg.writeString(sha256(username + password));
+
+ Net::AccountServer::connection->send(msg);
+}
+
+void Net::AccountServer::registerAccount(Net::Connection *connection,
+ int version, const std::string &username, const std::string &password,
+ const std::string &email)
+{
+ Net::AccountServer::connection = connection;
+
+ MessageOut msg(PAMSG_REGISTER);
+
+ msg.writeInt32(version); // client version
+ msg.writeString(username);
+ // When registering, the password and email hash is assumed by server.
+ // Hence, data can be validated safely server-side.
+ // This is the only time we send a clear password.
+ msg.writeString(password);
+ msg.writeString(email);
+
+ Net::AccountServer::connection->send(msg);
+}
+
+void Net::AccountServer::logout()
+{
+ MessageOut msg(PAMSG_LOGOUT);
+ Net::AccountServer::connection->send(msg);
+}
+
+void Net::AccountServer::reconnectAccount(Net::Connection *connection,
+ const std::string &passToken)
+{
+ Net::AccountServer::connection = connection;
+
+ MessageOut msg(PAMSG_RECONNECT);
+ msg.writeString(passToken, 32);
+ Net::AccountServer::connection->send(msg);
+}
diff --git a/src/net/tmwserv/accountserver/accountserver.h b/src/net/tmwserv/accountserver/accountserver.h
new file mode 100644
index 00000000..dd62fd25
--- /dev/null
+++ b/src/net/tmwserv/accountserver/accountserver.h
@@ -0,0 +1,47 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_ACCOUNTSERVER_ACCOUNTSERVER_H
+#define NET_ACCOUNTSERVER_ACCOUNTSERVER_H
+
+#include <iosfwd>
+
+namespace Net
+{
+ class Connection;
+
+ namespace AccountServer
+ {
+ void login(Net::Connection *connection, int version,
+ const std::string &username, const std::string &password);
+
+ void registerAccount(Net::Connection *connection, int version,
+ const std::string &username, const std::string &password,
+ const std::string &email);
+
+ void logout();
+
+ void reconnectAccount(Net::Connection *connection,
+ const std::string &passToken);
+ }
+}
+
+#endif
diff --git a/src/net/tmwserv/accountserver/internal.cpp b/src/net/tmwserv/accountserver/internal.cpp
new file mode 100644
index 00000000..de1d412c
--- /dev/null
+++ b/src/net/tmwserv/accountserver/internal.cpp
@@ -0,0 +1,32 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "internal.h"
+
+namespace Net
+{
+ class Connection;
+
+ namespace AccountServer
+ {
+ Connection *connection = 0;
+ }
+}
diff --git a/src/net/tmwserv/accountserver/internal.h b/src/net/tmwserv/accountserver/internal.h
new file mode 100644
index 00000000..ff741872
--- /dev/null
+++ b/src/net/tmwserv/accountserver/internal.h
@@ -0,0 +1,35 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_ACCOUNTSERVER_INTERNAL_H
+#define NET_ACCOUNTSERVER_INTERNAL_H
+
+namespace Net
+{
+ class Connection;
+
+ namespace AccountServer
+ {
+ extern Connection *connection;
+ }
+}
+
+#endif
diff --git a/src/net/tmwserv/beinghandler.cpp b/src/net/tmwserv/beinghandler.cpp
new file mode 100644
index 00000000..1a1744cc
--- /dev/null
+++ b/src/net/tmwserv/beinghandler.cpp
@@ -0,0 +1,357 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/beinghandler.h"
+
+#include "net/tmwserv/protocol.h"
+
+#include "net/messagein.h"
+
+#include "being.h"
+#include "beingmanager.h"
+#include "game.h"
+#include "localplayer.h"
+#include "log.h"
+#include "main.h"
+#include "npc.h"
+#include "particle.h"
+#include "sound.h"
+
+#include "gui/ok_dialog.h"
+
+#include "utils/gettext.h"
+
+#include "net/tmwserv/gameserver/player.h"
+
+const int EMOTION_TIME = 150; /**< Duration of emotion icon */
+
+BeingHandler::BeingHandler()
+{
+ static const Uint16 _messages[] = {
+ GPMSG_BEING_ATTACK,
+ GPMSG_BEING_ENTER,
+ GPMSG_BEING_LEAVE,
+ GPMSG_BEINGS_MOVE,
+ GPMSG_BEINGS_DAMAGE,
+ GPMSG_BEING_ACTION_CHANGE,
+ GPMSG_BEING_LOOKS_CHANGE,
+ GPMSG_BEING_DIR_CHANGE,
+ 0
+ };
+ handledMessages = _messages;
+}
+
+void BeingHandler::handleMessage(MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case GPMSG_BEING_ENTER:
+ handleBeingEnterMessage(msg);
+ break;
+ case GPMSG_BEING_LEAVE:
+ handleBeingLeaveMessage(msg);
+ break;
+ case GPMSG_BEINGS_MOVE:
+ handleBeingsMoveMessage(msg);
+ break;
+ case GPMSG_BEING_ATTACK:
+ handleBeingAttackMessage(msg);
+ break;
+ case GPMSG_BEINGS_DAMAGE:
+ handleBeingsDamageMessage(msg);
+ break;
+ case GPMSG_BEING_ACTION_CHANGE:
+ handleBeingActionChangeMessage(msg);
+ break;
+ case GPMSG_BEING_LOOKS_CHANGE:
+ handleBeingLooksChangeMessage(msg);
+ break;
+ case GPMSG_BEING_DIR_CHANGE:
+ handleBeingDirChangeMessage(msg);
+ break;
+ }
+}
+
+static void handleLooks(Player *being, MessageIn &msg)
+{
+ // Order of sent slots. Has to be in sync with the server code.
+ static int const nb_slots = 4;
+ static int const slots[nb_slots] =
+ { Being::WEAPON_SPRITE, Being::HAT_SPRITE, Being::TOPCLOTHES_SPRITE,
+ Being::BOTTOMCLOTHES_SPRITE };
+
+ int mask = msg.readInt8();
+
+ if (mask & (1 << 7))
+ {
+ // The equipment has to be cleared first.
+ for (int i = 0; i < nb_slots; ++i)
+ {
+ being->setSprite(slots[i], 0);
+ }
+ }
+
+ // Fill slots enumerated by the bitmask.
+ for (int i = 0; i < nb_slots; ++i)
+ {
+ if (!(mask & (1 << i))) continue;
+ int id = msg.readInt16();
+ being->setSprite(slots[i], id);
+ }
+}
+
+void BeingHandler::handleBeingEnterMessage(MessageIn &msg)
+{
+ int type = msg.readInt8();
+ int id = msg.readInt16();
+ Being::Action action = (Being::Action)msg.readInt8();
+ int px = msg.readInt16();
+ int py = msg.readInt16();
+ Being *being;
+
+ switch (type)
+ {
+ case OBJECT_PLAYER:
+ {
+ std::string name = msg.readString();
+ if (player_node->getName() == name)
+ {
+ being = player_node;
+ being->setId(id);
+ }
+ else
+ {
+ being = beingManager->createBeing(id, type, 0);
+ being->setName(name);
+ }
+ Player *p = static_cast< Player * >(being);
+ int hs = msg.readInt8(), hc = msg.readInt8();
+ p->setHairStyle(hs, hc);
+ p->setGender(msg.readInt8() == GENDER_MALE ?
+ GENDER_MALE : GENDER_FEMALE);
+ handleLooks(p, msg);
+ } break;
+
+ case OBJECT_MONSTER:
+ case OBJECT_NPC:
+ {
+ int subtype = msg.readInt16();
+ being = beingManager->createBeing(id, type, subtype);
+ std::string name = msg.readString();
+ if (name.length() > 0) being->setName(name);
+ } break;
+
+ default:
+ return;
+ }
+
+ being->setPosition(px, py);
+ being->setDestination(px, py);
+ being->setAction(action);
+}
+
+void BeingHandler::handleBeingLeaveMessage(MessageIn &msg)
+{
+ Being *being = beingManager->findBeing(msg.readInt16());
+ if (!being) return;
+
+ beingManager->destroyBeing(being);
+}
+
+void BeingHandler::handleBeingsMoveMessage(MessageIn &msg)
+{
+ while (msg.getUnreadLength())
+ {
+ int id = msg.readInt16();
+ int flags = msg.readInt8();
+ Being *being = beingManager->findBeing(id);
+ int sx = 0;
+ int sy = 0;
+ int dx = 0;
+ int dy = 0;
+ int speed = 0;
+
+ printf("handleBeingsMoveMessage for %p (%s | %s)\n",
+ (void*) being,
+ (flags & MOVING_POSITION) ? "pos" : "",
+ (flags & MOVING_DESTINATION) ? "dest" : "");
+
+ if (flags & MOVING_POSITION)
+ {
+ Uint16 sx2, sy2;
+ msg.readCoordinates(sx2, sy2);
+ sx = sx2 * 32 + 16;
+ sy = sy2 * 32 + 16;
+ speed = msg.readInt8();
+ }
+ if (flags & MOVING_DESTINATION)
+ {
+ dx = msg.readInt16();
+ dy = msg.readInt16();
+ if (!(flags & MOVING_POSITION))
+ {
+ sx = dx;
+ sy = dy;
+ }
+ }
+ if (!being || !(flags & (MOVING_POSITION | MOVING_DESTINATION)))
+ {
+ continue;
+ }
+ if (speed)
+ {
+ /* The speed on the server is the cost of moving from one tile to
+ * the next. Beings get 1000 cost units per second. The speed is
+ * transferred as devided by 10, so that slower speeds fit in a
+ * byte. Here we convert the speed to pixels per second.
+ */
+ const float tilesPerSecond = 100.0f / speed;
+ being->setWalkSpeed((int) (tilesPerSecond * 32));
+ }
+
+ // Ignore messages from the server for the local player
+ if (being == player_node)
+ continue;
+
+ // If being is a player, and he only moves a little, its ok to be a little out of sync
+ if (being->getType() == Being::PLAYER && abs(being->getPixelX() - dx) +
+ abs(being->getPixelY() - dy) < 2 * 32 &&
+ (dx != being->getDestination().x && dy != being->getDestination().y))
+ {
+ being->setDestination(being->getPixelX(),being->getPixelY());
+ continue;
+ }
+ if (abs(being->getPixelX() - sx) +
+ abs(being->getPixelY() - sy) > 10 * 32)
+ {
+ // Too large a desynchronization.
+ being->setPosition(sx, sy);
+ being->setDestination(dx, dy);
+ }
+ else if (!(flags & MOVING_POSITION))
+ {
+ being->setDestination(dx, dy);
+ }
+ else if (!(flags & MOVING_DESTINATION))
+ {
+ being->adjustCourse(sx, sy);
+ }
+ else
+ {
+ being->adjustCourse(sx, sy, dx, dy);
+ }
+ }
+}
+
+void BeingHandler::handleBeingAttackMessage(MessageIn &msg)
+{
+ Being *being = beingManager->findBeing(msg.readInt16());
+ int direction = msg.readInt8();
+ int attackType = msg.readInt8();
+
+ if (!being) return;
+
+ switch (direction)
+ {
+ case DIRECTION_UP: being->setDirection(Being::UP); break;
+ case DIRECTION_DOWN: being->setDirection(Being::DOWN); break;
+ case DIRECTION_LEFT: being->setDirection(Being::LEFT); break;
+ case DIRECTION_RIGHT: being->setDirection(Being::RIGHT); break;
+ }
+
+ being->setAction(Being::ATTACK, attackType);
+}
+
+void BeingHandler::handleBeingsDamageMessage(MessageIn &msg)
+{
+ while (msg.getUnreadLength())
+ {
+ Being *being = beingManager->findBeing(msg.readInt16());
+ int damage = msg.readInt16();
+ if (being)
+ {
+ being->takeDamage(0, damage, Being::HIT);
+ }
+ }
+}
+
+void BeingHandler::handleBeingActionChangeMessage(MessageIn &msg)
+{
+ Being* being = beingManager->findBeing(msg.readInt16());
+ Being::Action action = (Being::Action) msg.readInt8();
+ if (!being) return;
+
+ being->setAction(action);
+
+ if (action == Being::DEAD && being==player_node)
+ {
+ static char const *const deadMsg[] =
+ {
+ _("You are dead."),
+ _("We regret to inform you that your character was killed in battle."),
+ _("You are not that alive anymore."),
+ _("The cold hands of the grim reaper are grabbing for your soul."),
+ _("Game Over!"),
+ _("No, kids. Your character did not really die. It... err... went to a better place."),
+ _("Your plan of breaking your enemies weapon by bashing it with your throat failed."),
+ _("I guess this did not run too well."),
+ _("Do you want your possessions identified?"), // Nethack reference
+ _("Sadly, no trace of you was ever found..."), // Secret of Mana reference
+ _("Annihilated."), // Final Fantasy VI reference
+ _("Looks like you got your head handed to you."), //Earthbound reference
+ _("You screwed up again, dump your body down the tubes and get you another one.") // Leisure Suit Larry 1 Reference
+
+ };
+ std::string message(deadMsg[rand()%13]);
+ message.append(_(" Press OK to respawn"));
+ OkDialog *dlg = new OkDialog(_("You died"), message);
+ dlg->addActionListener(&(Net::GameServer::Player::respawnListener));
+ }
+}
+
+void BeingHandler::handleBeingLooksChangeMessage(MessageIn &msg)
+{
+ Being *being = beingManager->findBeing(msg.readInt16());
+ if (!being || being->getType() != Being::PLAYER) return;
+ Player * player = static_cast< Player * >(being);
+ handleLooks(player, msg);
+ if (msg.getUnreadLength())
+ {
+ int style = msg.readInt16();
+ int color = msg.readInt16();
+ player->setHairStyle(style, color);
+ player->setGender((Gender)msg.readInt16());
+ }
+}
+
+void BeingHandler::handleBeingDirChangeMessage(MessageIn &msg)
+{
+ Being *being = beingManager->findBeing(msg.readInt16());
+ if (!being) return;
+ int data = msg.readInt8();
+ switch (data)
+ {
+ case DIRECTION_UP: being->setDirection(Being::UP); break;
+ case DIRECTION_DOWN: being->setDirection(Being::DOWN); break;
+ case DIRECTION_LEFT: being->setDirection(Being::LEFT); break;
+ case DIRECTION_RIGHT: being->setDirection(Being::RIGHT); break;
+ }
+}
diff --git a/src/net/tmwserv/beinghandler.h b/src/net/tmwserv/beinghandler.h
new file mode 100644
index 00000000..0ca186f0
--- /dev/null
+++ b/src/net/tmwserv/beinghandler.h
@@ -0,0 +1,45 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_TMWSERV_BEINGHANDLER_H
+#define NET_TMWSERV_BEINGHANDLER_H
+
+#include "net/messagehandler.h"
+
+class BeingHandler : public MessageHandler
+{
+ public:
+ BeingHandler();
+
+ void handleMessage(MessageIn &msg);
+
+ private:
+ void handleBeingAttackMessage(MessageIn &msg);
+ void handleBeingEnterMessage(MessageIn &msg);
+ void handleBeingLeaveMessage(MessageIn &msg);
+ void handleBeingsMoveMessage(MessageIn &msg);
+ void handleBeingsDamageMessage(MessageIn &msg);
+ void handleBeingActionChangeMessage(MessageIn &msg);
+ void handleBeingLooksChangeMessage(MessageIn &msg);
+ void handleBeingDirChangeMessage(MessageIn &msg);
+};
+
+#endif
diff --git a/src/net/tmwserv/buysellhandler.cpp b/src/net/tmwserv/buysellhandler.cpp
new file mode 100644
index 00000000..bab475d2
--- /dev/null
+++ b/src/net/tmwserv/buysellhandler.cpp
@@ -0,0 +1,91 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/buysellhandler.h"
+
+#include "net/tmwserv/protocol.h"
+
+#include "net/messagein.h"
+
+#include "beingmanager.h"
+#include "item.h"
+#include "localplayer.h"
+#include "npc.h"
+
+#include "gui/buy.h"
+#include "gui/chat.h"
+#include "gui/sell.h"
+
+extern BuyDialog *buyDialog;
+extern SellDialog *sellDialog;
+extern Window *buySellDialog;
+
+BuySellHandler::BuySellHandler()
+{
+ static const Uint16 _messages[] = {
+ GPMSG_NPC_BUY,
+ GPMSG_NPC_SELL,
+ 0
+ };
+ handledMessages = _messages;
+}
+
+void BuySellHandler::handleMessage(MessageIn &msg)
+{
+ Being *being = beingManager->findBeing(msg.readInt16());
+ if (!being || being->getType() != Being::NPC)
+ {
+ return;
+ }
+
+ current_npc = being->getId();
+
+ switch (msg.getId())
+ {
+ case GPMSG_NPC_BUY:
+ buyDialog->reset();
+ buyDialog->setMoney(player_node->getMoney());
+ buyDialog->setVisible(true);
+
+ while (msg.getUnreadLength())
+ {
+ int itemId = msg.readInt16();
+ int amount = msg.readInt16();
+ int value = msg.readInt16();
+ buyDialog->addItem(itemId, amount, value);
+ }
+ break;
+
+ case GPMSG_NPC_SELL:
+ sellDialog->setMoney(player_node->getMoney());
+ sellDialog->reset();
+ sellDialog->setVisible(true);
+
+ while (msg.getUnreadLength())
+ {
+ int itemId = msg.readInt16();
+ int amount = msg.readInt16();
+ int value = msg.readInt16();
+ sellDialog->addItem(itemId, amount, value);
+ }
+ break;
+ }
+}
diff --git a/src/net/buysellhandler.h b/src/net/tmwserv/buysellhandler.h
index 2b4aaf4f..32f273f1 100644
--- a/src/net/buysellhandler.h
+++ b/src/net/tmwserv/buysellhandler.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,17 +19,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef NET_BUYSELLHANDLER_H
-#define NET_BUYSELLHANDLER_H
+#ifndef NET_TMWSERV_BUYSELLHANDLER_H
+#define NET_TMWSERV_BUYSELLHANDLER_H
-#include "messagehandler.h"
+#include "net/messagehandler.h"
class BuySellHandler : public MessageHandler
{
public:
BuySellHandler();
- void handleMessage(MessageIn *msg);
+ void handleMessage(MessageIn &msg);
};
#endif
diff --git a/src/net/tmwserv/charserverhandler.cpp b/src/net/tmwserv/charserverhandler.cpp
new file mode 100644
index 00000000..0779e499
--- /dev/null
+++ b/src/net/tmwserv/charserverhandler.cpp
@@ -0,0 +1,228 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/charserverhandler.h"
+
+#include "net/tmwserv/connection.h"
+#include "net/tmwserv/protocol.h"
+
+#include "net/messagein.h"
+
+#include "game.h"
+#include "localplayer.h"
+#include "log.h"
+#include "logindata.h"
+#include "main.h"
+
+#include "gui/ok_dialog.h"
+#include "gui/char_select.h"
+
+extern Net::Connection *gameServerConnection;
+extern Net::Connection *chatServerConnection;
+
+CharServerHandler::CharServerHandler():
+ mCharCreateDialog(0)
+{
+ static const Uint16 _messages[] = {
+ APMSG_CHAR_CREATE_RESPONSE,
+ APMSG_CHAR_DELETE_RESPONSE,
+ APMSG_CHAR_INFO,
+ APMSG_CHAR_SELECT_RESPONSE,
+ 0
+ };
+ handledMessages = _messages;
+}
+
+void CharServerHandler::handleMessage(MessageIn &msg)
+{
+ int slot;
+ LocalPlayer *tempPlayer;
+
+ switch (msg.getId())
+ {
+ case APMSG_CHAR_CREATE_RESPONSE:
+ handleCharCreateResponse(msg);
+ break;
+
+ case APMSG_CHAR_DELETE_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Character deletion successful
+ if (errMsg == ERRMSG_OK)
+ {
+ delete mCharInfo->getEntry();
+ mCharInfo->setEntry(0);
+ mCharInfo->unlock();
+ new OkDialog("Info", "Player deleted");
+ }
+ // Character deletion failed
+ else
+ {
+ std::string message = "";
+ switch (errMsg)
+ {
+ case ERRMSG_NO_LOGIN:
+ message = "Not logged in";
+ break;
+ case ERRMSG_INVALID_ARGUMENT:
+ message = "Selection out of range";
+ break;
+ default:
+ message = "Unknown error";
+ }
+ mCharInfo->unlock();
+ new OkDialog("Error", message);
+ }
+ }
+ break;
+
+ case APMSG_CHAR_INFO:
+ tempPlayer = readPlayerData(msg, slot);
+ 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:
+ handleCharSelectResponse(msg);
+ break;
+ }
+}
+
+void CharServerHandler::handleCharCreateResponse(MessageIn &msg)
+{
+ int errMsg = msg.readInt8();
+
+ // Character creation failed
+ if (errMsg != ERRMSG_OK)
+ {
+ std::string message = "";
+ switch (errMsg)
+ {
+ case ERRMSG_NO_LOGIN:
+ message = "Not logged in";
+ break;
+ case CREATE_TOO_MUCH_CHARACTERS:
+ message = "No empty slot";
+ break;
+ case ERRMSG_INVALID_ARGUMENT:
+ message = "Invalid name";
+ break;
+ case CREATE_EXISTS_NAME:
+ message = "Character's name already exists";
+ break;
+ case CREATE_INVALID_HAIRSTYLE:
+ message = "Invalid hairstyle";
+ break;
+ case CREATE_INVALID_HAIRCOLOR:
+ message = "Invalid hair color";
+ break;
+ case CREATE_INVALID_GENDER:
+ message = "Invalid gender";
+ break;
+ case CREATE_RAW_STATS_TOO_HIGH:
+ message = "Character's stats are too high";
+ break;
+ case CREATE_RAW_STATS_TOO_LOW:
+ message = "Character's stats are too low";
+ break;
+ case CREATE_RAW_STATS_EQUAL_TO_ZERO:
+ message = "One stat is zero";
+ break;
+ default:
+ message = "Unknown error";
+ break;
+ }
+ new OkDialog("Error", message);
+ }
+
+ if (mCharCreateDialog)
+ mCharCreateDialog->unlock();
+}
+
+void CharServerHandler::handleCharSelectResponse(MessageIn &msg)
+{
+ int errMsg = msg.readInt8();
+
+ if (errMsg == ERRMSG_OK)
+ {
+ token = msg.readString(32);
+ std::string gameServer = msg.readString();
+ unsigned short gameServerPort = msg.readInt16();
+ std::string chatServer = msg.readString();
+ unsigned short chatServerPort = msg.readInt16();
+
+ logger->log("Game server: %s:%d", gameServer.c_str(), gameServerPort);
+ logger->log("Chat server: %s:%d", chatServer.c_str(), chatServerPort);
+
+ gameServerConnection->connect(gameServer, gameServerPort);
+ chatServerConnection->connect(chatServer, chatServerPort);
+
+ // 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
+
+ state = STATE_CONNECT_GAME;
+ }
+}
+
+LocalPlayer* CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
+{
+ LocalPlayer *tempPlayer = new LocalPlayer;
+ slot = msg.readInt8(); // character slot
+ tempPlayer->setName(msg.readString());
+ tempPlayer->setGender(msg.readInt8() == GENDER_MALE ? GENDER_MALE : GENDER_FEMALE);
+ int hs = msg.readInt8(), hc = msg.readInt8();
+ tempPlayer->setHairStyle(hs, hc);
+ tempPlayer->setLevel(msg.readInt16());
+ tempPlayer->setCharacterPoints(msg.readInt16());
+ tempPlayer->setCorrectionPoints(msg.readInt16());
+ tempPlayer->setMoney(msg.readInt32());
+
+ for (int i = 0; i < 7; i++)
+ {
+ tempPlayer->setAttributeBase(i, msg.readInt8());
+ }
+
+ return tempPlayer;
+}
diff --git a/src/net/tmwserv/charserverhandler.h b/src/net/tmwserv/charserverhandler.h
new file mode 100644
index 00000000..e1e13b55
--- /dev/null
+++ b/src/net/tmwserv/charserverhandler.h
@@ -0,0 +1,68 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_TMWSERV_CHARSERVERHANDLER_H
+#define NET_TMWSERV_CHARSERVERHANDLER_H
+
+#include "net/messagehandler.h"
+
+#include "lockedarray.h"
+
+class CharCreateDialog;
+class LocalPlayer;
+class LoginData;
+
+/**
+ * Deals with incoming messages related to character selection.
+ */
+class CharServerHandler : public MessageHandler
+{
+ public:
+ CharServerHandler();
+
+ void handleMessage(MessageIn &msg);
+
+ void setCharInfo(LockedArray<LocalPlayer*> *charInfo)
+ {
+ 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);
+
+ void handleCharSelectResponse(MessageIn &msg);
+
+ LockedArray<LocalPlayer*> *mCharInfo;
+ CharCreateDialog *mCharCreateDialog;
+
+ LocalPlayer*
+ readPlayerData(MessageIn &msg, int &slot);
+};
+
+#endif
diff --git a/src/net/tmwserv/chathandler.cpp b/src/net/tmwserv/chathandler.cpp
new file mode 100644
index 00000000..1c537e30
--- /dev/null
+++ b/src/net/tmwserv/chathandler.cpp
@@ -0,0 +1,285 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/chathandler.h"
+
+#include "net/tmwserv/protocol.h"
+
+#include "net/messagein.h"
+
+#include "being.h"
+#include "beingmanager.h"
+#include "game.h"
+#include "channel.h"
+#include "channelmanager.h"
+
+#include "gui/widgets/channeltab.h"
+#include "gui/chat.h"
+#include "gui/guildwindow.h"
+
+#include <string>
+#include <iostream>
+
+#include "utils/gettext.h"
+
+extern Being *player_node;
+
+ChatHandler::ChatHandler()
+{
+ static const Uint16 _messages[] = {
+ GPMSG_SAY,
+ CPMSG_ENTER_CHANNEL_RESPONSE,
+ CPMSG_LIST_CHANNELS_RESPONSE,
+ CPMSG_PUBMSG,
+ CPMSG_ANNOUNCEMENT,
+ CPMSG_PRIVMSG,
+ CPMSG_QUIT_CHANNEL_RESPONSE,
+ CPMSG_LIST_CHANNELUSERS_RESPONSE,
+ CPMSG_CHANNEL_EVENT,
+ 0
+ };
+ handledMessages = _messages;
+}
+
+void ChatHandler::handleMessage(MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case GPMSG_SAY:
+ handleGameChatMessage(msg);
+ break;
+
+ case CPMSG_ENTER_CHANNEL_RESPONSE:
+ handleEnterChannelResponse(msg);
+ break;
+
+ case CPMSG_LIST_CHANNELS_RESPONSE:
+ handleListChannelsResponse(msg);
+ break;
+
+ case CPMSG_PRIVMSG:
+ handlePrivateMessage(msg);
+ break;
+
+ case CPMSG_ANNOUNCEMENT:
+ handleAnnouncement(msg);
+ break;
+
+ case CPMSG_PUBMSG:
+ handleChatMessage(msg);
+ break;
+
+ case CPMSG_QUIT_CHANNEL_RESPONSE:
+ handleQuitChannelResponse(msg);
+ break;
+
+ case CPMSG_LIST_CHANNELUSERS_RESPONSE:
+ handleListChannelUsersResponse(msg);
+ break;
+
+ case CPMSG_CHANNEL_EVENT:
+ handleChannelEvent(msg);
+ }
+}
+
+void ChatHandler::handleGameChatMessage(MessageIn &msg)
+{
+ short id = msg.readInt16();
+ std::string chatMsg = msg.readString();
+
+ if (id == 0)
+ {
+ localChatTab->chatLog(chatMsg, BY_SERVER);
+ return;
+ }
+
+ Being *being = beingManager->findBeing(id);
+
+ std::string mes;
+ if (being)
+ {
+ mes = being->getName() + " : " + chatMsg;
+ being->setSpeech(chatMsg, SPEECH_TIME);
+ }
+ else
+ mes = "Unknown : " + chatMsg;
+
+ localChatTab->chatLog(mes, being == player_node ? BY_PLAYER : BY_OTHER);
+}
+
+void ChatHandler::handleEnterChannelResponse(MessageIn &msg)
+{
+ if(msg.readInt8() == ERRMSG_OK)
+ {
+ short channelId = msg.readInt16();
+ std::string channelName = msg.readString();
+ std::string announcement = msg.readString();
+ Channel *channel = new Channel(channelId, channelName, announcement);
+ channelManager->addChannel(channel);
+ ChatTab *tab = channel->getTab();
+ tab->chatLog(_("Topic: ") + announcement, BY_CHANNEL);
+
+ std::string user;
+ std::string userModes;
+ tab->chatLog("Players in this channel:", BY_CHANNEL);
+ while(msg.getUnreadLength())
+ {
+ user = msg.readString();
+ if (user == "")
+ return;
+ userModes = msg.readString();
+ if (userModes.find('o') != std::string::npos)
+ {
+ user = "@" + user;
+ }
+ tab->chatLog(user, BY_CHANNEL);
+ }
+
+ }
+ else
+ {
+ localChatTab->chatLog("Error joining channel", BY_SERVER);
+ }
+}
+
+void ChatHandler::handleListChannelsResponse(MessageIn &msg)
+{
+ localChatTab->chatLog("Listing Channels", BY_SERVER);
+ while(msg.getUnreadLength())
+ {
+ std::string channelName = msg.readString();
+ if (channelName == "")
+ return;
+ std::ostringstream numUsers;
+ numUsers << msg.readInt16();
+ channelName += " - ";
+ channelName += numUsers.str();
+ localChatTab->chatLog(channelName, BY_SERVER);
+ }
+ localChatTab->chatLog("End of channel list", BY_SERVER);
+}
+
+void ChatHandler::handlePrivateMessage(MessageIn &msg)
+{
+ std::string userNick = msg.readString();
+ std::string chatMsg = msg.readString();
+
+ chatWindow->whisper(userNick, chatMsg);
+}
+
+void ChatHandler::handleAnnouncement(MessageIn &msg)
+{
+ std::string chatMsg = msg.readString();
+ localChatTab->chatLog(chatMsg, BY_GM);
+}
+
+void ChatHandler::handleChatMessage(MessageIn &msg)
+{
+ short channelId = msg.readInt16();
+ std::string userNick = msg.readString();
+ std::string chatMsg = msg.readString();
+
+ Channel *channel = channelManager->findById(channelId);
+ channel->getTab()->chatLog(userNick, chatMsg);
+}
+
+void ChatHandler::handleQuitChannelResponse(MessageIn &msg)
+{
+ if(msg.readInt8() == ERRMSG_OK)
+ {
+ short channelId = msg.readInt16();
+ Channel *channel = channelManager->findById(channelId);
+ channelManager->removeChannel(channel);
+ }
+}
+
+void ChatHandler::handleListChannelUsersResponse(MessageIn &msg)
+{
+ std::string channelName = msg.readString();
+ std::string userNick;
+ std::string userModes;
+ Channel *channel = channelManager->findByName(channelName);
+ channel->getTab()->chatLog("Players in this channel:", BY_CHANNEL);
+ while(msg.getUnreadLength())
+ {
+ userNick = msg.readString();
+ if (userNick == "")
+ {
+ break;
+ }
+ userModes = msg.readString();
+ if (userModes.find('o') != std::string::npos)
+ {
+ userNick = "@" + userNick;
+ }
+ localChatTab->chatLog(userNick, BY_CHANNEL, channel);
+ }
+}
+
+void ChatHandler::handleChannelEvent(MessageIn &msg)
+{
+ short channelId = msg.readInt16();
+ char eventId = msg.readInt8();
+ std::string line = msg.readString();
+ Channel *channel = channelManager->findById(channelId);
+
+ if(channel)
+ {
+ switch(eventId)
+ {
+ case CHAT_EVENT_NEW_PLAYER:
+ line += " entered the channel.";
+ break;
+
+ case CHAT_EVENT_LEAVING_PLAYER:
+ line += " left the channel.";
+ break;
+
+ case CHAT_EVENT_TOPIC_CHANGE:
+ line = "Topic: " + line;
+ break;
+
+ case CHAT_EVENT_MODE_CHANGE:
+ {
+ int first = line.find(":");
+ int second = line.find(":", first+1);
+ std::string user1 = line.substr(0, first);
+ std::string user2 = line.substr(first+1, second);
+ std::string mode = line.substr(second+1, line.length());
+ line = user1 + " has set mode " + mode + " on user " + user2;
+ } break;
+
+ case CHAT_EVENT_KICKED_PLAYER:
+ {
+ int first = line.find(":");
+ std::string user1 = line.substr(0, first);
+ std::string user2 = line.substr(first+1, line.length());
+ line = user1 + " has kicked " + user2;
+ } break;
+
+ default:
+ line = "Unknown channel event.";
+ }
+
+ channel->getTab()->chatLog(line, BY_CHANNEL);
+ }
+}
+
diff --git a/src/net/tmwserv/chathandler.h b/src/net/tmwserv/chathandler.h
new file mode 100644
index 00000000..f0604da8
--- /dev/null
+++ b/src/net/tmwserv/chathandler.h
@@ -0,0 +1,84 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_TMWSERV_CHATHANDLER_H
+#define NET_TMWSERV_CHATHANDLER_H
+
+#include "net/messagehandler.h"
+
+class ChatHandler : public MessageHandler
+{
+ public:
+ ChatHandler();
+
+ /**
+ * Handle the given message appropriately.
+ */
+ void handleMessage(MessageIn &msg);
+
+ private:
+ /**
+ * Handle chat messages sent from the game server.
+ */
+ void handleGameChatMessage(MessageIn &msg);
+
+ /**
+ * Handle channel entry responses.
+ */
+ void handleEnterChannelResponse(MessageIn &msg);
+
+ /**
+ * Handle list channels responses.
+ */
+ void handleListChannelsResponse(MessageIn &msg);
+
+ /**
+ * Handle private messages.
+ */
+ void handlePrivateMessage(MessageIn &msg);
+
+ /**
+ * Handle announcements.
+ */
+ void handleAnnouncement(MessageIn &msg);
+
+ /**
+ * Handle chat messages.
+ */
+ void handleChatMessage(MessageIn &msg);
+
+ /**
+ * Handle quit channel responses.
+ */
+ void handleQuitChannelResponse(MessageIn &msg);
+
+ /**
+ * Handle list channel users responses.
+ */
+ void handleListChannelUsersResponse(MessageIn &msg);
+
+ /**
+ * Handle channel events.
+ */
+ void handleChannelEvent(MessageIn &msg);
+};
+
+#endif
diff --git a/src/net/tmwserv/chatserver/chatserver.cpp b/src/net/tmwserv/chatserver/chatserver.cpp
new file mode 100644
index 00000000..49a17367
--- /dev/null
+++ b/src/net/tmwserv/chatserver/chatserver.cpp
@@ -0,0 +1,147 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "chatserver.h"
+
+#include "internal.h"
+
+#include "net/tmwserv/connection.h"
+#include "net/tmwserv/protocol.h"
+
+#include "net/messageout.h"
+
+using Net::ChatServer::connection;
+
+void Net::ChatServer::connect(Net::Connection *connection,
+ const std::string &token)
+{
+ Net::ChatServer::connection = connection;
+
+ MessageOut msg(PCMSG_CONNECT);
+
+ msg.writeString(token, 32);
+
+ connection->send(msg);
+}
+
+void Net::ChatServer::logout()
+{
+ MessageOut msg(PCMSG_DISCONNECT);
+
+ connection->send(msg);
+}
+
+void Net::ChatServer::chat(short channel, const std::string &text)
+{
+ MessageOut msg(PCMSG_CHAT);
+
+ msg.writeString(text);
+ msg.writeInt16(channel);
+
+ connection->send(msg);
+}
+
+void Net::ChatServer::announce(const std::string &text)
+{
+ MessageOut msg(PCMSG_ANNOUNCE);
+
+ msg.writeString(text);
+
+ connection->send(msg);
+}
+
+void Net::ChatServer::privMsg(const std::string &recipient,
+ const std::string &text)
+{
+ MessageOut msg(PCMSG_PRIVMSG);
+
+ msg.writeString(recipient);
+ msg.writeString(text);
+
+ connection->send(msg);
+}
+
+void Net::ChatServer::enterChannel(const std::string &channel, const std::string &password)
+{
+ MessageOut msg(PCMSG_ENTER_CHANNEL);
+
+ msg.writeString(channel);
+ msg.writeString(password);
+
+ connection->send(msg);
+}
+
+void Net::ChatServer::quitChannel(short channel)
+{
+ MessageOut msg(PCMSG_QUIT_CHANNEL);
+
+ msg.writeInt16(channel);
+
+ connection->send(msg);
+}
+
+void Net::ChatServer::getChannelList()
+{
+ MessageOut msg(PCMSG_LIST_CHANNELS);
+
+ connection->send(msg);
+}
+
+void Net::ChatServer::getUserList(const std::string &channel)
+{
+ MessageOut msg(PCMSG_LIST_CHANNELUSERS);
+
+ msg.writeString(channel);
+
+ connection->send(msg);
+}
+
+void Net::ChatServer::setChannelTopic(short channel, const std::string &topic)
+{
+ MessageOut msg(PCMSG_TOPIC_CHANGE);
+
+ msg.writeInt16(channel);
+ msg.writeString(topic);
+
+ connection->send(msg);
+}
+
+void Net::ChatServer::setUserMode(short channel, const std::string &user,
+ unsigned char mode)
+{
+ MessageOut msg(PCMSG_USER_MODE);
+
+ msg.writeInt16(channel);
+ msg.writeString(user);
+ msg.writeInt8(mode);
+
+ connection->send(msg);
+}
+
+void Net::ChatServer::kickUser(short channel, const std::string &user)
+{
+ MessageOut msg(PCMSG_KICK_USER);
+
+ msg.writeInt16(channel);
+ msg.writeString(user);
+
+ connection->send(msg);
+}
diff --git a/src/net/tmwserv/chatserver/chatserver.h b/src/net/tmwserv/chatserver/chatserver.h
new file mode 100644
index 00000000..8a6025a7
--- /dev/null
+++ b/src/net/tmwserv/chatserver/chatserver.h
@@ -0,0 +1,60 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_CHATSERVER_CHATSERVER_H
+#define NET_CHATSERVER_CHATSERVER_H
+
+#include <iosfwd>
+
+namespace Net
+{
+ class Connection;
+
+ namespace ChatServer
+ {
+ void connect(Net::Connection *connection, const std::string &token);
+
+ void logout();
+
+ void chat(short channel, const std::string &text);
+
+ void announce(const std::string &text);
+
+ void privMsg(const std::string &recipient, const std::string &text);
+
+ void enterChannel(const std::string &channel, const std::string &password);
+
+ void quitChannel(short channel);
+
+ void getChannelList();
+
+ void getUserList(const std::string &channel);
+
+ void setChannelTopic(short channel, const std::string &topic);
+
+ void setUserMode(short channel, const std::string &user, unsigned char mode);
+
+ void kickUser(short channel, const std::string &user);
+
+ }
+}
+
+#endif
diff --git a/src/net/tmwserv/chatserver/guild.cpp b/src/net/tmwserv/chatserver/guild.cpp
new file mode 100644
index 00000000..740e9efa
--- /dev/null
+++ b/src/net/tmwserv/chatserver/guild.cpp
@@ -0,0 +1,95 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "guild.h"
+
+#include "internal.h"
+
+#include "net/tmwserv/connection.h"
+#include "net/tmwserv/protocol.h"
+
+#include "net/messageout.h"
+
+#include "log.h"
+
+void Net::ChatServer::Guild::createGuild(const std::string &name)
+{
+ logger->log("Sending PCMSG_GUILD_CREATE");
+ MessageOut msg(PCMSG_GUILD_CREATE);
+
+ msg.writeString(name);
+
+ Net::ChatServer::connection->send(msg);
+}
+
+void Net::ChatServer::Guild::invitePlayer(const std::string &name, short guildId)
+{
+ logger->log("Sending PCMSG_GUILD_INVITE");
+ MessageOut msg(PCMSG_GUILD_INVITE);
+
+ msg.writeInt16(guildId);
+ msg.writeString(name);
+
+ Net::ChatServer::connection->send(msg);
+}
+
+void Net::ChatServer::Guild::acceptInvite(const std::string &name)
+{
+ logger->log("Sending PCMSG_GUILD_ACCEPT");
+ MessageOut msg(PCMSG_GUILD_ACCEPT);
+
+ msg.writeString(name);
+
+ Net::ChatServer::connection->send(msg);
+}
+
+void Net::ChatServer::Guild::getGuildMembers(short guildId)
+{
+ logger->log("Sending PCMSG_GUILD_GET_MEMBERS");
+ MessageOut msg(PCMSG_GUILD_GET_MEMBERS);
+
+ msg.writeInt16(guildId);
+
+ Net::ChatServer::connection->send(msg);
+}
+
+void Net::ChatServer::Guild::promoteMember(const std::string &name,
+ short guildId, short level)
+{
+ logger->log("Sending PCMSG_GUILD_PROMOTE_MEMBER");
+ MessageOut msg(PCMSG_GUILD_PROMOTE_MEMBER);
+
+ msg.writeInt16(guildId);
+ msg.writeString(name);
+ msg.writeInt8(level);
+
+ Net::ChatServer::connection->send(msg);
+}
+
+void Net::ChatServer::Guild::quitGuild(short guildId)
+{
+ logger->log("Sending PCMSG_GUILD_QUIT");
+ MessageOut msg(PCMSG_GUILD_QUIT);
+
+ msg.writeInt16(guildId);
+
+ Net::ChatServer::connection->send(msg);
+}
diff --git a/src/net/tmwserv/chatserver/guild.h b/src/net/tmwserv/chatserver/guild.h
new file mode 100644
index 00000000..2e9cf9a6
--- /dev/null
+++ b/src/net/tmwserv/chatserver/guild.h
@@ -0,0 +1,67 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_CHATSERVER_GUILD_H
+#define NET_CHATSERVER_GUILD_H
+
+#include <iosfwd>
+
+namespace Net
+{
+ namespace ChatServer
+ {
+ namespace Guild
+ {
+ /**
+ * Create guild.
+ */
+ void createGuild(const std::string &name);
+
+ /**
+ * Invite a player to your guild.
+ */
+ void invitePlayer(const std::string &name, short guildId);
+
+ /**
+ * Accept an invite another player has sent to join their guild.
+ */
+ void acceptInvite(const std::string &name);
+
+ /**
+ * Get a list of members in a guild.
+ */
+ void getGuildMembers(short guildId);
+
+ /**
+ * Promote guild member
+ */
+ void promoteMember(const std::string &name, short guildId,
+ short level);
+
+ /**
+ * Quit guild.
+ */
+ void quitGuild(short guildId);
+ }
+ }
+}
+
+#endif
diff --git a/src/net/tmwserv/chatserver/internal.cpp b/src/net/tmwserv/chatserver/internal.cpp
new file mode 100644
index 00000000..52744804
--- /dev/null
+++ b/src/net/tmwserv/chatserver/internal.cpp
@@ -0,0 +1,32 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "internal.h"
+
+namespace Net
+{
+ class Connection;
+
+ namespace ChatServer
+ {
+ Connection *connection = 0;
+ }
+}
diff --git a/src/net/tmwserv/chatserver/internal.h b/src/net/tmwserv/chatserver/internal.h
new file mode 100644
index 00000000..162d54fb
--- /dev/null
+++ b/src/net/tmwserv/chatserver/internal.h
@@ -0,0 +1,35 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_CHATSERVER_INTERNAL_H
+#define NET_CHATSERVER_INTERNAL_H
+
+namespace Net
+{
+ class Connection;
+
+ namespace ChatServer
+ {
+ extern Connection *connection;
+ }
+}
+
+#endif
diff --git a/src/net/tmwserv/chatserver/party.cpp b/src/net/tmwserv/chatserver/party.cpp
new file mode 100644
index 00000000..e5bdd861
--- /dev/null
+++ b/src/net/tmwserv/chatserver/party.cpp
@@ -0,0 +1,69 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "party.h"
+
+#include "internal.h"
+
+#include "net/tmwserv/connection.h"
+#include "net/tmwserv/protocol.h"
+
+#include "net/messageout.h"
+
+#include "log.h"
+
+void Net::ChatServer::Party::invitePlayer(const std::string &name)
+{
+ logger->log("Sending PCMSG_PARTY_INVITE");
+ MessageOut msg(PCMSG_PARTY_INVITE);
+
+ msg.writeString(name);
+
+ Net::ChatServer::connection->send(msg);
+}
+
+void Net::ChatServer::Party::acceptInvite(const std::string &name)
+{
+ logger->log("Sending PCMSG_PARTY_ACCEPT_INVITE");
+ MessageOut msg(PCMSG_PARTY_ACCEPT_INVITE);
+
+ msg.writeString(name);
+
+ Net::ChatServer::connection->send(msg);
+}
+
+void Net::ChatServer::Party::getPartyMembers()
+{
+ logger->log("Sending PCMSG_PARTY_GET_MEMBERS");
+// MessageOut msg(PCMSG_GUILD_GET_MEMBERS);
+
+// msg.writeInt16(guildId);
+
+// Net::ChatServer::connection->send(msg);
+}
+
+void Net::ChatServer::Party::quitParty()
+{
+ logger->log("Sending PCMSG_PARTY_QUIT");
+ MessageOut msg(PCMSG_PARTY_QUIT);
+
+ Net::ChatServer::connection->send(msg);
+}
diff --git a/src/net/tmwserv/chatserver/party.h b/src/net/tmwserv/chatserver/party.h
new file mode 100644
index 00000000..b3f0020b
--- /dev/null
+++ b/src/net/tmwserv/chatserver/party.h
@@ -0,0 +1,56 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_CHATSERVER_PARTY_H
+#define NET_CHATSERVER_PARTY_H
+
+#include <iosfwd>
+
+namespace Net
+{
+ namespace ChatServer
+ {
+ namespace Party
+ {
+ /**
+ * Invite a player to the party.
+ */
+ void invitePlayer(const std::string &name);
+
+ /**
+ * Accept an invite another player has sent to join their party
+ */
+ void acceptInvite(const std::string &name);
+
+ /**
+ * Get a list of party members
+ */
+ void getPartyMembers();
+
+ /**
+ * Leave party
+ */
+ void quitParty();
+ }
+ }
+}
+
+#endif
diff --git a/src/net/tmwserv/connection.cpp b/src/net/tmwserv/connection.cpp
new file mode 100644
index 00000000..0fcd530b
--- /dev/null
+++ b/src/net/tmwserv/connection.cpp
@@ -0,0 +1,104 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/connection.h"
+
+#include "net/tmwserv/internal.h"
+
+#include "net/messageout.h"
+
+#include "log.h"
+
+#include <string>
+
+Net::Connection::Connection(ENetHost *client):
+ mConnection(0), mClient(client)
+{
+ Net::connections++;
+}
+
+Net::Connection::~Connection()
+{
+ Net::connections--;
+}
+
+bool Net::Connection::connect(const std::string &address, short port)
+{
+ logger->log("Net::Connection::connect(%s, %i)", address.c_str(), port);
+
+ if (address.empty())
+ {
+ logger->log("Net::Connection::connect() got empty address!");
+ mState = NET_ERROR;
+ return false;
+ }
+
+ ENetAddress enetAddress;
+
+ enet_address_set_host(&enetAddress, address.c_str());
+ enetAddress.port = port;
+
+ // Initiate the connection, allocating channel 0.
+ mConnection = enet_host_connect(mClient, &enetAddress, 1);
+
+ if (!mConnection)
+ {
+ logger->log("Unable to initiate connection to the server.");
+ mState = NET_ERROR;
+ return false;
+ }
+
+ return true;
+}
+
+void Net::Connection::disconnect()
+{
+ if (!mConnection)
+ return;
+
+ enet_peer_disconnect(mConnection, 0);
+ enet_host_flush(mClient);
+ enet_peer_reset(mConnection);
+
+ mConnection = 0;
+}
+
+bool Net::Connection::isConnected()
+{
+ return bool (mConnection) ?
+ (mConnection->state == ENET_PEER_STATE_CONNECTED) : false;
+}
+
+void Net::Connection::send(const MessageOut &msg)
+{
+ if (!isConnected())
+ {
+ logger->log("Warning: cannot send message to not connected server!");
+ return;
+ }
+
+ //logger->log("Sending message of size %d...", msg.getDataSize());
+
+ ENetPacket *packet = enet_packet_create(msg.getData(),
+ msg.getDataSize(),
+ ENET_PACKET_FLAG_RELIABLE);
+ enet_peer_send(mConnection, 0, packet);
+}
diff --git a/src/net/tmwserv/connection.h b/src/net/tmwserv/connection.h
new file mode 100644
index 00000000..447cf71c
--- /dev/null
+++ b/src/net/tmwserv/connection.h
@@ -0,0 +1,80 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_TMWSERV_CONNECTION_H
+#define NET_TMWSERV_CONNECTION_H
+
+#include <iosfwd>
+
+#include <enet/enet.h>
+
+class MessageOut;
+
+namespace Net
+{
+ /**
+ * \ingroup Network
+ */
+ class Connection
+ {
+ public:
+ enum State {
+ OK,
+ NET_ERROR
+ };
+
+ ~Connection();
+
+ /**
+ * Connects to the given server with the specified address and port.
+ * This method is non-blocking, use isConnected to check whether the
+ * server is connected.
+ */
+ bool connect(const std::string &address, short port);
+
+ /**
+ * Disconnects from the given server.
+ */
+ void disconnect();
+
+ State getState() { return mState; }
+
+ /**
+ * Returns whether the server is connected.
+ */
+ bool isConnected();
+
+ /**
+ * Sends a message.
+ */
+ void send(const MessageOut &msg);
+
+ private:
+ friend Connection *Net::getConnection();
+ Connection(ENetHost *client);
+
+ ENetPeer *mConnection;
+ ENetHost *mClient;
+ State mState;
+ };
+}
+
+#endif
diff --git a/src/net/tmwserv/effecthandler.cpp b/src/net/tmwserv/effecthandler.cpp
new file mode 100644
index 00000000..d2b26fca
--- /dev/null
+++ b/src/net/tmwserv/effecthandler.cpp
@@ -0,0 +1,59 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/effecthandler.h"
+
+#include "net/tmwserv/protocol.h"
+
+#include "net/messagein.h"
+
+#include "effectmanager.h"
+
+
+EffectHandler::EffectHandler()
+{
+ static const Uint16 _messages[] = {
+ GPMSG_CREATE_EFFECT,
+ 0
+ };
+ handledMessages = _messages;
+}
+
+void EffectHandler::handleMessage(MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case GPMSG_CREATE_EFFECT:
+ handleCreateEffects(msg);
+ break;
+ default:
+ break;
+ }
+}
+
+void EffectHandler::handleCreateEffects(MessageIn &msg)
+{
+ int id = msg.readInt16();
+ Uint16 x = msg.readInt16();
+ Uint16 y = msg.readInt16();
+ effectManager->trigger(id, x, y);
+}
+
diff --git a/src/net/tmwserv/effecthandler.h b/src/net/tmwserv/effecthandler.h
new file mode 100644
index 00000000..894ad1c8
--- /dev/null
+++ b/src/net/tmwserv/effecthandler.h
@@ -0,0 +1,38 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_TMWSERV_EFFECTSHANDLER_H
+#define NET_TMWSERV_EFFECTSHANDLER_H
+
+#include "net/messagehandler.h"
+
+class EffectHandler : public MessageHandler
+{
+ public:
+ EffectHandler();
+
+ void handleMessage(MessageIn &msg);
+
+ private:
+ void handleCreateEffects(MessageIn &msg);
+};
+
+#endif
diff --git a/src/net/tmwserv/gameserver/gameserver.cpp b/src/net/tmwserv/gameserver/gameserver.cpp
new file mode 100644
index 00000000..e70c4d19
--- /dev/null
+++ b/src/net/tmwserv/gameserver/gameserver.cpp
@@ -0,0 +1,50 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "gameserver.h"
+
+#include "internal.h"
+
+#include "net/tmwserv/connection.h"
+#include "net/tmwserv/protocol.h"
+
+#include "net/messageout.h"
+
+void Net::GameServer::connect(Net::Connection *connection,
+ const std::string &token)
+{
+ Net::GameServer::connection = connection;
+
+ MessageOut msg(PGMSG_CONNECT);
+
+ msg.writeString(token, 32);
+
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::logout(bool reconnectAccount)
+{
+ MessageOut msg(PGMSG_DISCONNECT);
+
+ msg.writeInt8((unsigned char) reconnectAccount);
+
+ Net::GameServer::connection->send(msg);
+}
diff --git a/src/net/tmwserv/gameserver/gameserver.h b/src/net/tmwserv/gameserver/gameserver.h
new file mode 100644
index 00000000..6de82c2e
--- /dev/null
+++ b/src/net/tmwserv/gameserver/gameserver.h
@@ -0,0 +1,39 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_GAMESERVER_GAMESERVER_H
+#define NET_GAMESERVER_GAMESERVER_H
+
+#include <iosfwd>
+
+namespace Net
+{
+ class Connection;
+
+ namespace GameServer
+ {
+ void connect(Net::Connection *connection, const std::string &token);
+
+ void logout(bool reconnectAccount);
+ }
+}
+
+#endif
diff --git a/src/net/tmwserv/gameserver/internal.cpp b/src/net/tmwserv/gameserver/internal.cpp
new file mode 100644
index 00000000..27cb4a47
--- /dev/null
+++ b/src/net/tmwserv/gameserver/internal.cpp
@@ -0,0 +1,32 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "internal.h"
+
+namespace Net
+{
+ class Connection;
+
+ namespace GameServer
+ {
+ Connection *connection = 0;
+ }
+}
diff --git a/src/net/tmwserv/gameserver/internal.h b/src/net/tmwserv/gameserver/internal.h
new file mode 100644
index 00000000..6c6e2613
--- /dev/null
+++ b/src/net/tmwserv/gameserver/internal.h
@@ -0,0 +1,35 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_GAMESERVER_INTERNAL_H
+#define NET_GAMESERVER_INTERNAL_H
+
+namespace Net
+{
+ class Connection;
+
+ namespace GameServer
+ {
+ extern Connection *connection;
+ }
+}
+
+#endif
diff --git a/src/net/tmwserv/gameserver/player.cpp b/src/net/tmwserv/gameserver/player.cpp
new file mode 100644
index 00000000..ec346d9f
--- /dev/null
+++ b/src/net/tmwserv/gameserver/player.cpp
@@ -0,0 +1,203 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "player.h"
+
+#include "internal.h"
+
+#include "net/tmwserv/connection.h"
+#include "net/tmwserv/protocol.h"
+
+#include "net/messageout.h"
+
+void RespawnRequestListener::action(const gcn::ActionEvent &event)
+{
+ Net::GameServer::Player::respawn();
+}
+
+void Net::GameServer::Player::say(const std::string &text)
+{
+ MessageOut msg(PGMSG_SAY);
+ msg.writeString(text);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::walk(int x, int y)
+{
+ MessageOut msg(PGMSG_WALK);
+ msg.writeInt16(x);
+ msg.writeInt16(y);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::pickUp(int x, int y)
+{
+ MessageOut msg(PGMSG_PICKUP);
+ msg.writeInt16(x);
+ msg.writeInt16(y);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::moveItem(int oldSlot, int newSlot, int amount)
+{
+ MessageOut msg(PGMSG_MOVE_ITEM);
+ msg.writeInt8(oldSlot);
+ msg.writeInt8(newSlot);
+ msg.writeInt8(amount);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::drop(int slot, int amount)
+{
+ MessageOut msg(PGMSG_DROP);
+ msg.writeInt8(slot);
+ msg.writeInt8(amount);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::equip(int slot)
+{
+ MessageOut msg(PGMSG_EQUIP);
+ msg.writeInt8(slot);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::unequip(int slot)
+{
+ MessageOut msg(PGMSG_UNEQUIP);
+ msg.writeInt8(slot);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::useItem(int slot)
+{
+ MessageOut msg(PGMSG_USE_ITEM);
+ msg.writeInt8(slot);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::attack(int direction)
+{
+ MessageOut msg(PGMSG_ATTACK);
+ msg.writeInt8(direction);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::useSpecial(int special)
+{
+ MessageOut msg(PGMSG_USE_SPECIAL);
+ msg.writeInt8(special);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::changeAction(Being::Action action)
+{
+ MessageOut msg(PGMSG_ACTION_CHANGE);
+ msg.writeInt8(action);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::talkToNPC(int id, bool restart)
+{
+ MessageOut msg(restart ? PGMSG_NPC_TALK : PGMSG_NPC_TALK_NEXT);
+ msg.writeInt16(id);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::selectFromNPC(int id, int choice)
+{
+ MessageOut msg(PGMSG_NPC_SELECT);
+ msg.writeInt16(id);
+ msg.writeInt8(choice);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::requestTrade(int id)
+{
+ MessageOut msg(PGMSG_TRADE_REQUEST);
+ msg.writeInt16(id);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::acceptTrade(bool accept)
+{
+ MessageOut msg(accept ? PGMSG_TRADE_ACCEPT : PGMSG_TRADE_CANCEL);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::tradeItem(int slot, int amount)
+{
+ MessageOut msg(PGMSG_TRADE_ADD_ITEM);
+ msg.writeInt8(slot);
+ msg.writeInt8(amount);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::tradeMoney(int amount)
+{
+ MessageOut msg(PGMSG_TRADE_SET_MONEY);
+ msg.writeInt32(amount);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::tradeWithNPC(int item, int amount)
+{
+ MessageOut msg(PGMSG_NPC_BUYSELL);
+ msg.writeInt16(item);
+ msg.writeInt16(amount);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::sendLetter(const std::string &player,
+ const std::string &text)
+{
+ MessageOut msg(PGMSG_NPC_POST_SEND);
+ msg.writeString(player);
+ msg.writeString(text);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::raiseAttribute(int attribute)
+{
+ MessageOut msg(PGMSG_RAISE_ATTRIBUTE);
+ msg.writeInt8(attribute);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::lowerAttribute(int attribute)
+{
+ MessageOut msg(PGMSG_LOWER_ATTRIBUTE);
+ msg.writeInt8(attribute);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::respawn()
+{
+ MessageOut msg(PGMSG_RESPAWN);
+ Net::GameServer::connection->send(msg);
+}
+
+void Net::GameServer::Player::changeDir(unsigned char dir)
+{
+ MessageOut msg(PGMSG_DIRECTION_CHANGE);
+ msg.writeInt8(dir);
+ Net::GameServer::connection->send(msg);
+}
diff --git a/src/net/tmwserv/gameserver/player.h b/src/net/tmwserv/gameserver/player.h
new file mode 100644
index 00000000..3f33c7d5
--- /dev/null
+++ b/src/net/tmwserv/gameserver/player.h
@@ -0,0 +1,71 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_GAMESERVER_PLAYER_H
+#define NET_GAMESERVER_PLAYER_H
+
+#include "being.h"
+
+#include <guichan/actionlistener.hpp>
+
+#include <iosfwd>
+
+
+struct RespawnRequestListener : public gcn::ActionListener
+{
+ void action(const gcn::ActionEvent &event);
+};
+
+namespace Net
+{
+ namespace GameServer
+ {
+ namespace Player
+ {
+ void say(const std::string &text);
+ void walk(int x, int y);
+ void pickUp(int x, int y);
+ void moveItem(int oldSlot, int newSlot, int amount);
+ void drop(int slot, int amount);
+ void equip(int slot);
+ void unequip(int slot);
+ void useItem(int slot);
+ void attack(int direction);
+ void useSpecial(int special);
+ void changeAction(Being::Action action);
+ void talkToNPC(int id, bool restart);
+ void selectFromNPC(int id, int choice);
+ void requestTrade(int id);
+ void acceptTrade(bool accept);
+ void tradeItem(int slot, int amount);
+ void tradeMoney(int amount);
+ void tradeWithNPC(int item, int amount);
+ void sendLetter(const std::string &player, const std::string &text);
+ void raiseAttribute(int attribute);
+ void lowerAttribute(int attribute);
+ void respawn();
+ static RespawnRequestListener respawnListener;
+ void changeDir(unsigned char dir);
+ }
+ }
+}
+
+#endif
diff --git a/src/net/tmwserv/guildhandler.cpp b/src/net/tmwserv/guildhandler.cpp
new file mode 100644
index 00000000..21b43063
--- /dev/null
+++ b/src/net/tmwserv/guildhandler.cpp
@@ -0,0 +1,243 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/guildhandler.h"
+
+#include "net/messagein.h"
+
+#include "net/tmwserv/chatserver/chatserver.h"
+#include "net/tmwserv/chatserver/guild.h"
+#include "net/tmwserv/protocol.h"
+
+#include "gui/widgets/channeltab.h"
+#include "gui/chat.h"
+#include "gui/guildwindow.h"
+
+#include "guild.h"
+#include "log.h"
+#include "localplayer.h"
+#include "channel.h"
+#include "channelmanager.h"
+
+#include <iostream>
+
+GuildHandler::GuildHandler()
+{
+ static const Uint16 _messages[] = {
+ CPMSG_GUILD_CREATE_RESPONSE,
+ CPMSG_GUILD_INVITE_RESPONSE,
+ CPMSG_GUILD_ACCEPT_RESPONSE,
+ CPMSG_GUILD_GET_MEMBERS_RESPONSE,
+ CPMSG_GUILD_UPDATE_LIST,
+ CPMSG_GUILD_INVITED,
+ CPMSG_GUILD_REJOIN,
+ CPMSG_GUILD_QUIT_RESPONSE,
+ 0
+ };
+ handledMessages = _messages;
+
+}
+
+void GuildHandler::handleMessage(MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case CPMSG_GUILD_CREATE_RESPONSE:
+ {
+ logger->log("Received CPMSG_GUILD_CREATE_RESPONSE");
+ if(msg.readInt8() == ERRMSG_OK)
+ {
+ // TODO - Acknowledge guild was created
+ localChatTab->chatLog("Guild created.");
+ joinedGuild(msg);
+ }
+ else
+ {
+ localChatTab->chatLog("Error creating guild.");
+ }
+ } break;
+
+ case CPMSG_GUILD_INVITE_RESPONSE:
+ {
+ logger->log("Received CPMSG_GUILD_INVITE_RESPONSE");
+ if(msg.readInt8() == ERRMSG_OK)
+ {
+ // TODO - Acknowledge invite was sent
+ localChatTab->chatLog("Invite sent.");
+ }
+ } break;
+
+ case CPMSG_GUILD_ACCEPT_RESPONSE:
+ {
+ logger->log("Received CPMSG_GUILD_ACCEPT_RESPONSE");
+ if(msg.readInt8() == ERRMSG_OK)
+ {
+ // TODO - Acknowledge accepted into guild
+ joinedGuild(msg);
+ }
+ } break;
+
+ case CPMSG_GUILD_GET_MEMBERS_RESPONSE:
+ {
+ logger->log("Received CPMSG_GUILD_GET_MEMBERS_RESPONSE");
+ if(msg.readInt8() == ERRMSG_OK)
+ {
+ std::string guildMember;
+ bool online;
+ std::string guildName;
+ Guild *guild;
+
+ short guildId = msg.readInt16();
+ guild = player_node->getGuild(guildId);
+
+ if (!guild)
+ return;
+
+ guildName = guild->getName();
+
+ while(msg.getUnreadLength())
+ {
+ guildMember = msg.readString();
+ online = msg.readInt8();
+ if(guildMember != "")
+ {
+ guild->addMember(guildMember);
+ guildWindow->setOnline(guildName, guildMember, online);
+ }
+ }
+
+ guildWindow->updateTab();
+ }
+ } break;
+
+ case CPMSG_GUILD_UPDATE_LIST:
+ {
+ logger->log("Received CPMSG_GUILD_UPDATE_LIST");
+ short guildId = msg.readInt16();
+ std::string guildMember = msg.readString();
+ char eventId = msg.readInt8();
+
+ Guild *guild = player_node->getGuild(guildId);
+ if (guild)
+ {
+ switch(eventId)
+ {
+ case GUILD_EVENT_NEW_PLAYER:
+ guild->addMember(guildMember);
+ guildWindow->setOnline(guild->getName(), guildMember, true);
+ break;
+
+ case GUILD_EVENT_LEAVING_PLAYER:
+ guild->removeMember(guildMember);
+ break;
+
+ case GUILD_EVENT_ONLINE_PLAYER:
+ guildWindow->setOnline(guild->getName(), guildMember, true);
+ break;
+
+ case GUILD_EVENT_OFFLINE_PLAYER:
+ guildWindow->setOnline(guild->getName(), guildMember, false);
+ break;
+
+ default:
+ logger->log("Invalid guild event");
+ }
+ }
+ guildWindow->updateTab();
+
+
+ } break;
+
+ case CPMSG_GUILD_INVITED:
+ {
+ logger->log("Received CPMSG_GUILD_INVITED");
+ std::string inviterName = msg.readString();
+ std::string guildName = msg.readString();
+
+ // Open a dialog asking if the player accepts joining the guild.
+ guildWindow->openAcceptDialog(inviterName, guildName);
+ } break;
+
+ case CPMSG_GUILD_PROMOTE_MEMBER_RESPONSE:
+ {
+ logger->log("Received CPMSG_GUILD_PROMOTE_MEMBER_RESPONSE");
+
+ if (msg.readInt8() == ERRMSG_OK)
+ {
+ // promotion succeeded
+ localChatTab->chatLog("Member was promoted successfully");
+ }
+ else
+ {
+ // promotion failed
+ localChatTab->chatLog("Failed to promote member");
+ }
+ }
+
+ case CPMSG_GUILD_REJOIN:
+ {
+ logger->log("Received CPMSG_GUILD_REJOIN");
+
+ joinedGuild(msg);
+ } break;
+
+ case CPMSG_GUILD_QUIT_RESPONSE:
+ {
+ logger->log("Received CPMSG_GUILD_QUIT_RESPONSE");
+
+ if (msg.readInt8() == ERRMSG_OK)
+ {
+ // Must remove tab first, as it wont find the guild
+ // name after its removed from the player
+ int guildId = msg.readInt16();
+ Guild *guild = player_node->getGuild(guildId);
+ if (guild)
+ {
+ Channel *channel = channelManager->findByName(guild->getName());
+ channelManager->removeChannel(channel);
+ guildWindow->removeTab(guildId);
+ player_node->removeGuild(guildId);
+ }
+ }
+ } break;
+ }
+}
+
+void GuildHandler::joinedGuild(MessageIn &msg)
+{
+ std::string guildName = msg.readString();
+ short guildId = msg.readInt16();
+ short permissions = msg.readInt16();
+ short channelId = msg.readInt16();
+ std::string announcement = msg.readString();
+
+ // Add guild to player and create new guild tab
+ Guild *guild = player_node->addGuild(guildId, permissions);
+ guild->setName(guildName);
+ guildWindow->newGuildTab(guildName);
+ guildWindow->requestMemberList(guildId);
+
+ // Automatically create the guild channel
+ // COMMENT: Should this go here??
+ Channel *channel = new Channel(channelId, guildName, announcement);
+ channelManager->addChannel(channel);
+ channel->getTab()->chatLog("Topic: " + announcement, BY_CHANNEL);
+}
diff --git a/src/net/tmwserv/guildhandler.h b/src/net/tmwserv/guildhandler.h
new file mode 100644
index 00000000..9b900d9f
--- /dev/null
+++ b/src/net/tmwserv/guildhandler.h
@@ -0,0 +1,40 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_TMWSERV_GUILDHANDLER_H
+#define NET_TMWSERV_GUILDHANDLER_H
+
+#include "net/messagehandler.h"
+
+#include <string>
+
+class GuildHandler : public MessageHandler
+{
+public:
+ GuildHandler();
+
+ void handleMessage(MessageIn &msg);
+
+protected:
+ void joinedGuild(MessageIn &msg);
+};
+
+#endif
diff --git a/src/net/tmwserv/internal.cpp b/src/net/tmwserv/internal.cpp
new file mode 100644
index 00000000..253d4f5f
--- /dev/null
+++ b/src/net/tmwserv/internal.cpp
@@ -0,0 +1,27 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/internal.h"
+
+namespace Net
+{
+ int connections = 0;
+}
diff --git a/src/net/tmwserv/internal.h b/src/net/tmwserv/internal.h
new file mode 100644
index 00000000..17ee9081
--- /dev/null
+++ b/src/net/tmwserv/internal.h
@@ -0,0 +1,30 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_TMWSERV_INTERNAL_H
+#define NET_TMWSERV_INTERNAL_H
+
+namespace Net
+{
+ extern int connections;
+}
+
+#endif
diff --git a/src/net/tmwserv/inventoryhandler.cpp b/src/net/tmwserv/inventoryhandler.cpp
new file mode 100644
index 00000000..f6522128
--- /dev/null
+++ b/src/net/tmwserv/inventoryhandler.cpp
@@ -0,0 +1,79 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/inventoryhandler.h"
+
+#include "net/tmwserv/protocol.h"
+
+#include "net/messagein.h"
+
+#include "equipment.h"
+#include "inventory.h"
+#include "item.h"
+#include "itemshortcut.h"
+#include "localplayer.h"
+
+#include "gui/chat.h"
+
+#include "resources/iteminfo.h"
+
+InventoryHandler::InventoryHandler()
+{
+ static const Uint16 _messages[] = {
+ GPMSG_INVENTORY_FULL,
+ GPMSG_INVENTORY,
+ 0
+ };
+ handledMessages = _messages;
+}
+
+void InventoryHandler::handleMessage(MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case GPMSG_INVENTORY_FULL:
+ player_node->clearInventory();
+ // no break!
+
+ case GPMSG_INVENTORY:
+ while (msg.getUnreadLength())
+ {
+ int slot = msg.readInt8();
+ if (slot == 255)
+ {
+ player_node->setMoney(msg.readInt32());
+ continue;
+ }
+
+ int id = msg.readInt16();
+ if (slot < EQUIPMENT_SIZE)
+ {
+ player_node->mEquipment->setEquipment(slot, id);
+ }
+ else if (slot >= 32 && slot < 32 + INVENTORY_SIZE)
+ {
+ int amount = id ? msg.readInt8() : 0;
+ player_node->setInvItem(slot - 32, id, amount);
+ }
+ };
+ break;
+ }
+}
diff --git a/src/net/inventoryhandler.h b/src/net/tmwserv/inventoryhandler.h
index f87e1214..4144d89c 100644
--- a/src/net/inventoryhandler.h
+++ b/src/net/tmwserv/inventoryhandler.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,17 +19,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef NET_INVENTORYHANDLER_H
-#define NET_INVENTORYHANDLER_H
+#ifndef NET_TMWSERV_INVENTORYHANDLER_H
+#define NET_TMWSERV_INVENTORYHANDLER_H
-#include "messagehandler.h"
+#include "net/messagehandler.h"
class InventoryHandler : public MessageHandler
{
public:
InventoryHandler();
- void handleMessage(MessageIn *msg);
+ void handleMessage(MessageIn &msg);
};
#endif
diff --git a/src/net/tmwserv/itemhandler.cpp b/src/net/tmwserv/itemhandler.cpp
new file mode 100644
index 00000000..4ed61266
--- /dev/null
+++ b/src/net/tmwserv/itemhandler.cpp
@@ -0,0 +1,66 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/itemhandler.h"
+
+#include "net/tmwserv/protocol.h"
+
+#include "net/messagein.h"
+
+#include "engine.h"
+#include "flooritemmanager.h"
+
+ItemHandler::ItemHandler()
+{
+ static const Uint16 _messages[] = {
+ GPMSG_ITEMS,
+ GPMSG_ITEM_APPEAR,
+ 0
+ };
+ handledMessages = _messages;
+}
+
+void ItemHandler::handleMessage(MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case GPMSG_ITEM_APPEAR:
+ case GPMSG_ITEMS:
+ {
+ while (msg.getUnreadLength())
+ {
+ int itemId = msg.readInt16();
+ int x = msg.readInt16();
+ int y = msg.readInt16();
+ int id = (x << 16) | y; // dummy id
+
+ if (itemId)
+ {
+ floorItemManager->create(id, itemId, x / 32, y / 32, engine->getCurrentMap());
+ }
+ else if (FloorItem *item = floorItemManager->findById(id))
+ {
+ floorItemManager->destroy(item);
+ }
+ }
+ } break;
+ }
+}
diff --git a/src/net/itemhandler.h b/src/net/tmwserv/itemhandler.h
index 0f292d46..6a2a96c8 100644
--- a/src/net/itemhandler.h
+++ b/src/net/tmwserv/itemhandler.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,17 +19,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef NET_ITEMHANDLER_H
-#define NET_ITEMHANDLER_H
+#ifndef NET_TMWSERV_ITEMHANDLER_H
+#define NET_TMWSERV_ITEMHANDLER_H
-#include "messagehandler.h"
+#include "net/messagehandler.h"
class ItemHandler : public MessageHandler
{
public:
ItemHandler();
- void handleMessage(MessageIn *msg);
+ void handleMessage(MessageIn &msg);
};
#endif
diff --git a/src/net/tmwserv/loginhandler.cpp b/src/net/tmwserv/loginhandler.cpp
new file mode 100644
index 00000000..ccba06ed
--- /dev/null
+++ b/src/net/tmwserv/loginhandler.cpp
@@ -0,0 +1,226 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/loginhandler.h"
+
+#include "net/tmwserv/protocol.h"
+
+#include "net/messagein.h"
+
+#include "logindata.h"
+#include "main.h"
+
+LoginHandler::LoginHandler()
+{
+ static const Uint16 _messages[] = {
+ APMSG_LOGIN_RESPONSE,
+ APMSG_REGISTER_RESPONSE,
+ APMSG_RECONNECT_RESPONSE,
+ APMSG_PASSWORD_CHANGE_RESPONSE,
+ APMSG_EMAIL_CHANGE_RESPONSE,
+ 0
+ };
+ handledMessages = _messages;
+}
+
+void LoginHandler::setLoginData(LoginData *loginData)
+{
+ mLoginData = loginData;
+}
+
+void LoginHandler::handleMessage(MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case APMSG_LOGIN_RESPONSE:
+ handleLoginResponse(msg);
+ break;
+ case APMSG_REGISTER_RESPONSE:
+ handleRegisterResponse(msg);
+ break;
+ case APMSG_RECONNECT_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Successful login
+ if (errMsg == ERRMSG_OK)
+ {
+ state = STATE_CHAR_SELECT;
+ }
+ // Login failed
+ else
+ {
+ switch (errMsg) {
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage = "Wrong magic_token";
+ break;
+ case ERRMSG_FAILURE:
+ errorMessage = "Already logged in";
+ break;
+ case LOGIN_SERVER_FULL:
+ errorMessage = "Server is full";
+ break;
+ default:
+ errorMessage = "Unknown error";
+ break;
+ }
+ state = STATE_ERROR;
+ }
+ }
+ break;
+
+ case APMSG_PASSWORD_CHANGE_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Successful pass change
+ if (errMsg == ERRMSG_OK)
+ {
+ state = STATE_CHANGEPASSWORD;
+ }
+ // pass change failed
+ else
+ {
+ switch (errMsg) {
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage = "New password incorrect";
+ break;
+ case ERRMSG_FAILURE:
+ errorMessage = "Old password incorrect";
+ break;
+ case ERRMSG_NO_LOGIN:
+ errorMessage = "Account not connected. Please login first.";
+ break;
+ default:
+ errorMessage = "Unknown error";
+ break;
+ }
+ state = STATE_ACCOUNTCHANGE_ERROR;
+ }
+ }
+ break;
+
+ case APMSG_EMAIL_CHANGE_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Successful pass change
+ if (errMsg == ERRMSG_OK)
+ {
+ state = STATE_CHANGEEMAIL;
+ }
+ // pass change failed
+ else
+ {
+ switch (errMsg) {
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage = "New email address incorrect";
+ break;
+ case ERRMSG_FAILURE:
+ errorMessage = "Old email address incorrect";
+ break;
+ case ERRMSG_NO_LOGIN:
+ errorMessage = "Account not connected. Please login first.";
+ break;
+ case ERRMSG_EMAIL_ALREADY_EXISTS:
+ errorMessage = "The new Email Address already exists.";
+ break;
+ default:
+ errorMessage = "Unknown error";
+ break;
+ }
+ state = STATE_ACCOUNTCHANGE_ERROR;
+ }
+ }
+ break;
+
+ }
+}
+
+void LoginHandler::handleLoginResponse(MessageIn &msg)
+{
+ const int errMsg = msg.readInt8();
+
+ if (errMsg == ERRMSG_OK)
+ {
+ readUpdateHost(msg);
+ state = STATE_CHAR_SELECT;
+ }
+ else
+ {
+ switch (errMsg) {
+ case LOGIN_INVALID_VERSION:
+ errorMessage = "Client version is too old";
+ break;
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage = "Wrong username or password";
+ break;
+ case ERRMSG_FAILURE:
+ errorMessage = "Already logged in";
+ break;
+ case LOGIN_SERVER_FULL:
+ errorMessage = "Server is full";
+ break;
+ default:
+ errorMessage = "Unknown error";
+ break;
+ }
+ state = STATE_LOGIN_ERROR;
+ }
+}
+
+void LoginHandler::handleRegisterResponse(MessageIn &msg)
+{
+ const int errMsg = msg.readInt8();
+
+ if (errMsg == ERRMSG_OK)
+ {
+ readUpdateHost(msg);
+ state = STATE_CHAR_SELECT;
+ }
+ else
+ {
+ switch (errMsg) {
+ case REGISTER_INVALID_VERSION:
+ errorMessage = "Client version is too old";
+ break;
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage = "Wrong username, password or email address";
+ break;
+ case REGISTER_EXISTS_USERNAME:
+ errorMessage = "Username already exists";
+ break;
+ case REGISTER_EXISTS_EMAIL:
+ errorMessage = "Email address already exists";
+ break;
+ default:
+ errorMessage = "Unknown error";
+ break;
+ }
+ state = STATE_LOGIN_ERROR;
+ }
+}
+
+void LoginHandler::readUpdateHost(MessageIn &msg)
+{
+ // Set the update host when included in the message
+ if (msg.getUnreadLength() > 0)
+ {
+ mLoginData->updateHost = msg.readString();
+ }
+}
diff --git a/src/net/tmwserv/loginhandler.h b/src/net/tmwserv/loginhandler.h
new file mode 100644
index 00000000..81dd273c
--- /dev/null
+++ b/src/net/tmwserv/loginhandler.h
@@ -0,0 +1,47 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_TMWSERV_LOGINHANDLER_H
+#define NET_TMWSERV_LOGINHANDLER_H
+
+#include "net/messagehandler.h"
+
+class LoginData;
+
+class LoginHandler : public MessageHandler
+{
+ public:
+ LoginHandler();
+
+ void setLoginData(LoginData *loginData);
+
+ void handleMessage(MessageIn &msg);
+
+ private:
+ void handleLoginResponse(MessageIn &msg);
+ void handleRegisterResponse(MessageIn &msg);
+
+ void readUpdateHost(MessageIn &msg);
+
+ LoginData *mLoginData;
+};
+
+#endif // NET_TMWSERV_LOGINHANDLER_H
diff --git a/src/net/tmwserv/logouthandler.cpp b/src/net/tmwserv/logouthandler.cpp
new file mode 100644
index 00000000..8b0e2d6e
--- /dev/null
+++ b/src/net/tmwserv/logouthandler.cpp
@@ -0,0 +1,218 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/logouthandler.h"
+
+#include "net/tmwserv/protocol.h"
+
+#include "net/messagein.h"
+
+#include "main.h"
+
+LogoutHandler::LogoutHandler():
+ mPassToken(NULL),
+ mScenario(LOGOUT_EXIT),
+ mLoggedOutAccount(false),
+ mLoggedOutGame(false),
+ mLoggedOutChat(false)
+{
+ static const Uint16 _messages[] = {
+ APMSG_LOGOUT_RESPONSE,
+ APMSG_UNREGISTER_RESPONSE,
+ GPMSG_DISCONNECT_RESPONSE,
+ CPMSG_DISCONNECT_RESPONSE,
+ 0
+ };
+ handledMessages = _messages;
+}
+
+void LogoutHandler::handleMessage(MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case APMSG_LOGOUT_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+
+ // Successful logout
+ if (errMsg == ERRMSG_OK)
+ {
+ mLoggedOutAccount = true;
+
+ switch (mScenario)
+ {
+ case LOGOUT_SWITCH_ACCOUNTSERVER:
+ if (mLoggedOutGame && mLoggedOutChat)
+ state = STATE_SWITCH_ACCOUNTSERVER;
+ break;
+
+ case LOGOUT_EXIT:
+ default:
+ if (mLoggedOutGame && mLoggedOutChat)
+ state = STATE_FORCE_QUIT;
+ break;
+ }
+ }
+ // Logout failed
+ else
+ {
+ switch (errMsg) {
+ case ERRMSG_NO_LOGIN:
+ errorMessage = "Accountserver: Not logged in";
+ break;
+ default:
+ errorMessage = "Accountserver: Unknown error";
+ break;
+ }
+ state = STATE_ERROR;
+ }
+ }
+ break;
+ case APMSG_UNREGISTER_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Successful unregistration
+ if (errMsg == ERRMSG_OK)
+ {
+ state = STATE_UNREGISTER;
+ }
+ // Unregistration failed
+ else
+ {
+ switch (errMsg) {
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage =
+ "Accountserver: Wrong username or password";
+ break;
+ default:
+ errorMessage = "Accountserver: Unknown error";
+ break;
+ }
+ state = STATE_ACCOUNTCHANGE_ERROR;
+ }
+ }
+ break;
+ case GPMSG_DISCONNECT_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Successful logout
+ if (errMsg == ERRMSG_OK)
+ {
+ mLoggedOutGame = true;
+
+ switch (mScenario)
+ {
+ case LOGOUT_SWITCH_CHARACTER:
+ if (mPassToken)
+ {
+ *mPassToken = msg.readString(32);
+ mPassToken = NULL;
+ }
+ if (mLoggedOutChat) state = STATE_RECONNECT_ACCOUNT;
+ break;
+
+ case LOGOUT_SWITCH_ACCOUNTSERVER:
+ if (mLoggedOutAccount && mLoggedOutChat)
+ state = STATE_SWITCH_ACCOUNTSERVER;
+ break;
+
+ case LOGOUT_EXIT:
+ default:
+ if (mLoggedOutAccount && mLoggedOutChat)
+ state = STATE_FORCE_QUIT;
+ break;
+ }
+ }
+ // Logout failed
+ else
+ {
+ switch (errMsg) {
+ case ERRMSG_NO_LOGIN:
+ errorMessage = "Gameserver: Not logged in";
+ break;
+ default:
+ errorMessage = "Gameserver: Unknown error";
+ break;
+ }
+ state = STATE_ERROR;
+ }
+ }
+ break;
+ case CPMSG_DISCONNECT_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Successful logout
+ if (errMsg == ERRMSG_OK)
+ {
+ mLoggedOutChat = true;
+
+ switch (mScenario)
+ {
+ case LOGOUT_SWITCH_CHARACTER:
+ if (mLoggedOutGame) state = STATE_RECONNECT_ACCOUNT;
+ break;
+
+ case LOGOUT_SWITCH_ACCOUNTSERVER:
+ if (mLoggedOutAccount && mLoggedOutGame)
+ state = STATE_SWITCH_ACCOUNTSERVER;
+ break;
+
+ case LOGOUT_EXIT:
+ default:
+ if (mLoggedOutAccount && mLoggedOutGame)
+ {
+ state = STATE_FORCE_QUIT;
+ }
+ break;
+ }
+ }
+ else
+ {
+ switch (errMsg) {
+ case ERRMSG_NO_LOGIN:
+ errorMessage = "Chatserver: Not logged in";
+ break;
+ default:
+ errorMessage = "Chatserver: Unknown error";
+ break;
+ }
+ state = STATE_ERROR;
+ }
+ }
+ break;
+ }
+}
+
+void LogoutHandler::setScenario(unsigned short scenario,
+ std::string *passToken)
+{
+ mScenario = scenario;
+ mPassToken = passToken;
+}
+
+void LogoutHandler::reset()
+{
+ mPassToken = NULL;
+ mScenario = LOGOUT_EXIT;
+ mLoggedOutAccount = false;
+ mLoggedOutGame = false;
+ mLoggedOutChat = false;
+}
diff --git a/src/net/tmwserv/logouthandler.h b/src/net/tmwserv/logouthandler.h
new file mode 100644
index 00000000..6c69c8be
--- /dev/null
+++ b/src/net/tmwserv/logouthandler.h
@@ -0,0 +1,62 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_TMWSERV_LOGOUTHANDLER_H
+#define NET_TMWSERV_LOGOUTHANDLER_H
+
+#include "net/messagehandler.h"
+
+#include <string>
+
+/**
+ * The different scenarios for which LogoutHandler can be used
+ */
+enum {
+ LOGOUT_EXIT,
+ LOGOUT_SWITCH_ACCOUNTSERVER,
+ LOGOUT_SWITCH_CHARACTER
+};
+
+class LogoutHandler : public MessageHandler
+{
+ public:
+ LogoutHandler();
+
+ void handleMessage(MessageIn &msg);
+
+ void setScenario(unsigned short scenario,
+ std::string *passToken = NULL);
+
+ void reset();
+
+ void setAccountLoggedOut() { mLoggedOutAccount = true; }
+ void setGameLoggedOut() { mLoggedOutGame = true; }
+ void setChatLoggedOut() { mLoggedOutChat = true; }
+
+ private:
+ std::string* mPassToken;
+ unsigned short mScenario;
+ bool mLoggedOutAccount;
+ bool mLoggedOutGame;
+ bool mLoggedOutChat;
+};
+
+#endif
diff --git a/src/net/tmwserv/network.cpp b/src/net/tmwserv/network.cpp
new file mode 100644
index 00000000..d353da17
--- /dev/null
+++ b/src/net/tmwserv/network.cpp
@@ -0,0 +1,170 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/network.h"
+
+#include "net/tmwserv/connection.h"
+#include "net/tmwserv/internal.h"
+
+#include "net/messagehandler.h"
+#include "net/messagein.h"
+
+#include "log.h"
+
+#include <enet/enet.h>
+
+#include <map>
+
+/**
+ * The local host which is shared for all outgoing connections.
+ */
+namespace {
+ ENetHost *client;
+}
+
+typedef std::map<unsigned short, MessageHandler*> MessageHandlers;
+typedef MessageHandlers::iterator MessageHandlerIterator;
+static MessageHandlers mMessageHandlers;
+
+void Net::initialize()
+{
+ if (enet_initialize())
+ {
+ logger->error("Failed to initialize ENet.");
+ }
+
+ client = enet_host_create(NULL, 3, 0, 0);
+
+ if (!client)
+ {
+ logger->error("Failed to create the local host.");
+ }
+}
+
+void Net::finalize()
+{
+ if (!client)
+ return; // Wasn't initialized at all
+
+ if (Net::connections) {
+ logger->error("Tried to shutdown the network subsystem while there "
+ "are network connections left!");
+ }
+
+ clearHandlers();
+ enet_deinitialize();
+}
+
+Net::Connection *Net::getConnection()
+{
+ if (!client)
+ {
+ logger->error("Tried to instantiate a network object before "
+ "initializing the network subsystem!");
+ }
+
+ return new Net::Connection(client);
+}
+
+void Net::registerHandler(MessageHandler *handler)
+{
+ for (const Uint16 *i = handler->handledMessages; *i; i++)
+ {
+ mMessageHandlers[*i] = handler;
+ }
+}
+
+void Net::unregisterHandler(MessageHandler *handler)
+{
+ for (const Uint16 *i = handler->handledMessages; *i; i++)
+ {
+ mMessageHandlers.erase(*i);
+ }
+}
+
+void Net::clearHandlers()
+{
+ mMessageHandlers.clear();
+}
+
+
+/**
+ * Dispatches a message to the appropriate message handler and
+ * destroys it afterwards.
+ */
+namespace
+{
+ void dispatchMessage(ENetPacket *packet)
+ {
+ MessageIn msg((const char *)packet->data, packet->dataLength);
+
+ MessageHandlerIterator iter = mMessageHandlers.find(msg.getId());
+
+ if (iter != mMessageHandlers.end()) {
+ //logger->log("Received packet %x (%i B)",
+ // msg.getId(), msg.getLength());
+ iter->second->handleMessage(msg);
+ }
+ else {
+ logger->log("Unhandled packet %x (%i B)",
+ msg.getId(), msg.getLength());
+ }
+
+ // Clean up the packet now that we're done using it.
+ enet_packet_destroy(packet);
+ }
+}
+
+void Net::flush()
+{
+ ENetEvent event;
+
+ // Wait up to 10 milliseconds for an event.
+ while (enet_host_service(client, &event, 10) > 0)
+ {
+ switch (event.type)
+ {
+ case ENET_EVENT_TYPE_CONNECT:
+ logger->log("Connected to port %d.", event.peer->address.port);
+ // Store any relevant server information here.
+ event.peer->data = 0;
+ break;
+
+ case ENET_EVENT_TYPE_RECEIVE:
+ dispatchMessage(event.packet);
+ break;
+
+ case ENET_EVENT_TYPE_DISCONNECT:
+ logger->log("Disconnected.");
+ // Reset the server information.
+ event.peer->data = 0;
+ break;
+
+ case ENET_EVENT_TYPE_NONE:
+ logger->log("No event during 10 milliseconds.");
+ break;
+
+ default:
+ logger->log("Unhandled enet event.");
+ break;
+ }
+ }
+}
diff --git a/src/net/tmwserv/network.h b/src/net/tmwserv/network.h
new file mode 100644
index 00000000..1b5c7bc6
--- /dev/null
+++ b/src/net/tmwserv/network.h
@@ -0,0 +1,79 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_TMWSERV_NETWORK_H
+#define NET_TMWSERV_NETWORK_H
+
+#include <iosfwd>
+
+/**
+ * \defgroup Network Core network layer
+ */
+
+class MessageHandler;
+class MessageOut;
+
+/**
+ * \ingroup Network
+ */
+namespace Net
+{
+ class Connection;
+
+ /**
+ * Initializes the network subsystem.
+ */
+ void initialize();
+
+ /**
+ * Finalizes the network subsystem.
+ */
+ void finalize();
+
+ /**
+ * Returns a new Connection object. Should be deleted by the caller.
+ */
+ Connection *getConnection();
+
+ /**
+ * Registers a message handler. A message handler handles a certain
+ * subset of incoming messages.
+ */
+ void registerHandler(MessageHandler *handler);
+
+ /**
+ * Unregisters a message handler.
+ */
+ void unregisterHandler(MessageHandler *handler);
+
+ /**
+ * Clears all registered message handlers.
+ */
+ void clearHandlers();
+
+ /*
+ * Handles all events and dispatches incoming messages to the
+ * registered handlers
+ */
+ void flush();
+}
+
+#endif
diff --git a/src/net/tmwserv/npchandler.cpp b/src/net/tmwserv/npchandler.cpp
new file mode 100644
index 00000000..bae5228c
--- /dev/null
+++ b/src/net/tmwserv/npchandler.cpp
@@ -0,0 +1,83 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/npchandler.h"
+
+#include "net/tmwserv/protocol.h"
+
+#include "net/messagein.h"
+
+#include "beingmanager.h"
+#include "npc.h"
+
+#include "gui/npclistdialog.h"
+#include "gui/npcpostdialog.h"
+#include "gui/npc_text.h"
+
+NPCHandler::NPCHandler()
+{
+ static const Uint16 _messages[] = {
+ GPMSG_NPC_CHOICE,
+ GPMSG_NPC_POST,
+ GPMSG_NPC_MESSAGE,
+ GPMSG_NPC_ERROR,
+ 0
+ };
+ handledMessages = _messages;
+}
+
+void NPCHandler::handleMessage(MessageIn &msg)
+{
+ Being *being = beingManager->findBeing(msg.readInt16());
+ if (!being || being->getType() != Being::NPC)
+ {
+ return;
+ }
+
+ current_npc = being->getId();
+
+ switch (msg.getId())
+ {
+ case GPMSG_NPC_CHOICE:
+ npcListDialog->reset();
+ while (msg.getUnreadLength())
+ {
+ npcListDialog->addItem(msg.readString());
+ }
+ npcListDialog->setVisible(true);
+ break;
+
+ case GPMSG_NPC_POST:
+ npcTextDialog->setVisible(false);
+ npcPostDialog->clear();
+ npcPostDialog->setVisible(true);
+ break;
+
+ case GPMSG_NPC_ERROR:
+ current_npc = NULL;
+ case GPMSG_NPC_MESSAGE:
+ npcTextDialog->addText(msg.readString(msg.getUnreadLength()));
+ npcListDialog->setVisible(false);
+ npcTextDialog->setVisible(true);
+ npcPostDialog->setVisible(false);
+ break;
+ }
+}
diff --git a/src/net/npchandler.h b/src/net/tmwserv/npchandler.h
index 35db2956..905c9b01 100644
--- a/src/net/npchandler.h
+++ b/src/net/tmwserv/npchandler.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,17 +19,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef NET_NPCHANDLER_H
-#define NET_NPCHANDLER_H
+#ifndef NET_TMWSERV_NPCHANDLER_H
+#define NET_TMWSERV_NPCHANDLER_H
-#include "messagehandler.h"
+#include "net/messagehandler.h"
class NPCHandler : public MessageHandler
{
public:
NPCHandler();
- void handleMessage(MessageIn *msg);
+ void handleMessage(MessageIn &msg);
};
#endif
diff --git a/src/net/tmwserv/partyhandler.cpp b/src/net/tmwserv/partyhandler.cpp
new file mode 100644
index 00000000..dfbcea80
--- /dev/null
+++ b/src/net/tmwserv/partyhandler.cpp
@@ -0,0 +1,105 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/partyhandler.h"
+
+#include "net/tmwserv/chatserver/chatserver.h"
+#include "net/tmwserv/protocol.h"
+
+#include "net/messagein.h"
+
+#include "gui/chat.h"
+#include "gui/partywindow.h"
+
+#include "log.h"
+#include "localplayer.h"
+
+#include <iostream>
+
+PartyHandler::PartyHandler()
+{
+ static const Uint16 _messages[] = {
+ CPMSG_PARTY_INVITE_RESPONSE,
+ CPMSG_PARTY_INVITED,
+ CPMSG_PARTY_ACCEPT_INVITE_RESPONSE,
+ CPMSG_PARTY_QUIT_RESPONSE,
+ CPMSG_PARTY_NEW_MEMBER,
+ CPMSG_PARTY_MEMBER_LEFT,
+ 0
+ };
+ handledMessages = _messages;
+
+}
+
+void PartyHandler::handleMessage(MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case CPMSG_PARTY_INVITE_RESPONSE:
+ {
+ if (msg.readInt8() == ERRMSG_OK)
+ {
+
+ }
+ } break;
+
+ case CPMSG_PARTY_INVITED:
+ {
+ std::string inviter = msg.readString();
+ partyWindow->showPartyInvite(inviter);
+ } break;
+
+ case CPMSG_PARTY_ACCEPT_INVITE_RESPONSE:
+ {
+ if (msg.readInt8() == ERRMSG_OK)
+ {
+ player_node->setInParty(true);
+ localChatTab->chatLog("Joined party");
+ }
+ }
+
+ case CPMSG_PARTY_QUIT_RESPONSE:
+ {
+ if (msg.readInt8() == ERRMSG_OK)
+ {
+ player_node->setInParty(false);
+ }
+ } break;
+
+ case CPMSG_PARTY_NEW_MEMBER:
+ {
+ msg.readInt16(); // being id
+ std::string name = msg.readString();
+
+ localChatTab->chatLog(name + " joined the party");
+
+ if (!player_node->getInParty())
+ player_node->setInParty(true);
+
+ partyWindow->addPartyMember(name);
+ } break;
+
+ case CPMSG_PARTY_MEMBER_LEFT:
+ {
+ partyWindow->removePartyMember(msg.readString());
+ } break;
+ }
+}
diff --git a/src/net/tmwserv/partyhandler.h b/src/net/tmwserv/partyhandler.h
new file mode 100644
index 00000000..66e29b0d
--- /dev/null
+++ b/src/net/tmwserv/partyhandler.h
@@ -0,0 +1,38 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_TMWSERV_PARTYHANDLER_H
+#define NET_TMWSERV_PARTYHANDLER_H
+
+#include "net/messagehandler.h"
+
+#include <string>
+
+class PartyHandler : public MessageHandler
+{
+public:
+ PartyHandler();
+
+ void handleMessage(MessageIn &msg);
+};
+
+#endif
+
diff --git a/src/net/tmwserv/playerhandler.cpp b/src/net/tmwserv/playerhandler.cpp
new file mode 100644
index 00000000..863fcb65
--- /dev/null
+++ b/src/net/tmwserv/playerhandler.cpp
@@ -0,0 +1,329 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/playerhandler.h"
+
+#include "net/tmwserv/protocol.h"
+
+#include "net/messagein.h"
+
+#include "engine.h"
+#include "localplayer.h"
+#include "log.h"
+#include "particle.h"
+#include "npc.h"
+
+#include "gui/buy.h"
+#include "gui/chat.h"
+#include "gui/gui.h"
+#include "gui/npclistdialog.h"
+#include "gui/npc_text.h"
+#include "gui/ok_dialog.h"
+#include "gui/sell.h"
+#include "gui/skill.h"
+#include "gui/viewport.h"
+
+// TODO Move somewhere else
+OkDialog *weightNotice = NULL;
+OkDialog *deathNotice = NULL;
+
+extern NpcListDialog *npcListDialog;
+extern NpcTextDialog *npcTextDialog;
+extern BuyDialog *buyDialog;
+extern SellDialog *sellDialog;
+extern Window *buySellDialog;
+
+/* Max. distance we are willing to scroll after a teleport;
+ * everything beyond will reset the port hard.
+ */
+static const int MAP_TELEPORT_SCROLL_DISTANCE = 8 * 32;
+
+/**
+ * Listener used for handling the overweigth message.
+ */
+// TODO Move somewhere else
+namespace {
+ struct WeightListener : public gcn::ActionListener
+ {
+ void action(const gcn::ActionEvent &event)
+ {
+ weightNotice = NULL;
+ }
+ } weightListener;
+}
+
+/**
+ * Listener used for handling death message.
+ */
+// TODO Move somewhere else
+namespace {
+ struct DeathListener : public gcn::ActionListener
+ {
+ void action(const gcn::ActionEvent &event)
+ {
+ player_node->revive();
+ deathNotice = NULL;
+ npcListDialog->setVisible(false);
+ npcTextDialog->setVisible(false);
+ buyDialog->setVisible(false);
+ sellDialog->setVisible(false);
+#ifdef EATHENA_SUPPORT
+ buySellDialog->setVisible(false);
+#endif
+ current_npc = 0;
+ }
+ } deathListener;
+}
+
+PlayerHandler::PlayerHandler()
+{
+ static const Uint16 _messages[] = {
+ GPMSG_PLAYER_MAP_CHANGE,
+ GPMSG_PLAYER_SERVER_CHANGE,
+ GPMSG_PLAYER_ATTRIBUTE_CHANGE,
+ GPMSG_PLAYER_EXP_CHANGE,
+ GPMSG_LEVELUP,
+ GPMSG_LEVEL_PROGRESS,
+ GPMSG_RAISE_ATTRIBUTE_RESPONSE,
+ GPMSG_LOWER_ATTRIBUTE_RESPONSE,
+ 0
+ };
+ handledMessages = _messages;
+}
+
+void PlayerHandler::handleMessage(MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case GPMSG_PLAYER_MAP_CHANGE:
+ handleMapChangeMessage(msg);
+ break;
+
+ case GPMSG_PLAYER_SERVER_CHANGE:
+ { // TODO: Implement reconnecting to another game server
+ std::string token = msg.readString(32);
+ std::string address = msg.readString();
+ int port = msg.readInt16();
+ logger->log("Changing server to %s:%d", address.c_str(), port);
+ } break;
+
+ case GPMSG_PLAYER_ATTRIBUTE_CHANGE:
+ {
+ logger->log("ATTRIBUTE UPDATE:");
+ while (msg.getUnreadLength())
+ {
+ int stat = msg.readInt8();
+ int base = msg.readInt16();
+ int value = msg.readInt16();
+ logger->log("%d set to %d %d", stat, base, value);
+
+ if (stat == BASE_ATTR_HP)
+ {
+ player_node->setMaxHp(base);
+ player_node->setHp(value);
+ }
+ else if (stat < NB_CHARACTER_ATTRIBUTES)
+ {
+ if (stat >= CHAR_SKILL_BEGIN && stat < CHAR_SKILL_END
+ && player_node->getAttributeBase(stat) < base
+ && player_node->getAttributeBase(stat) > -1)
+ {
+ Particle* effect = particleEngine->addEffect("graphics/particles/skillup.particle.xml", 0, 0);
+ player_node->controlParticle(effect);
+ }
+
+ player_node->setAttributeBase(stat, base);
+ player_node->setAttributeEffective(stat, value);
+ }
+ else
+ {
+ logger->log("Warning: server wants to update unknown "
+ "attribute %d to %d", stat, value);
+ }
+ }
+ } break;
+
+ case GPMSG_PLAYER_EXP_CHANGE:
+ {
+ logger->log("EXP Update");
+ while (msg.getUnreadLength())
+ {
+ int skill = msg.readInt8();
+ int current = msg.readInt32();
+ int next = msg.readInt32();
+
+ if (skill < CHAR_SKILL_NB)
+ {
+ player_node->setExperience(skill, current, next);
+ }
+ else
+ {
+ logger->log("Warning: server wants to update experience of unknown "
+ "skill %d to %d / %d", skill, current, next);
+ }
+ }
+ } break;
+
+ case GPMSG_LEVELUP:
+ {
+ player_node->setLevel(msg.readInt16());
+ player_node->setCharacterPoints(msg.readInt16());
+ player_node->setCorrectionPoints(msg.readInt16());
+ Particle* effect = particleEngine->addEffect("graphics/particles/levelup.particle.xml", 0, 0);
+ player_node->controlParticle(effect);
+ } break;
+
+
+ case GPMSG_LEVEL_PROGRESS:
+ {
+ logger->log("Level Progress Update");
+ player_node->setLevelProgress(msg.readInt8());
+ } break;
+
+
+ case GPMSG_RAISE_ATTRIBUTE_RESPONSE:
+ {
+ int errCode = msg.readInt8();
+ int attrNum = msg.readInt8() - CHAR_ATTR_BEGIN;
+ switch (errCode)
+ {
+ case ATTRIBMOD_OK:
+ {
+ // feel(acknowledgment);
+ } break;
+ case ATTRIBMOD_INVALID_ATTRIBUTE:
+ {
+ logger->log("Warning: Server denied increase of attribute %d (unknown attribute) ", attrNum);
+ } break;
+ case ATTRIBMOD_NO_POINTS_LEFT:
+ {
+ // when the server says "you got no points" it
+ // has to be correct. The server is always right!
+ // undo attribute change and set points to 0
+ logger->log("Warning: Server denied increase of attribute %d (no points left) ", attrNum);
+ int attrValue = player_node->getAttributeBase(attrNum) - 1;
+ player_node->setCharacterPoints(0);
+ player_node->setAttributeBase(attrNum, attrValue);
+ } break;
+ case ATTRIBMOD_DENIED:
+ {
+ // undo attribute change
+ logger->log("Warning: Server denied increase of attribute %d (reason unknown) ", attrNum);
+ int points = player_node->getCharacterPoints() - 1;
+ player_node->setCharacterPoints(points);
+ int attrValue = player_node->getAttributeBase(attrNum) - 1;
+ player_node->setAttributeBase(attrNum, attrValue);
+ } break;
+ }
+ } break;
+
+ case GPMSG_LOWER_ATTRIBUTE_RESPONSE:
+ {
+ int errCode = msg.readInt8();
+ int attrNum = msg.readInt8() - CHAR_ATTR_BEGIN;
+ switch (errCode)
+ {
+ case ATTRIBMOD_OK:
+ {
+ // feel(acknowledgment);
+ } break;
+ case ATTRIBMOD_INVALID_ATTRIBUTE:
+ {
+ logger->log("Warning: Server denied reduction of attribute %d (unknown attribute) ", attrNum);
+ } break;
+ case ATTRIBMOD_NO_POINTS_LEFT:
+ {
+ // when the server says "you got no points" it
+ // has to be correct. The server is always right!
+ // undo attribute change and set points to 0
+ logger->log("Warning: Server denied reduction of attribute %d (no points left) ", attrNum);
+ int attrValue = player_node->getAttributeBase(attrNum) + 1;
+ player_node->setCorrectionPoints(0);
+ player_node->setAttributeBase(attrNum, attrValue);
+ break;
+ } break;
+ case ATTRIBMOD_DENIED:
+ {
+ // undo attribute change
+ logger->log("Warning: Server denied reduction of attribute %d (reason unknown) ", attrNum);
+ int charaPoints = player_node->getCharacterPoints() - 1;
+ player_node->setCharacterPoints(charaPoints);
+ int correctPoints = player_node->getCorrectionPoints() + 1;
+ player_node->setCorrectionPoints(correctPoints);
+ int attrValue = player_node->getAttributeBase(attrNum) + 1;
+ player_node->setAttributeBase(attrNum, attrValue);
+ } break;
+ }
+
+ } break;
+ /*
+ case SMSG_PLAYER_ARROW_MESSAGE:
+ {
+ Sint16 type = msg.readInt16();
+
+ switch (type) {
+ case 0:
+ localChatTab->chatLog("Equip arrows first",
+ BY_SERVER);
+ break;
+ default:
+ logger->log("0x013b: Unhandled message %i", type);
+ break;
+ }
+ }
+ break;
+ */
+ }
+}
+
+void PlayerHandler::handleMapChangeMessage(MessageIn &msg)
+{
+ const std::string mapName = msg.readString();
+ const unsigned short x = msg.readInt16();
+ const unsigned short y = msg.readInt16();
+ const bool nearby = (engine->getCurrentMapName() == mapName);
+
+ logger->log("Changing map to %s (%d, %d)", mapName.c_str(), x, y);
+
+ // Switch the actual map, deleting the previous one
+ engine->changeMap(mapName);
+
+ current_npc = 0;
+
+ const Vector &playerPos = player_node->getPosition();
+ float scrollOffsetX = 0.0f;
+ float scrollOffsetY = 0.0f;
+
+ /* Scroll if neccessary */
+ if (!nearby
+ || (abs(x - (int) playerPos.x) > MAP_TELEPORT_SCROLL_DISTANCE)
+ || (abs(y - (int) playerPos.y) > MAP_TELEPORT_SCROLL_DISTANCE)) {
+ scrollOffsetX = x - (int) playerPos.x;
+ scrollOffsetY = y - (int) playerPos.y;
+ }
+
+ player_node->setAction(Being::STAND);
+ player_node->setPosition(x, y);
+
+ logger->log("Adjust scrolling by %d,%d", (int) scrollOffsetX,
+ (int) scrollOffsetY);
+ viewport->scrollBy(scrollOffsetX, scrollOffsetY);
+}
diff --git a/src/net/tmwserv/playerhandler.h b/src/net/tmwserv/playerhandler.h
new file mode 100644
index 00000000..c8eacc38
--- /dev/null
+++ b/src/net/tmwserv/playerhandler.h
@@ -0,0 +1,38 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_TMWSERV_PLAYERHANDLER_H
+#define NET_TMWSERV_PLAYERHANDLER_H
+
+#include "net/messagehandler.h"
+
+class PlayerHandler : public MessageHandler
+{
+ public:
+ PlayerHandler();
+
+ void handleMessage(MessageIn &msg);
+
+ private:
+ void handleMapChangeMessage(MessageIn &msg);
+};
+
+#endif
diff --git a/src/net/tmwserv/protocol.h b/src/net/tmwserv/protocol.h
new file mode 100644
index 00000000..7eb0b931
--- /dev/null
+++ b/src/net/tmwserv/protocol.h
@@ -0,0 +1,295 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TMWSERV_PROTOCOL_H
+#define TMWSERV_PROTOCOL_H
+
+/**
+ * Enumerated type for communicated messages:
+ *
+ * - PAMSG_*: from client to account server
+ * - APMSG_*: from account server to client
+ * - PCMSG_*: from client to chat server
+ * - CPMSG_*: from chat server to client
+ * - PGMSG_*: from client to game server
+ * - GPMSG_*: from game server to client
+ *
+ * Components: B byte, W word, D double word, S variable-size string
+ * C tile-based coordinates (B*3)
+ *
+ * Hosts: P (player's client), A (account server), C (char server),
+ * G (game server)
+ */
+enum {
+ // Login/Register
+ PAMSG_REGISTER = 0x0000, // L version, S username, S password, S email
+ APMSG_REGISTER_RESPONSE = 0x0002, // B error [, S updatehost]
+ PAMSG_UNREGISTER = 0x0003, // -
+ APMSG_UNREGISTER_RESPONSE = 0x0004, // B error
+ PAMSG_LOGIN = 0x0010, // L version, S username, S password
+ APMSG_LOGIN_RESPONSE = 0x0012, // B error [, S updatehost]
+ PAMSG_LOGOUT = 0x0013, // -
+ APMSG_LOGOUT_RESPONSE = 0x0014, // B error
+ PAMSG_CHAR_CREATE = 0x0020, // S name, B hair style, B hair color, B gender, W*6 stats
+ APMSG_CHAR_CREATE_RESPONSE = 0x0021, // B error
+ PAMSG_CHAR_DELETE = 0x0022, // B index
+ APMSG_CHAR_DELETE_RESPONSE = 0x0023, // B error
+ APMSG_CHAR_INFO = 0x0024, // B index, S name, B gender, B hair style, B hair color, W level, W character points, W correction points, D money, W*6 stats
+ PAMSG_CHAR_SELECT = 0x0026, // B index
+ APMSG_CHAR_SELECT_RESPONSE = 0x0027, // B error, B*32 token, S game address, W game port, S chat address, W chat port
+ PAMSG_EMAIL_CHANGE = 0x0030, // S email
+ APMSG_EMAIL_CHANGE_RESPONSE = 0x0031, // B error
+ PAMSG_PASSWORD_CHANGE = 0x0034, // S old password, S new password
+ APMSG_PASSWORD_CHANGE_RESPONSE = 0x0035, // B error
+
+ PGMSG_CONNECT = 0x0050, // B*32 token
+ GPMSG_CONNECT_RESPONSE = 0x0051, // B error
+ PCMSG_CONNECT = 0x0053, // B*32 token
+ CPMSG_CONNECT_RESPONSE = 0x0054, // B error
+
+ PGMSG_DISCONNECT = 0x0060, // B reconnect account
+ GPMSG_DISCONNECT_RESPONSE = 0x0061, // B error, B*32 token
+ PCMSG_DISCONNECT = 0x0063, // -
+ CPMSG_DISCONNECT_RESPONSE = 0x0064, // B error
+
+ PAMSG_RECONNECT = 0x0065, // B*32 token
+ APMSG_RECONNECT_RESPONSE = 0x0066, // B error
+
+ // Game
+ GPMSG_PLAYER_MAP_CHANGE = 0x0100, // S filename, W x, W y
+ GPMSG_PLAYER_SERVER_CHANGE = 0x0101, // B*32 token, S game address, W game port
+ PGMSG_PICKUP = 0x0110, // W*2 position
+ PGMSG_DROP = 0x0111, // B slot, B amount
+ PGMSG_EQUIP = 0x0112, // B slot
+ PGMSG_UNEQUIP = 0x0113, // B slot
+ PGMSG_MOVE_ITEM = 0x0114, // B slot1, B slot2, B amount
+ GPMSG_INVENTORY = 0x0120, // { B slot, W item id [, B amount] }*
+ GPMSG_INVENTORY_FULL = 0x0121, // { B slot, W item id [, B amount] }*
+ GPMSG_PLAYER_ATTRIBUTE_CHANGE = 0x0130, // { B attribute, W base value, W modified value }*
+ GPMSG_PLAYER_EXP_CHANGE = 0x0140, // { B skill, D exp got, D exp needed }*
+ GPMSG_LEVELUP = 0x0150, // W new level
+ GPMSG_LEVEL_PROGRESS = 0x0151, // B percent completed to next levelup
+ PGMSG_RAISE_ATTRIBUTE = 0x0160, // B attribute
+ GPMSG_RAISE_ATTRIBUTE_RESPONSE = 0x0161, // B error, B attribute
+ PGMSG_LOWER_ATTRIBUTE = 0x0170, // B attribute
+ GPMSG_LOWER_ATTRIBUTE_RESPONSE = 0x0171, // B error, B attribute
+ PGMSG_RESPAWN = 0x0180, // -
+ GPMSG_BEING_ENTER = 0x0200, // B type, W being id, B action, W*2 position
+ // player: S name, B hair style, B hair color, B gender, B item bitmask, { W item id }*
+ // monster: W type id
+ // npc: W type id
+ GPMSG_BEING_LEAVE = 0x0201, // W being id
+ GPMSG_ITEM_APPEAR = 0x0202, // W item id, W*2 position
+ GPMSG_BEING_LOOKS_CHANGE = 0x0210, // W weapon, W hat, W top clothes, W bottom clothes
+ PGMSG_WALK = 0x0260, // W*2 destination
+ PGMSG_ACTION_CHANGE = 0x0270, // B Action
+ GPMSG_BEING_ACTION_CHANGE = 0x0271, // W being id, B action
+ PGMSG_DIRECTION_CHANGE = 0x0272, // B Direction
+ GPMSG_BEING_DIR_CHANGE = 0x0273, // W being id, B direction
+ GPMSG_BEINGS_MOVE = 0x0280, // { W being id, B flags [, C position, B speed] [, W*2 destination] }*
+ GPMSG_ITEMS = 0x0281, // { W item id, W*2 position }*
+ PGMSG_ATTACK = 0x0290, // B direction
+ PGMSG_USE_SPECIAL = 0x0292, // B specialID
+ GPMSG_BEING_ATTACK = 0x0291, // W being id
+ PGMSG_SAY = 0x02A0, // S text
+ GPMSG_SAY = 0x02A1, // W being id, S text
+ GPMSG_NPC_CHOICE = 0x02B0, // W being id, { S text }*
+ GPMSG_NPC_MESSAGE = 0x02B1, // W being id, B* text
+ PGMSG_NPC_TALK = 0x02B2, // W being id
+ PGMSG_NPC_TALK_NEXT = 0x02B3, // W being id
+ PGMSG_NPC_SELECT = 0x02B4, // W being id, B choice
+ GPMSG_NPC_BUY = 0x02B5, // W being id, { W item id, W amount, W cost }*
+ GPMSG_NPC_SELL = 0x02B6, // W being id, { W item id, W amount, W cost }*
+ PGMSG_NPC_BUYSELL = 0x02B7, // W item id, W amount
+ GPMSG_NPC_ERROR = 0x02B8, // B error
+ GPMSG_NPC_POST = 0x02D0, // W being id
+ PGMSG_NPC_POST_SEND = 0x02D1, // S name, S text, W item id
+ GPMSG_NPC_POST_GET = 0x02D2, // W being id, { S name, S text, W item id }
+ PGMSG_TRADE_REQUEST = 0x02C0, // W being id
+ GPMSG_TRADE_REQUEST = 0x02C1, // W being id
+ GPMSG_TRADE_START = 0x02C2, // -
+ GPMSG_TRADE_COMPLETE = 0x02C3, // -
+ PGMSG_TRADE_CANCEL = 0x02C4, // -
+ GPMSG_TRADE_CANCEL = 0x02C5, // -
+ PGMSG_TRADE_ACCEPT = 0x02C6, // -
+ GPMSG_TRADE_ACCEPT = 0x02C7, // -
+ PGMSG_TRADE_ADD_ITEM = 0x02C8, // B slot, B amount
+ GPMSG_TRADE_ADD_ITEM = 0x02C9, // W item id, B amount
+ PGMSG_TRADE_SET_MONEY = 0x02CA, // L amount
+ GPMSG_TRADE_SET_MONEY = 0x02CB, // L amount
+ PGMSG_USE_ITEM = 0x0300, // B slot
+ GPMSG_USE_RESPONSE = 0x0301, // B error
+ GPMSG_BEINGS_DAMAGE = 0x0310, // { W being id, W amount }*
+ GPMSG_CREATE_EFFECT = 0x0320, // W effect id, W*2 position
+
+ // Guild
+ PCMSG_GUILD_CREATE = 0x0350, // S name
+ CPMSG_GUILD_CREATE_RESPONSE = 0x0351, // B error, W guild, B rights, W channel
+ PCMSG_GUILD_INVITE = 0x0352, // W id, S name
+ CPMSG_GUILD_INVITE_RESPONSE = 0x0353, // B error
+ PCMSG_GUILD_ACCEPT = 0x0354, // W id
+ CPMSG_GUILD_ACCEPT_RESPONSE = 0x0355, // B error, W guild, B rights, W channel
+ PCMSG_GUILD_GET_MEMBERS = 0x0356, // W id
+ CPMSG_GUILD_GET_MEMBERS_RESPONSE = 0x0357, // S names, B online
+ CPMSG_GUILD_UPDATE_LIST = 0x0358, // W id, S name, B event
+ PCMSG_GUILD_QUIT = 0x0360, // W id
+ CPMSG_GUILD_QUIT_RESPONSE = 0x0361, // B error
+ PCMSG_GUILD_PROMOTE_MEMBER = 0x0365, // W guild, S name, B rights
+ CPMSG_GUILD_PROMOTE_MEMBER_RESPONSE = 0x0366, // B error
+
+ CPMSG_GUILD_INVITED = 0x0370, // S char name, S guild name, W id
+ CPMSG_GUILD_REJOIN = 0x0371, // S name, W guild, W rights, W channel, S announce
+
+ // Party
+ PCMSG_PARTY_INVITE = 0x03A0, // S name
+ CPMSG_PARTY_INVITE_RESPONSE = 0x03A1, // B error
+ CPMSG_PARTY_INVITED = 0x03A2, // S name
+ PCMSG_PARTY_ACCEPT_INVITE = 0x03A5, // S name
+ CPMSG_PARTY_ACCEPT_INVITE_RESPONSE = 0x03A6, // B error, { S name }
+ PCMSG_PARTY_QUIT = 0x03AA, // -
+ CPMSG_PARTY_QUIT_RESPONSE = 0x03AB, // B error
+ CPMSG_PARTY_NEW_MEMBER = 0x03B0, // W being id, S name
+ CPMSG_PARTY_MEMBER_LEFT = 0x03B1, // W being id
+
+ // Chat
+ CPMSG_ERROR = 0x0401, // B error
+ CPMSG_ANNOUNCEMENT = 0x0402, // S text
+ CPMSG_PRIVMSG = 0x0403, // S user, S text
+ CPMSG_PUBMSG = 0x0404, // W channel, S user, S text
+ PCMSG_CHAT = 0x0410, // S text, W channel
+ PCMSG_ANNOUNCE = 0x0411, // S text
+ PCMSG_PRIVMSG = 0x0412, // S user, S text
+ // -- Channeling
+ CPMSG_CHANNEL_EVENT = 0x0430, // W channel, B event, S info
+ PCMSG_ENTER_CHANNEL = 0x0440, // S channel, S password
+ CPMSG_ENTER_CHANNEL_RESPONSE = 0x0441, // B error, W id, S name, S topic, S userlist
+ PCMSG_QUIT_CHANNEL = 0x0443, // W channel id
+ CPMSG_QUIT_CHANNEL_RESPONSE = 0x0444, // B error, W channel id
+ PCMSG_LIST_CHANNELS = 0x0445, // -
+ CPMSG_LIST_CHANNELS_RESPONSE = 0x0446, // S names, W number of users
+ PCMSG_LIST_CHANNELUSERS = 0x0460, // S channel
+ CPMSG_LIST_CHANNELUSERS_RESPONSE = 0x0461, // S channel, { S user, B mode }
+ PCMSG_TOPIC_CHANGE = 0x0462, // W channel id, S topic
+ // -- User mode
+ PCMSG_USER_MODE = 0x0465, // W channel id, S name, B mode
+ PCMSG_KICK_USER = 0x0466, // W channel id, S name
+
+ XXMSG_INVALID = 0x7FFF
+};
+
+// Generic return values
+
+enum {
+ ERRMSG_OK = 0, // everything is fine
+ ERRMSG_FAILURE, // the action failed
+ ERRMSG_NO_LOGIN, // the user is not yet logged
+ ERRMSG_NO_CHARACTER_SELECTED, // the user needs a character
+ ERRMSG_INSUFFICIENT_RIGHTS, // the user is not privileged
+ ERRMSG_INVALID_ARGUMENT, // part of the received message was invalid
+ ERRMSG_EMAIL_ALREADY_EXISTS, // The Email Address already exists
+ ERRMSG_ALREADY_TAKEN, // name used was already taken
+ ERRMSG_SERVER_FULL, // the server is overloaded
+ ERRMSG_TIME_OUT // data failed to arrive in due time
+};
+
+// Login specific return values
+enum {
+ LOGIN_INVALID_VERSION = 0x40, // the user is using an incompatible protocol
+ LOGIN_SERVER_FULL // the server is overloaded
+};
+
+// Account register specific return values
+enum {
+ REGISTER_INVALID_VERSION = 0x40, // the user is using an incompatible protocol
+ REGISTER_EXISTS_USERNAME, // there already is an account with this username
+ REGISTER_EXISTS_EMAIL // there already is an account with this email address
+};
+
+// Character creation specific return values
+enum {
+ CREATE_INVALID_HAIRSTYLE = 0x40,
+ CREATE_INVALID_HAIRCOLOR,
+ CREATE_INVALID_GENDER,
+ CREATE_RAW_STATS_TOO_HIGH,
+ CREATE_RAW_STATS_TOO_LOW,
+ CREATE_RAW_STATS_EQUAL_TO_ZERO,
+ CREATE_EXISTS_NAME,
+ CREATE_TOO_MUCH_CHARACTERS
+};
+
+// Character attribute modification specific return value
+enum AttribmodResponseCode {
+ ATTRIBMOD_OK = ERRMSG_OK,
+ ATTRIBMOD_INVALID_ATTRIBUTE = 0x40,
+ ATTRIBMOD_NO_POINTS_LEFT,
+ ATTRIBMOD_DENIED
+};
+// Object type enumeration
+enum {
+ // A simple item
+ OBJECT_ITEM = 0,
+ // An item that can be activated (doors, switchs, sign, ...)
+ OBJECT_ACTOR,
+ // Non-Playable-Character is an actor capable of movement and maybe actions
+ OBJECT_NPC,
+ // A monster (moving actor with AI. able to toggle map/quest actions, too)
+ OBJECT_MONSTER,
+ // A player
+ OBJECT_PLAYER
+};
+
+// Moving object flags
+enum {
+ // Payload contains the current position.
+ MOVING_POSITION = 1,
+ // Payload contains the destination.
+ MOVING_DESTINATION = 2
+};
+
+// Email change specific return values
+enum {
+ EMAILCHG_EXISTS_EMAIL = 0x40
+};
+
+// Chat errors return values
+enum {
+ CHAT_USING_BAD_WORDS = 0x40,
+ CHAT_UNHANDLED_COMMAND
+};
+
+// Chat channels event values
+enum {
+ CHAT_EVENT_NEW_PLAYER = 0,
+ CHAT_EVENT_LEAVING_PLAYER,
+ CHAT_EVENT_TOPIC_CHANGE,
+ CHAT_EVENT_MODE_CHANGE,
+ CHAT_EVENT_KICKED_PLAYER
+};
+
+// Guild member event values
+enum {
+ GUILD_EVENT_NEW_PLAYER = 0,
+ GUILD_EVENT_LEAVING_PLAYER,
+ GUILD_EVENT_ONLINE_PLAYER,
+ GUILD_EVENT_OFFLINE_PLAYER
+};
+
+#endif
diff --git a/src/net/tmwserv/tradehandler.cpp b/src/net/tmwserv/tradehandler.cpp
new file mode 100644
index 00000000..85228355
--- /dev/null
+++ b/src/net/tmwserv/tradehandler.cpp
@@ -0,0 +1,137 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/tmwserv/tradehandler.h"
+
+#include "net/tmwserv/gameserver/player.h"
+#include "net/tmwserv/protocol.h"
+
+#include "net/messagein.h"
+
+#include "beingmanager.h"
+#include "item.h"
+#include "localplayer.h"
+
+#include "gui/chat.h"
+#include "gui/confirm_dialog.h"
+#include "gui/trade.h"
+
+std::string tradePartnerName;
+int tradePartnerID;
+
+/**
+ * Listener for request trade dialogs
+ */
+namespace {
+ struct RequestTradeListener : public gcn::ActionListener
+ {
+ void action(const gcn::ActionEvent &event)
+ {
+ if (event.getId() == "yes")
+ Net::GameServer::Player::requestTrade(tradePartnerID);
+ else
+ Net::GameServer::Player::acceptTrade(false);
+ }
+ } listener;
+}
+
+TradeHandler::TradeHandler():
+ mAcceptTradeRequests(true)
+{
+ static const Uint16 _messages[] = {
+ GPMSG_TRADE_REQUEST,
+ GPMSG_TRADE_CANCEL,
+ GPMSG_TRADE_START,
+ GPMSG_TRADE_COMPLETE,
+ GPMSG_TRADE_ACCEPT,
+ GPMSG_TRADE_ADD_ITEM,
+ GPMSG_TRADE_SET_MONEY,
+ 0
+ };
+ handledMessages = _messages;
+}
+
+void TradeHandler::setAcceptTradeRequests(bool acceptTradeRequests)
+{
+ mAcceptTradeRequests = acceptTradeRequests;
+ if (mAcceptTradeRequests) {
+ localChatTab->chatLog("Accepting incoming trade requests", BY_SERVER);
+ } else {
+ localChatTab->chatLog("Ignoring incoming trade requests", BY_SERVER);
+ }
+}
+
+void TradeHandler::handleMessage(MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case GPMSG_TRADE_REQUEST:
+ {
+ Being *being = beingManager->findBeing(msg.readInt16());
+ if (!being || !mAcceptTradeRequests)
+ {
+ Net::GameServer::Player::acceptTrade(false);
+ break;
+ }
+ player_node->setTrading(true);
+ tradePartnerName = being->getName();
+ tradePartnerID = being->getId();
+ ConfirmDialog *dlg = new ConfirmDialog("Request for trade",
+ tradePartnerName + " wants to trade with you, do you accept?");
+ dlg->addActionListener(&listener);
+ } break;
+
+ case GPMSG_TRADE_ADD_ITEM:
+ {
+ int type = msg.readInt16();
+ int amount = msg.readInt8();
+ tradeWindow->addItem(type, false, amount);
+ } break;
+
+ case GPMSG_TRADE_SET_MONEY:
+ tradeWindow->setMoney(msg.readInt32());
+ break;
+
+ case GPMSG_TRADE_START:
+ tradeWindow->reset();
+ tradeWindow->setCaption("Trading with " + tradePartnerName);
+ tradeWindow->setVisible(true);
+ break;
+
+ case GPMSG_TRADE_ACCEPT:
+ tradeWindow->receivedOk();
+ break;
+
+ case GPMSG_TRADE_CANCEL:
+ localChatTab->chatLog("Trade canceled.", BY_SERVER);
+ tradeWindow->setVisible(false);
+ tradeWindow->reset();
+ player_node->setTrading(false);
+ break;
+
+ case GPMSG_TRADE_COMPLETE:
+ localChatTab->chatLog("Trade completed.", BY_SERVER);
+ tradeWindow->setVisible(false);
+ tradeWindow->reset();
+ player_node->setTrading(false);
+ break;
+ }
+}
diff --git a/src/net/tmwserv/tradehandler.h b/src/net/tmwserv/tradehandler.h
new file mode 100644
index 00000000..a064bbce
--- /dev/null
+++ b/src/net/tmwserv/tradehandler.h
@@ -0,0 +1,53 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef NET_TMWSERV_TRADEHANDLER_H
+#define NET_TMWSERV_TRADEHANDLER_H
+
+#include "net/messagehandler.h"
+
+class TradeHandler : public MessageHandler
+{
+ public:
+ TradeHandler();
+
+ void handleMessage(MessageIn &msg);
+
+ /**
+ * Returns whether trade requests are accepted.
+ *
+ * @see setAcceptTradeRequests
+ */
+ bool acceptTradeRequests() const
+ { return mAcceptTradeRequests; }
+
+ /**
+ * Sets whether trade requests are accepted. When set to false, trade
+ * requests are automatically denied. When true, a popup will ask the
+ * player whether he wants to trade.
+ */
+ void setAcceptTradeRequests(bool acceptTradeRequests);
+
+ private:
+ bool mAcceptTradeRequests;
+};
+
+#endif
diff --git a/src/npc.cpp b/src/npc.cpp
index a6d60dbb..d0a1a523 100644
--- a/src/npc.cpp
+++ b/src/npc.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,19 +28,29 @@
#include "gui/npc_text.h"
#include "gui/palette.h"
+#ifdef TMWSERV_SUPPORT
+#include "net/tmwserv/gameserver/player.h"
+#else
#include "net/messageout.h"
-#include "net/protocol.h"
+#include "net/ea/protocol.h"
+#endif
#include "resources/npcdb.h"
-bool NPC::mTalking = false;
+bool NPC::isTalking = false;
int current_npc = 0;
static const int NAME_X_OFFSET = 15;
static const int NAME_Y_OFFSET = 30;
+#ifdef TMWSERV_SUPPORT
+NPC::NPC(Uint16 id, int job, Map *map):
+ Player(id, job, map)
+#else
NPC::NPC(int id, Uint16 job, Map *map, Network *network):
- Player(id, job, map), mNetwork(network)
+ Player(id, job, map),
+ mNetwork(network)
+#endif
{
NPCInfo info = NPCDB::get(job);
@@ -110,18 +119,37 @@ Being::Type NPC::getType() const
void NPC::talk()
{
- if (mTalking || !mNetwork)
+ if (isTalking)
+ return;
+
+ isTalking = true;
+
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::talkToNPC(mId, true);
+#else
+ if (!mNetwork)
return;
- mTalking = true;
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_NPC_TALK);
+ //outMsg.writeInt16(CMSG_NPC_TALK);
outMsg.writeInt32(mId);
outMsg.writeInt8(0);
+#endif
}
void NPC::updateCoords()
{
if (mName)
- mName->adviseXY(mPx + NAME_X_OFFSET, mPy + NAME_Y_OFFSET);
+ {
+#ifdef TMWSERV_SUPPORT
+ const Vector &pos = getPosition();
+ const int px = (int) pos.x + NAME_X_OFFSET;
+ const int py = (int) pos.y + NAME_Y_OFFSET;
+#else
+ const int px = mPx + NAME_X_OFFSET;
+ const int py = mPy + NAME_Y_OFFSET;
+#endif
+ mName->adviseXY(px, py);
+ }
}
diff --git a/src/npc.h b/src/npc.h
index 137cd5f5..fed03b51 100644
--- a/src/npc.h
+++ b/src/npc.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,14 +24,20 @@
#include "player.h"
+#ifdef EATHENA_SUPPORT
class Network;
+#endif
class Graphics;
class Text;
class NPC : public Player
{
public:
+#ifdef TMWSERV_SUPPORT
+ NPC(Uint16 id, int sprite, Map *map);
+#else
NPC(int id, Uint16 job, Map *map, Network *network);
+#endif
~NPC();
@@ -42,12 +47,25 @@ class NPC : public Player
virtual Type getType() const;
- void talk();;
+ void talk();
- static bool mTalking;
+ /**
+ * Gets the way an NPC is blocked by other things on the map
+ */
+ virtual unsigned char getWalkMask() const
+ { return 0x83; } // blocked like a monster by walls, monsters and characters ( bin 1000 0011)
+ static bool isTalking;
protected:
+ /**
+ * Gets the way a monster blocks pathfinding for other objects
+ */
+ virtual Map::BlockType getBlockType() const
+ { return Map::BLOCKTYPE_CHARACTER; } //blocks like a player character
+
+#ifdef EATHENA_SUPPORT
Network *mNetwork;
+#endif
void updateCoords();
private:
Text *mName;
diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp
index df8d264f..7a1d259e 100644
--- a/src/openglgraphics.cpp
+++ b/src/openglgraphics.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,12 +26,12 @@
#include "resources/image.h"
+#ifdef USE_OPENGL
+
#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#endif
-#ifdef USE_OPENGL
-
#ifndef GL_TEXTURE_RECTANGLE_ARB
#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
diff --git a/src/openglgraphics.h b/src/openglgraphics.h
index a7181420..469e1f53 100644
--- a/src/openglgraphics.h
+++ b/src/openglgraphics.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/particle.cpp b/src/particle.cpp
index 0e412ada..21844f01 100644
--- a/src/particle.cpp
+++ b/src/particle.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2006 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -250,7 +249,7 @@ void Particle::moveTo(float x, float y)
moveTo(Vector(x, y, mPos.z));
}
-Particle* Particle::addEffect(const std::string &particleEffectFile,
+Particle *Particle::addEffect(const std::string &particleEffectFile,
int pixelX, int pixelY, int rotation)
{
Particle *newParticle = NULL;
diff --git a/src/particle.h b/src/particle.h
index 76beb8d1..f3f5571a 100644
--- a/src/particle.h
+++ b/src/particle.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2006 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,8 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _PARTICLE_H
-#define _PARTICLE_H
+#ifndef PARTICLE_H
+#define PARTICLE_H
#include <list>
#include <string>
diff --git a/src/particlecontainer.cpp b/src/particlecontainer.cpp
index 0ebf4bc3..63f89079 100644
--- a/src/particlecontainer.cpp
+++ b/src/particlecontainer.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,15 +24,17 @@
#include "particle.h"
#include "particlecontainer.h"
-ParticleContainer::ParticleContainer(ParticleContainer *parent, bool delParent) :
+
+ParticleContainer::ParticleContainer(ParticleContainer *parent,
+ bool delParent):
mDelParent(delParent),
mNext(parent)
-{};
+{}
ParticleContainer::~ParticleContainer()
{
clearLocally();
- if (mNext && mDelParent)
+ if (mDelParent)
delete mNext;
}
@@ -52,10 +53,12 @@ void ParticleContainer::moveTo(float x, float y)
// -- particle list ----------------------------------------
-ParticleList::ParticleList(ParticleContainer *parent, bool delParent) :
- ParticleContainer(parent, delParent) {};
+ParticleList::ParticleList(ParticleContainer *parent, bool delParent):
+ ParticleContainer(parent, delParent)
+{}
-ParticleList::~ParticleList() {}
+ParticleList::~ParticleList()
+{}
void ParticleList::addLocally(Particle *particle)
{
@@ -71,10 +74,12 @@ void ParticleList::removeLocally(Particle *particle)
{
for (std::list<Particle *>::iterator it = mElements.begin();
it != mElements.end(); it++)
+ {
if (*it == particle) {
(*it)->kill();
mElements.erase(it);
}
+ }
}
void ParticleList::clearLocally()
@@ -82,7 +87,7 @@ void ParticleList::clearLocally()
for (std::list<Particle *>::iterator it = mElements.begin();
it != mElements.end(); it++)
(*it)->kill();
-
+
mElements.clear();
}
@@ -106,10 +111,12 @@ void ParticleList::moveTo(float x, float y)
// -- particle vector ----------------------------------------
-ParticleVector::ParticleVector(ParticleContainer *parent, bool delParent) :
- ParticleContainer(parent, delParent) {};
+ParticleVector::ParticleVector(ParticleContainer *parent, bool delParent):
+ ParticleContainer(parent, delParent)
+{}
-ParticleVector::~ParticleVector() {};
+ParticleVector::~ParticleVector()
+{}
void ParticleVector::setLocally(int index, Particle *particle)
{
@@ -120,6 +127,8 @@ void ParticleVector::setLocally(int index, Particle *particle)
if (mIndexedElements.size() <= (unsigned) index)
mIndexedElements.resize(index + 1, NULL);
+ if (particle)
+ particle->disableAutoDelete();
mIndexedElements[index] = particle;
}
@@ -149,7 +158,7 @@ void ParticleVector::moveTo(float x, float y)
ParticleContainer::moveTo(x, y);
for (std::vector<Particle *>::iterator it = mIndexedElements.begin();
- it != mIndexedElements.end(); it++)
+ it != mIndexedElements.end(); it++) {
if (*it)
{
(*it)->moveTo(x, y);
@@ -160,5 +169,6 @@ void ParticleVector::moveTo(float x, float y)
*it = NULL;
}
}
+ }
}
diff --git a/src/particlecontainer.h b/src/particlecontainer.h
index 1e2f8ff7..26539dd7 100644
--- a/src/particlecontainer.h
+++ b/src/particlecontainer.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -61,8 +60,8 @@ public:
virtual void moveTo(float x, float y);
protected:
- bool mDelParent; /**< Delete mNext in destructor */
- ParticleContainer *mNext; /**< Contained container, if any */
+ bool mDelParent; /**< Delete mNext in destructor */
+ ParticleContainer *mNext; /**< Contained container, if any */
};
/**
@@ -89,7 +88,7 @@ public:
virtual void moveTo(float x, float y);
protected:
- std::list<Particle *> mElements; /**< Contained particle effects */
+ std::list<Particle *> mElements; /**< Contained particle effects */
};
/**
diff --git a/src/particleemitter.cpp b/src/particleemitter.cpp
index 84c4c1ec..25e6ade5 100644
--- a/src/particleemitter.cpp
+++ b/src/particleemitter.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2006 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/particleemitter.h b/src/particleemitter.h
index 835f39c5..67b35ae2 100644
--- a/src/particleemitter.h
+++ b/src/particleemitter.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2006 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/particleemitterprop.h b/src/particleemitterprop.h
index e3817763..e68ac222 100644
--- a/src/particleemitterprop.h
+++ b/src/particleemitterprop.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2006 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/party.cpp b/src/party.cpp
index a4f1b940..51a86360 100644
--- a/src/party.cpp
+++ b/src/party.cpp
@@ -1,8 +1,8 @@
/*
- * Aethyra
- * Copyright 2008 Lloyd Bryant <lloyd_bryant@netzero.net>
+ * The Mana World
+ * Copyright (C) 2008 Lloyd Bryant <lloyd_bryant@netzero.net>
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,17 +23,17 @@
#include "localplayer.h"
#include "party.h"
+#include "gui/widgets/chattab.h"
#include "gui/chat.h"
#include "gui/confirm_dialog.h"
#include "net/messageout.h"
-#include "net/protocol.h"
+#include "net/ea/protocol.h"
#include "utils/gettext.h"
#include "utils/strprintf.h"
-Party::Party(ChatWindow *chat, Network *network) :
- mChat(chat),
+Party::Party(Network *network) :
mNetwork(network),
mInviteListener(network, &mInParty)
{
@@ -53,7 +53,7 @@ void Party::respond(const std::string &command, const std::string &args)
}
if (command == "settings")
{
- mChat->chatLog(_("Not yet implemented!"), BY_SERVER);
+ localChatTab->chatLog(_("Not yet implemented!"), BY_SERVER);
return;
/*
MessageOut outMsg(mNetwork);
@@ -62,14 +62,14 @@ void Party::respond(const std::string &command, const std::string &args)
outMsg.writeInt16(0); // Item
*/
}
- mChat->chatLog(_("Party command not known."), BY_SERVER);
+ localChatTab->chatLog(_("Party command not known."), BY_SERVER);
}
void Party::create(const std::string &party)
{
if (party.empty())
{
- mChat->chatLog(_("Party name is missing."), BY_SERVER);
+ localChatTab->chatLog(_("Party name is missing."), BY_SERVER);
return;
}
MessageOut outMsg(mNetwork);
@@ -82,7 +82,7 @@ void Party::leave(const std::string &args)
{
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_PARTY_LEAVE);
- mChat->chatLog(_("Left party."), BY_SERVER);
+ localChatTab->chatLog(_("Left party."), BY_SERVER);
mInParty = false;
}
@@ -90,12 +90,12 @@ void Party::createResponse(bool ok)
{
if (ok)
{
- mChat->chatLog(_("Party successfully created."), BY_SERVER);
+ localChatTab->chatLog(_("Party successfully created."), BY_SERVER);
mInParty = true;
}
else
{
- mChat->chatLog(_("Could not create party."), BY_SERVER);
+ localChatTab->chatLog(_("Could not create party."), BY_SERVER);
}
}
@@ -104,15 +104,15 @@ void Party::inviteResponse(const std::string &nick, int status)
switch (status)
{
case 0:
- mChat->chatLog(strprintf(_("%s is already a member of a party."),
+ localChatTab->chatLog(strprintf(_("%s is already a member of a party."),
nick.c_str()), BY_SERVER);
break;
case 1:
- mChat->chatLog(strprintf(_("%s refused your invitation."),
+ localChatTab->chatLog(strprintf(_("%s refused your invitation."),
nick.c_str()), BY_SERVER);
break;
case 2:
- mChat->chatLog(strprintf(_("%s is now a member of your party."),
+ localChatTab->chatLog(strprintf(_("%s is now a member of your party."),
nick.c_str()), BY_SERVER);
break;
}
@@ -124,7 +124,7 @@ void Party::invitedAsk(const std::string &nick, int gender,
mPartyName = partyName; /* Quick and nasty - needs redoing */
if (nick.empty())
{
- mChat->chatLog(_("You can\'t have a blank party name!"), BY_SERVER);
+ localChatTab->chatLog(_("You can\'t have a blank party name!"), BY_SERVER);
return;
}
mCreating = false;
@@ -147,7 +147,7 @@ void Party::InviteListener::action(const gcn::ActionEvent &event)
void Party::leftResponse(const std::string &nick)
{
- mChat->chatLog(strprintf(_("%s has left your party."), nick.c_str()),
+ localChatTab->chatLog(strprintf(_("%s has left your party."), nick.c_str()),
BY_SERVER);
}
@@ -159,47 +159,50 @@ void Party::receiveChat(Being *being, const std::string &msg)
}
if (being->getType() != Being::PLAYER)
{
- mChat->chatLog(_("Party chat received, but being is not a player"),
+ localChatTab->chatLog(_("Party chat received, but being is not a player"),
BY_SERVER);
return;
}
being->setSpeech(msg, SPEECH_TIME);
- mChat->chatLog(being->getName() + " : " + msg, BY_PARTY);
+ localChatTab->chatLog(being->getName() + " : " + msg, BY_PARTY);
}
-void Party::help(const std::string &msg)
+void Party::help(const std::string &args)
{
+ // Strip "party " from the front
+ std::string msg = args.substr(6, args.length());
+
if (msg.empty())
{
- mChat->chatLog(_("Command: /party <command> <args>"), BY_SERVER);
- mChat->chatLog(_("where <command> can be one of:"), BY_SERVER);
- mChat->chatLog(_(" /new"), BY_SERVER);
- mChat->chatLog(_(" /create"), BY_SERVER);
- mChat->chatLog(_(" /prefix"), BY_SERVER);
- mChat->chatLog(_(" /leave"), BY_SERVER);
- mChat->chatLog(_("This command implements the partying function."),
+ localChatTab->chatLog(_("Command: /party <command> <args>"), BY_SERVER);
+ localChatTab->chatLog(_("where <command> can be one of:"), BY_SERVER);
+ localChatTab->chatLog(_(" /new"), BY_SERVER);
+ localChatTab->chatLog(_(" /create"), BY_SERVER);
+ localChatTab->chatLog(_(" /prefix"), BY_SERVER);
+ localChatTab->chatLog(_(" /leave"), BY_SERVER);
+ localChatTab->chatLog(_("This command implements the partying function."),
BY_SERVER);
- mChat->chatLog(_("Type /help party <command> for further help."),
+ localChatTab->chatLog(_("Type /help party <command> for further help."),
BY_SERVER);
return;
}
if (msg == "new" || msg == "create")
{
- mChat->chatLog(_("Command: /party new <party-name>"), BY_SERVER);
- mChat->chatLog(_("Command: /party create <party-name>"), BY_SERVER);
- mChat->chatLog(_("These commands create a new party <party-name."),
+ localChatTab->chatLog(_("Command: /party new <party-name>"), BY_SERVER);
+ localChatTab->chatLog(_("Command: /party create <party-name>"), BY_SERVER);
+ localChatTab->chatLog(_("These commands create a new party <party-name."),
BY_SERVER);
return;
}
if (msg == "prefix")
{
- mChat->chatLog(_("Command: /party prefix <prefix-char>"), BY_SERVER);
- mChat->chatLog(_("This command sets the party prefix character."),
+ localChatTab->chatLog(_("Command: /party prefix <prefix-char>"), BY_SERVER);
+ localChatTab->chatLog(_("This command sets the party prefix character."),
BY_SERVER);
- mChat->chatLog(_("Any message preceded by <prefix-char> is sent to "
+ localChatTab->chatLog(_("Any message preceded by <prefix-char> is sent to "
"the party instead of everyone."), BY_SERVER);
- mChat->chatLog(_("Command: /party prefix"), BY_SERVER);
- mChat->chatLog(_("This command reports the current party prefix "
+ localChatTab->chatLog(_("Command: /party prefix"), BY_SERVER);
+ localChatTab->chatLog(_("This command reports the current party prefix "
"character."), BY_SERVER);
return;
}
@@ -207,11 +210,11 @@ void Party::help(const std::string &msg)
//if (msg == "info")
if (msg == "leave")
{
- mChat->chatLog(_("Command: /party leave"), BY_SERVER);
- mChat->chatLog(_("This command causes the player to leave the party."),
+ localChatTab->chatLog(_("Command: /party leave"), BY_SERVER);
+ localChatTab->chatLog(_("This command causes the player to leave the party."),
BY_SERVER);
return;
}
- mChat->chatLog(_("Unknown /party command."), BY_SERVER);
- mChat->chatLog(_("Type /help party for a list of options."), BY_SERVER);
+ localChatTab->chatLog(_("Unknown /party command."), BY_SERVER);
+ localChatTab->chatLog(_("Type /help party for a list of options."), BY_SERVER);
}
diff --git a/src/party.h b/src/party.h
index 0a19ae1d..d73b4a0f 100644
--- a/src/party.h
+++ b/src/party.h
@@ -1,8 +1,8 @@
/*
- * Aethyra
- * Copyright 2008 Lloyd Bryant <lloyd_bryant@netzero.net>
+ * The Mana World
+ * Copyright (C) 2008 Lloyd Bryant <lloyd_bryant@netzero.net>
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,7 +34,7 @@ class Network;
class Party
{
public:
- Party(ChatWindow *chat, Network *network);
+ Party(Network *network);
void respond(const std::string &command, const std::string &args);
void create(const std::string &party);
@@ -47,10 +47,9 @@ class Party
void leftResponse(const std::string &nick);
void receiveChat(Being *being, const std::string &msg);
- void help(const std::string &msg);
+ void help(const std::string &args);
private:
- ChatWindow *mChat;
std::string mPartyName;
Network *mNetwork;
bool mInParty;
@@ -73,4 +72,6 @@ class Party
InviteListener mInviteListener;
};
+extern Party *playerParty;
+
#endif
diff --git a/src/player.cpp b/src/player.cpp
index ba4ed1ff..de4a012b 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,6 +21,9 @@
#include "animatedsprite.h"
#include "game.h"
+#ifdef TMWSERV_SUPPORT
+#include "guild.h"
+#endif
#include "localplayer.h"
#include "particle.h"
#include "player.h"
@@ -31,6 +33,7 @@
#include "resources/colordb.h"
#include "resources/itemdb.h"
+#include "resources/iteminfo.h"
#include "utils/strprintf.h"
@@ -72,6 +75,7 @@ void Player::setName(const std::string &name)
}
}
+#ifdef EATHENA_SUPPORT
void Player::logic()
{
switch (mAction)
@@ -89,7 +93,7 @@ void Player::logic()
break;
case WALK:
- mFrame = (get_elapsed_time(mWalkTime) * 6) / mWalkSpeed;
+ mFrame = (get_elapsed_time(mWalkTime) * 6) / getWalkSpeed();
if (mFrame >= 6)
nextStep();
@@ -137,6 +141,7 @@ void Player::logic()
Being::logic();
}
+#endif
Being::Type Player::getType() const
{
@@ -183,7 +188,7 @@ void Player::setHairStyle(int style, int color)
setAction(mAction);
}
-void Player::setSprite(int slot, int id, std::string color)
+void Player::setSprite(int slot, int id, const std::string &color)
{
// id = 0 means unequip
if (id == 0)
@@ -191,8 +196,10 @@ void Player::setSprite(int slot, int id, std::string color)
delete mSprites[slot];
mSprites[slot] = NULL;
+#ifdef EATHENA_SUPPORT
if (slot == WEAPON_SPRITE)
mEquippedWeapon = NULL;
+#endif
}
else
{
@@ -229,3 +236,55 @@ void Player::updateCoords()
mName->adviseXY(mPx + NAME_X_OFFSET, mPy + NAME_Y_OFFSET);
}
+#ifdef TMWSERV_SUPPORT
+
+Guild* Player::addGuild(short guildId, short rights)
+{
+ Guild *guild = new Guild(guildId, rights);
+ mGuilds.insert(std::pair<int, Guild*>(guildId, guild));
+ return guild;
+}
+
+void Player::removeGuild(int id)
+{
+ mGuilds.erase(id);
+}
+
+Guild* Player::getGuild(const std::string &guildName)
+{
+ std::map<int, Guild*>::iterator itr, itr_end = mGuilds.end();
+ for (itr = mGuilds.begin(); itr != itr_end; ++itr)
+ {
+ Guild *guild = itr->second;
+ if (guild->getName() == guildName)
+ {
+ return guild;
+ }
+ }
+
+ return NULL;
+}
+
+Guild* Player::getGuild(int id)
+{
+ std::map<int, Guild*>::iterator itr;
+ itr = mGuilds.find(id);
+ if (itr != mGuilds.end())
+ {
+ return itr->second;
+ }
+
+ return NULL;
+}
+
+short Player::getNumberOfGuilds()
+{
+ return mGuilds.size();
+}
+
+void Player::setInParty(bool value)
+{
+ mInParty = value;
+}
+
+#endif
diff --git a/src/player.h b/src/player.h
index b815b829..1904c6d9 100644
--- a/src/player.h
+++ b/src/player.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,6 +27,9 @@
class FlashText;
class Graphics;
class Map;
+#ifdef TMWSERV_SUPPORT
+class Guild;
+#endif
/**
* A player being. Players have their name drawn beneath them. This class also
@@ -37,6 +39,9 @@ class Map;
class Player : public Being
{
public:
+ /**
+ * Constructor.
+ */
Player(int id, int job, Map *map);
~Player();
@@ -46,7 +51,9 @@ class Player : public Being
*/
virtual void setName(const std::string &name);
+#ifdef EATHENA_SUPPORT
virtual void logic();
+#endif
virtual Type getType() const;
@@ -67,17 +74,76 @@ class Player : public Being
/**
* Sets visible equipments for this player.
*/
- virtual void setSprite(int slot, int id, std::string color = "");
+ virtual void setSprite(int slot, int id, const std::string &color = "");
/**
* Flash the player's name
*/
void flash(int time);
+#ifdef TMWSERV_SUPPORT
+ /**
+ * Adds a guild to the player.
+ */
+ Guild* addGuild(short guildId, short rights);
+
+ /**
+ * Removers a guild from the player.
+ */
+ void removeGuild(int id);
+
+ /**
+ * Returns a pointer to the specified guild.
+ */
+ Guild* getGuild(const std::string &guildName);
+
+ /**
+ * Returns a pointer to the guild with matching id.
+ */
+ Guild* getGuild(int id);
+
+ /**
+ * Get number of guilds the player belongs to.
+ */
+ short getNumberOfGuilds();
+
+ /**
+ * Set the player in party
+ */
+ void setInParty(bool value);
+
+ /**
+ * Returns whether player is in the party
+ */
+ bool getInParty() const { return mInParty; }
+#endif
+
+ /**
+ * Gets the way the character is blocked by other objects.
+ */
+ virtual unsigned char getWalkMask() const
+ { return 0x82; } // blocked by walls and monsters (bin 1000 0010)
+
protected:
+ /**
+ * Gets the way the monster blocks pathfinding for other objects.
+ */
+ virtual Map::BlockType getBlockType() const
+ { return Map::BLOCKTYPE_CHARACTER; }
+
virtual void updateCoords();
+#ifdef TMWSERV_SUPPORT
+ // Character guild information
+ std::map<int, Guild*> mGuilds;
+#endif
+
FlashText *mName;
+
+#ifdef TMWSERV_SUPPORT
+ private:
+ bool mInParty;
+#endif
};
#endif
diff --git a/src/player_relations.cpp b/src/player_relations.cpp
index eec4153c..ef2ef1bc 100644
--- a/src/player_relations.cpp
+++ b/src/player_relations.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -352,8 +351,6 @@ private:
-static std::vector<PlayerIgnoreStrategy *> player_ignore_strategies;
-
std::vector<PlayerIgnoreStrategy *> *
PlayerRelationsManager::getPlayerIgnoreStrategies()
{
diff --git a/src/player_relations.h b/src/player_relations.h
index f4860e08..a6c6a115 100644
--- a/src/player_relations.h
+++ b/src/player_relations.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -95,7 +94,6 @@ class PlayerRelationsManager
{
public:
PlayerRelationsManager();
-
~PlayerRelationsManager();
/**
diff --git a/src/position.cpp b/src/position.cpp
index f370f27b..69d50476 100644
--- a/src/position.cpp
+++ b/src/position.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/position.h b/src/position.h
index 1c961c46..cbcf8c99 100644
--- a/src/position.h
+++ b/src/position.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/properties.h b/src/properties.h
index ad5af1d6..a2ce5b88 100644
--- a/src/properties.h
+++ b/src/properties.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -46,7 +45,8 @@ class Properties
* @return the value of the given property or the given default when it
* doesn't exist.
*/
- const std::string& getProperty(const std::string &name, const std::string &def = "") const
+ const std::string &getProperty(const std::string &name,
+ const std::string &def = "") const
{
PropertyMap::const_iterator i = mProperties.find(name);
return (i != mProperties.end()) ? i->second : def;
@@ -60,7 +60,7 @@ class Properties
* @return the value of the given property, or 0.0f when it doesn't
* exist.
*/
- float getFloatProperty(std::string const &name, float def = 0.0f) const
+ float getFloatProperty(const std::string &name, float def = 0.0f) const
{
PropertyMap::const_iterator i = mProperties.find(name);
float ret = def;
diff --git a/src/resources/action.cpp b/src/resources/action.cpp
index 27369def..7bd7c54f 100644
--- a/src/resources/action.cpp
+++ b/src/resources/action.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,10 +19,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "action.h"
-#include "animation.h"
+#include "resources/action.h"
-#include "../utils/dtor.h"
+#include "resources/animation.h"
+
+#include "utils/dtor.h"
Action::Action()
{
diff --git a/src/resources/action.h b/src/resources/action.h
index 8dde068c..387f1b14 100644
--- a/src/resources/action.h
+++ b/src/resources/action.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,19 +34,13 @@ class Animation;
class Action
{
public:
- /**
- * Constructor.
- */
Action();
- /**
- * Destructor.
- */
~Action();
void setAnimation(int direction, Animation *animation);
- Animation* getAnimation(int direction) const;
+ Animation *getAnimation(int direction) const;
protected:
typedef std::map<int, Animation*> Animations;
diff --git a/src/resources/ambientoverlay.cpp b/src/resources/ambientoverlay.cpp
index 9585f4f7..93c7c3e1 100644
--- a/src/resources/ambientoverlay.cpp
+++ b/src/resources/ambientoverlay.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,10 +19,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "ambientoverlay.h"
-#include "image.h"
+#include "resources/ambientoverlay.h"
-#include "../graphics.h"
+#include "resources/image.h"
+
+#include "graphics.h"
AmbientOverlay::AmbientOverlay(Image *img, float parallax,
float speedX, float speedY):
diff --git a/src/resources/ambientoverlay.h b/src/resources/ambientoverlay.h
index 142dfd2f..756d0eb7 100644
--- a/src/resources/ambientoverlay.h
+++ b/src/resources/ambientoverlay.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,17 +31,14 @@ class AmbientOverlay
/**
* Constructor.
*
- * @param img the image this overlay displays
- * @param parallax scroll factor based on camera position
- * @param speedX scrolling speed in x-direction
- * @param speedY scrolling speed in y-direction
+ * @param img the image this overlay displays
+ * @param parallax scroll factor based on camera position
+ * @param speedX scrolling speed in x-direction
+ * @param speedY scrolling speed in y-direction
*/
AmbientOverlay(Image *img, float parallax,
float speedX, float speedY);
- /**
- * Destructor.
- */
~AmbientOverlay();
void update(int timePassed, float dx, float dy);
diff --git a/src/resources/animation.cpp b/src/resources/animation.cpp
index 901f4f25..40a2687f 100644
--- a/src/resources/animation.cpp
+++ b/src/resources/animation.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,16 +19,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "animation.h"
+#include "resources/animation.h"
-#include "../utils/dtor.h"
+#include "utils/dtor.h"
Animation::Animation():
mDuration(0)
{
}
-void Animation::addFrame(Image *image, unsigned int delay, int offsetX, int offsetY)
+void Animation::addFrame(Image *image, unsigned int delay,
+ int offsetX, int offsetY)
{
Frame frame = { image, delay, offsetX, offsetY };
mFrames.push_back(frame);
diff --git a/src/resources/animation.h b/src/resources/animation.h
index bc8431c7..f309dbf8 100644
--- a/src/resources/animation.h
+++ b/src/resources/animation.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -47,15 +46,13 @@ struct Frame
class Animation
{
public:
- /**
- * Constructor.
- */
Animation();
/**
* Appends a new animation at the end of the sequence.
*/
- void addFrame(Image *image, unsigned int delay, int offsetX, int offsetY);
+ void addFrame(Image *image, unsigned int delay,
+ int offsetX, int offsetY);
/**
* Appends an animation terminator that states that the animation
@@ -66,7 +63,7 @@ class Animation
/**
* Returns the frame at the specified index.
*/
- Frame* getFrame(int index) { return &(mFrames[index]); }
+ Frame *getFrame(int index) { return &(mFrames[index]); }
/**
* Returns the length of this animation in frames.
diff --git a/src/resources/colordb.cpp b/src/resources/colordb.cpp
index c9252a8a..af498297 100644
--- a/src/resources/colordb.cpp
+++ b/src/resources/colordb.cpp
@@ -1,8 +1,8 @@
/*
- * Color Database
- * Copyright 2008 Aethyra Development Team
+ * Color database
+ * Copyright (C) 2008 Aethyra Development Team
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,17 +15,17 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <libxml/tree.h>
+#include "resources/colordb.h"
-#include "colordb.h"
+#include "log.h"
-#include "../log.h"
+#include "utils/xml.h"
-#include "../utils/xml.h"
+#include <libxml/tree.h>
#define HAIR_COLOR_FILE "colors.xml"
#define TMW_COLOR_FILE "hair.xml"
@@ -96,7 +96,7 @@ void ColorDB::unload()
mLoaded = false;
}
-std::string& ColorDB::get(int id)
+std::string &ColorDB::get(int id)
{
if (!mLoaded)
load();
diff --git a/src/resources/colordb.h b/src/resources/colordb.h
index d4568d54..92b63d77 100644
--- a/src/resources/colordb.h
+++ b/src/resources/colordb.h
@@ -1,8 +1,8 @@
/*
- * Color Database
- * Copyright 2008 Aethyra Development Team
+ * Color database
+ * Copyright (C) 2008 Aethyra Development Team
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,8 +15,8 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COLOR_MANAGER_H
@@ -26,7 +26,7 @@
#include <string>
/**
- * The class that holds the color information.
+ * Color information database.
*/
namespace ColorDB
{
@@ -40,13 +40,13 @@ namespace ColorDB
*/
void unload();
- std::string& get(int id);
+ std::string &get(int id);
int size();
// Color DB
typedef std::map<int, std::string> Colors;
typedef Colors::iterator ColorIterator;
-};
+}
#endif
diff --git a/src/resources/dye.cpp b/src/resources/dye.cpp
index 35a8ca89..aa4d6835 100644
--- a/src/resources/dye.cpp
+++ b/src/resources/dye.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,18 +19,22 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <sstream>
+#include "resources/dye.h"
-#include "dye.h"
+#include "log.h"
-#include "../log.h"
+#include <sstream>
DyePalette::DyePalette(const std::string &description)
{
int size = description.length();
- if (size == 0 || description[0] != '#')
+ if (size == 0)
+ return;
+ if (description[0] != '#')
+ {
// TODO: load palette from file.
return;
+ }
int pos = 1;
for (;;)
diff --git a/src/resources/dye.h b/src/resources/dye.h
index f39ba043..d0d010bc 100644
--- a/src/resources/dye.h
+++ b/src/resources/dye.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/resources/emotedb.cpp b/src/resources/emotedb.cpp
index ec87c5cd..3ee40f0e 100644
--- a/src/resources/emotedb.cpp
+++ b/src/resources/emotedb.cpp
@@ -1,8 +1,8 @@
/*
* Emote database
- * Copyright 2009 Aethyra Development Team
+ * Copyright (C) 2009 Aethyra Development Team
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,16 +15,16 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "emotedb.h"
+#include "resources/emotedb.h"
-#include "../animatedsprite.h"
-#include "../log.h"
+#include "animatedsprite.h"
+#include "log.h"
-#include "../utils/xml.h"
+#include "utils/xml.h"
namespace
{
@@ -138,13 +138,13 @@ const EmoteInfo *EmoteDB::get(int id)
}
}
-const AnimatedSprite* EmoteDB::getAnimation(int id)
+const AnimatedSprite *EmoteDB::getAnimation(int id)
{
const EmoteInfo *info = get(id);
return info->sprites.front()->sprite;
}
-const int& EmoteDB::getLast()
+const int &EmoteDB::getLast()
{
return mLastEmote;
}
diff --git a/src/resources/emotedb.h b/src/resources/emotedb.h
index 48e1d53c..375887d2 100644
--- a/src/resources/emotedb.h
+++ b/src/resources/emotedb.h
@@ -1,8 +1,8 @@
/*
* Emote database
- * Copyright 2009 Aethyra Development Team
+ * Copyright (C) 2009 Aethyra Development Team
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,8 +15,8 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EMOTE_DB_H
@@ -55,7 +55,7 @@ namespace EmoteDB
const AnimatedSprite *getAnimation(int id);
- const int& getLast();
+ const int &getLast();
typedef EmoteInfos::iterator EmoteInfosIterator;
}
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index cff40197..0c542a8b 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,13 +19,13 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <SDL_image.h>
+#include "resources/image.h"
+
+#include "resources/dye.h"
-#include "dye.h"
-#include "image.h"
+#include "log.h"
-#include "../log.h"
-#include "../position.h"
+#include <SDL_image.h>
#ifdef USE_OPENGL
bool Image::mUseOpenGL = false;
@@ -316,7 +315,7 @@ void Image::setAlpha(float a)
}
}
-Image* Image::merge(Image* image, const Position& pos)
+Image* Image::merge(Image *image, int x, int y)
{
SDL_Surface* surface = new SDL_Surface(*(image->mImage));
@@ -326,20 +325,20 @@ Image* Image::merge(Image* image, const Position& pos)
SDL_PixelFormat *current_fmt = mImage->format;
SDL_PixelFormat *surface_fmt = surface->format;
int current_offset, surface_offset;
- Position offset(0, 0);
+ int offset_x, offset_y;
SDL_LockSurface(surface);
SDL_LockSurface(mImage);
// for each pixel lines of a source image
- for (offset.x = (pos.x > 0 ? 0 : -pos.x); offset.x < image->getWidth() &&
- pos.x + offset.x < getWidth(); offset.x++)
+ for (offset_x = (x > 0 ? 0 : -x); offset_x < image->getWidth() &&
+ x + offset_x < getWidth(); offset_x++)
{
- for (offset.y = (pos.y > 0 ? 0 : -pos.y); offset.y < image->getHeight()
- && pos.y + offset.y < getHeight(); offset.y++)
+ for (offset_y = (y > 0 ? 0 : -y); offset_y < image->getHeight()
+ && y + offset_y < getHeight(); offset_y++)
{
// Computing offset on both images
- current_offset = (pos.y + offset.y) * getWidth() + pos.x + offset.x;
- surface_offset = offset.y * surface->w + offset.x;
+ current_offset = (y + offset_y) * getWidth() + x + offset_x;
+ surface_offset = offset_y * surface->w + offset_x;
// Retrieving a pixel to merge
surface_pix = ((Uint32*) surface->pixels)[surface_offset];
@@ -386,12 +385,12 @@ Image* Image::merge(Image* image, const Position& pos)
SDL_UnlockSurface(surface);
SDL_UnlockSurface(mImage);
- Image* newImage = new Image(surface);
+ Image *newImage = new Image(surface);
return newImage;
}
-float Image::getAlpha()
+float Image::getAlpha() const
{
return mAlpha;
}
diff --git a/src/resources/image.h b/src/resources/image.h
index f6b77f26..3cfb9216 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,9 +22,11 @@
#ifndef IMAGE_H
#define IMAGE_H
-#include <SDL.h>
+#include "main.h"
+
+#include "resources/resource.h"
-#include "../main.h"
+#include <SDL.h>
#ifdef USE_OPENGL
@@ -38,12 +39,8 @@
#include <SDL_opengl.h>
#endif
-#include "resource.h"
-
class Dye;
class Position;
-class SDL_Rect;
-class SDL_Surface;
/**
* Defines a class for loading and storing images.
@@ -123,7 +120,7 @@ class Image : public Resource
/**
* Returns the alpha value of this image.
*/
- float getAlpha();
+ float getAlpha() const;
#ifdef USE_OPENGL
/**
@@ -140,7 +137,7 @@ class Image : public Resource
* improve overall framerates. Don't use unless you are using it to
* reduce the number of overall layers that need to be drawn through SDL.
*/
- Image* merge(Image* image, const Position& pos);
+ Image *merge(Image *image, int x, int y);
protected:
/**
diff --git a/src/resources/imageloader.cpp b/src/resources/imageloader.cpp
index fe420e89..694c57af 100644
--- a/src/resources/imageloader.cpp
+++ b/src/resources/imageloader.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,14 +19,15 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <cassert>
+#include "resources/imageloader.h"
+
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
#include <guichan/color.hpp>
#include <guichan/sdl/sdlpixel.hpp>
-#include "image.h"
-#include "imageloader.h"
-#include "resourcemanager.h"
+#include <cassert>
ProxyImage::ProxyImage(SDL_Surface *s):
mImage(NULL), mSDLImage(s)
@@ -88,7 +88,7 @@ void ProxyImage::convertToDisplayFormat()
mSDLImage = NULL;
}
-gcn::Image *ImageLoader::load(std::string const &filename, bool convert)
+gcn::Image *ImageLoader::load(const std::string &filename, bool convert)
{
ResourceManager *resman = ResourceManager::getInstance();
ProxyImage *i = new ProxyImage(resman->loadSDLSurface(filename));
diff --git a/src/resources/imageloader.h b/src/resources/imageloader.h
index 2695b99c..d3207715 100644
--- a/src/resources/imageloader.h
+++ b/src/resources/imageloader.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,11 +22,11 @@
#ifndef IMAGELOADER_H
#define IMAGELOADER_H
-#include <string>
-
#include <guichan/image.hpp>
#include <guichan/imageloader.hpp>
+#include <string>
+
class Image;
struct SDL_Surface;
@@ -36,6 +35,7 @@ class ProxyImage : public gcn::Image
public:
ProxyImage(SDL_Surface *);
~ProxyImage();
+
void free();
int getWidth() const;
int getHeight() const;
@@ -62,7 +62,8 @@ class ProxyImage : public gcn::Image
class ImageLoader : public gcn::ImageLoader
{
public:
- gcn::Image *load(std::string const &filename, bool convertToDisplayFormat);
+ gcn::Image *load(const std::string &filename,
+ bool convertToDisplayFormat);
};
#endif
diff --git a/src/resources/imageset.cpp b/src/resources/imageset.cpp
index 33be1573..0c836134 100644
--- a/src/resources/imageset.cpp
+++ b/src/resources/imageset.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,12 +19,13 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "image.h"
-#include "imageset.h"
+#include "resources/imageset.h"
-#include "../log.h"
+#include "resources/image.h"
-#include "../utils/dtor.h"
+#include "log.h"
+
+#include "utils/dtor.h"
ImageSet::ImageSet(Image *img, int width, int height)
{
diff --git a/src/resources/imageset.h b/src/resources/imageset.h
index ad209aaf..f4464017 100644
--- a/src/resources/imageset.h
+++ b/src/resources/imageset.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,9 +22,9 @@
#ifndef IMAGESET_H
#define IMAGESET_H
-#include <vector>
+#include "resources/resource.h"
-#include "resource.h"
+#include <vector>
class Image;
@@ -35,7 +34,7 @@ class Image;
class ImageSet : public Resource
{
public:
- /*
+ /**
* Cuts the passed image in a grid of sub images.
*/
ImageSet(Image *img, int w, int h);
@@ -48,12 +47,12 @@ class ImageSet : public Resource
/**
* Returns the width of the images in the image set.
*/
- int getWidth() const { return mWidth; };
+ int getWidth() const { return mWidth; }
/**
* Returns the height of the images in the image set.
*/
- int getHeight() const { return mHeight; };
+ int getHeight() const { return mHeight; }
typedef std::vector<Image*>::size_type size_type;
Image* get(size_type i) const;
diff --git a/src/resources/imagewriter.cpp b/src/resources/imagewriter.cpp
index 854753c1..097e0c05 100644
--- a/src/resources/imagewriter.cpp
+++ b/src/resources/imagewriter.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,14 +19,14 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "resources/imagewriter.h"
+
+#include "log.h"
+
#include <png.h>
#include <SDL.h>
#include <string>
-#include "imagewriter.h"
-
-#include "../log.h"
-
bool ImageWriter::writePNG(SDL_Surface *surface, const std::string &filename)
{
// TODO Maybe someone can make this look nice?
diff --git a/src/resources/imagewriter.h b/src/resources/imagewriter.h
index c69eb2d3..a9133846 100644
--- a/src/resources/imagewriter.h
+++ b/src/resources/imagewriter.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,6 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <iosfwd>
+
struct SDL_Surface;
class ImageWriter
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
index 49913300..db919b64 100644
--- a/src/resources/itemdb.cpp
+++ b/src/resources/itemdb.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,18 +19,22 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <cassert>
+#include "resources/itemdb.h"
-#include <libxml/tree.h>
+#include "resources/iteminfo.h"
+#include "resources/resourcemanager.h"
-#include "itemdb.h"
+#include "log.h"
-#include "../log.h"
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/strprintf.h"
+#include "utils/stringutils.h"
+#include "utils/xml.h"
-#include "../utils/dtor.h"
-#include "../utils/gettext.h"
-#include "../utils/stringutils.h"
-#include "../utils/xml.h"
+#include <libxml/tree.h>
+
+#include <cassert>
namespace
{
@@ -45,6 +48,48 @@ namespace
static void loadSpriteRef(ItemInfo *itemInfo, xmlNodePtr node);
static void loadSoundRef(ItemInfo *itemInfo, xmlNodePtr node);
+static char const *const fields[][2] =
+{
+ { "attack", N_("Attack %+d") },
+ { "defense", N_("Defense %+d") },
+ { "hp", N_("HP %+d") },
+ { "mp", N_("MP %+d") }
+};
+
+static ItemType itemTypeFromString(const std::string &name, int id = 0)
+{
+ if (name=="generic") return ITEM_UNUSABLE;
+ else if (name=="usable") return ITEM_USABLE;
+ else if (name=="equip-1hand") return ITEM_EQUIPMENT_ONE_HAND_WEAPON;
+ else if (name=="equip-2hand") return ITEM_EQUIPMENT_TWO_HANDS_WEAPON;
+ else if (name=="equip-torso") return ITEM_EQUIPMENT_TORSO;
+ else if (name=="equip-arms") return ITEM_EQUIPMENT_ARMS;
+ else if (name=="equip-head") return ITEM_EQUIPMENT_HEAD;
+ else if (name=="equip-legs") return ITEM_EQUIPMENT_LEGS;
+ else if (name=="equip-shield") return ITEM_EQUIPMENT_SHIELD;
+ else if (name=="equip-ring") return ITEM_EQUIPMENT_RING;
+ else if (name=="equip-necklace") return ITEM_EQUIPMENT_NECKLACE;
+ else if (name=="equip-feet") return ITEM_EQUIPMENT_FEET;
+ else if (name=="equip-ammo") return ITEM_EQUIPMENT_AMMO;
+ else return ITEM_UNUSABLE;
+}
+
+static WeaponType weaponTypeFromString(const std::string &name, int id = 0)
+{
+ if (name=="knife") return WPNTYPE_KNIFE;
+ else if (name=="sword") return WPNTYPE_SWORD;
+ else if (name=="polearm") return WPNTYPE_POLEARM;
+ else if (name=="staff") return WPNTYPE_STAFF;
+ else if (name=="whip") return WPNTYPE_WHIP;
+ else if (name=="bow") return WPNTYPE_BOW;
+ else if (name=="shooting") return WPNTYPE_SHOOTING;
+ else if (name=="mace") return WPNTYPE_MACE;
+ else if (name=="axe") return WPNTYPE_AXE;
+ else if (name=="thrown") return WPNTYPE_THROWN;
+
+ else return WPNTYPE_NONE;
+}
+
void ItemDB::load()
{
if (mLoaded)
@@ -52,7 +97,7 @@ void ItemDB::load()
logger->log("Initializing item database...");
- mUnknown = new ItemInfo();
+ mUnknown = new ItemInfo;
mUnknown->setName(_("Unknown item"));
mUnknown->setImageName("");
mUnknown->setSprite("error.xml", GENDER_MALE);
@@ -83,61 +128,81 @@ void ItemDB::load()
logger->log("ItemDB: Redefinition of item ID %d", id);
}
- std::string type = XML::getProperty(node, "type", "other");
+ std::string typeStr = XML::getProperty(node, "type", "other");
int weight = XML::getProperty(node, "weight", 0);
int view = XML::getProperty(node, "view", 0);
std::string name = XML::getProperty(node, "name", "");
std::string image = XML::getProperty(node, "image", "");
std::string description = XML::getProperty(node, "description", "");
- std::string effect = XML::getProperty(node, "effect", "");
+#ifdef TMWSERV_SUPPORT
+ int weaponType = weaponTypeFromString(XML::getProperty(node, "weapon-type", ""));
+#else
int weaponType = XML::getProperty(node, "weapon_type", 0);
+#endif
+ int attackRange = XML::getProperty(node, "attack-range", 0);
+
+ ItemInfo *itemInfo = new ItemInfo;
+ itemInfo->setId(id);
+ itemInfo->setImageName(image);
+ itemInfo->setName(name.empty() ? _("Unnamed") : name);
+ itemInfo->setDescription(description);
+#ifdef TMWSERV_SUPPORT
+ int type = itemTypeFromString(typeStr);
+ itemInfo->setType(type);
+#else
+ itemInfo->setType(typeStr);
+#endif
+ itemInfo->setView(view);
+ itemInfo->setWeight(weight);
+ itemInfo->setWeaponType(weaponType);
+ itemInfo->setAttackRange(attackRange);
+
+#ifdef TMWSERV_SUPPORT
+ std::string effect;
+ for (int i = 0; i < int(sizeof(fields) / sizeof(fields[0])); ++i)
+ {
+ int value = XML::getProperty(node, fields[i][0], 0);
+ if (!value) continue;
+ if (!effect.empty()) effect += " / ";
+ effect += strprintf(gettext(fields[i][1]), value);
+ }
+#else
+ std::string effect = XML::getProperty(node, "effect", "");
+#endif
+ itemInfo->setEffect(effect);
- if (id)
+
+ for_each_xml_child_node(itemChild, node)
{
- ItemInfo *itemInfo = new ItemInfo;
- itemInfo->setId(id);
- itemInfo->setImageName(image);
- itemInfo->setName(name.empty() ? _("Unnamed") : name);
- itemInfo->setDescription(description);
- itemInfo->setEffect(effect);
- itemInfo->setType(type);
- itemInfo->setView(view);
- itemInfo->setWeight(weight);
- itemInfo->setWeaponType(weaponType);
-
- for_each_xml_child_node(itemChild, node)
+ if (xmlStrEqual(itemChild->name, BAD_CAST "sprite"))
{
- if (xmlStrEqual(itemChild->name, BAD_CAST "sprite"))
- {
- std::string attackParticle = XML::getProperty(
- itemChild, "particle-effect", "");
- itemInfo->setParticleEffect(attackParticle);
-
- loadSpriteRef(itemInfo, itemChild);
- }
- else if (xmlStrEqual(itemChild->name, BAD_CAST "sound"))
- {
- loadSoundRef(itemInfo, itemChild);
- }
+ std::string attackParticle = XML::getProperty(
+ itemChild, "particle-effect", "");
+ itemInfo->setParticleEffect(attackParticle);
+
+ loadSpriteRef(itemInfo, itemChild);
}
+ else if (xmlStrEqual(itemChild->name, BAD_CAST "sound"))
+ {
+ loadSoundRef(itemInfo, itemChild);
+ }
+ }
+
+ mItemInfos[id] = itemInfo;
+ if (!name.empty())
+ {
+ std::string temp = name;
+ toLower(trim(temp));
- mItemInfos[id] = itemInfo;
- if (!name.empty())
+ NamedItemInfoIterator itr = mNamedItemInfos.find(temp);
+ if (itr == mNamedItemInfos.end())
+ {
+ mNamedItemInfos[temp] = itemInfo;
+ }
+ else
{
- std::string temp = name;
- toLower(trim(temp));
-
- NamedItemInfoIterator itr = mNamedItemInfos.find(temp);
- if (itr == mNamedItemInfos.end())
- {
- mNamedItemInfos[temp] = itemInfo;
- }
- else
- {
- logger->log("ItemDB: Duplicate name of item found item %d",
- id);
- }
+ logger->log("ItemDB: Duplicate name of item found item %d", id);
}
}
diff --git a/src/resources/itemdb.h b/src/resources/itemdb.h
index 1e55f146..aa5edab5 100644
--- a/src/resources/itemdb.h
+++ b/src/resources/itemdb.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,13 +23,12 @@
#define ITEM_MANAGER_H
#include <map>
-
-#include "iteminfo.h"
+#include <string>
class ItemInfo;
/**
- * The namespace that holds the item information.
+ * Item information database.
*/
namespace ItemDB
{
@@ -44,8 +42,8 @@ namespace ItemDB
*/
void unload();
- const ItemInfo& get(int id);
- const ItemInfo& get(const std::string &name);
+ const ItemInfo &get(int id);
+ const ItemInfo &get(const std::string &name);
// Items database
typedef std::map<int, ItemInfo*> ItemInfos;
diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp
index 8dcb1c32..63b0c00e 100644
--- a/src/resources/iteminfo.cpp
+++ b/src/resources/iteminfo.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,10 +19,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "itemdb.h"
-#include "iteminfo.h"
+#include "resources/iteminfo.h"
-const std::string& ItemInfo::getSprite(Gender gender) const
+#include "resources/itemdb.h"
+
+const std::string &ItemInfo::getSprite(Gender gender) const
{
if (mView)
{
@@ -45,6 +45,26 @@ void ItemInfo::setWeaponType(int type)
// See server item.hpp file for type values.
switch (type)
{
+#ifdef TMWSERV_SUPPORT
+ case WPNTYPE_NONE:
+ mAttackType = ACTION_DEFAULT;
+ break;
+ case WPNTYPE_KNIFE:
+ case WPNTYPE_SWORD:
+ mAttackType = ACTION_ATTACK_STAB;
+ break;
+ case WPNTYPE_THROWN:
+ mAttackType = ACTION_ATTACK_THROW;
+ break;
+ case WPNTYPE_BOW:
+ mAttackType = ACTION_ATTACK_BOW;
+ break;
+ case WPNTYPE_POLEARM:
+ mAttackType = ACTION_ATTACK_SWING;
+ break;
+ default:
+ mAttackType = ACTION_ATTACK;
+#else
case 0: // none
mAttackType = ACTION_DEFAULT;
break;
@@ -63,6 +83,7 @@ void ItemInfo::setWeaponType(int type)
break;
default:
mAttackType = ACTION_ATTACK;
+#endif
}
}
@@ -71,7 +92,7 @@ void ItemInfo::addSound(EquipmentSoundEvent event, const std::string &filename)
mSounds[event].push_back("sfx/" + filename);
}
-const std::string& ItemInfo::getSound(EquipmentSoundEvent event) const
+const std::string &ItemInfo::getSound(EquipmentSoundEvent event) const
{
static const std::string empty;
std::map< EquipmentSoundEvent, std::vector<std::string> >::const_iterator i;
diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h
index 0ea59050..bcee1fbd 100644
--- a/src/resources/iteminfo.h
+++ b/src/resources/iteminfo.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,20 +22,88 @@
#ifndef ITEMINFO_H
#define ITEMINFO_H
+#include "resources/spritedef.h"
+
+#include "being.h"
+
#include <map>
#include <string>
#include <vector>
-#include "spritedef.h"
-
-#include "../being.h"
-
enum EquipmentSoundEvent
{
EQUIP_EVENT_STRIKE,
EQUIP_EVENT_HIT
};
+enum EquipmentSlot
+{
+ // Equipment rules:
+ // 1 Brest equipment
+ EQUIP_TORSO_SLOT = 0,
+ // 1 arms equipment
+ EQUIP_ARMS_SLOT = 1,
+ // 1 head equipment
+ EQUIP_HEAD_SLOT = 2,
+ // 1 legs equipment
+ EQUIP_LEGS_SLOT = 3,
+ // 1 feet equipment
+ EQUIP_FEET_SLOT = 4,
+ // 2 rings
+ EQUIP_RING1_SLOT = 5,
+ EQUIP_RING2_SLOT = 6,
+ // 1 necklace
+ EQUIP_NECKLACE_SLOT = 7,
+ // Fight:
+ // 2 one-handed weapons
+ // or 1 two-handed weapon
+ // or 1 one-handed weapon + 1 shield.
+ EQUIP_FIGHT1_SLOT = 8,
+ EQUIP_FIGHT2_SLOT = 9,
+ // Projectile:
+ // this item does not amount to one, it only indicates the chosen projectile.
+ EQUIP_PROJECTILE_SLOT = 10
+};
+
+
+/**
+ * Enumeration of available Item types.
+ */
+enum ItemType
+{
+ ITEM_UNUSABLE = 0,
+ ITEM_USABLE, // 1
+ ITEM_EQUIPMENT_ONE_HAND_WEAPON, // 2
+ ITEM_EQUIPMENT_TWO_HANDS_WEAPON,// 3
+ ITEM_EQUIPMENT_TORSO,// 4
+ ITEM_EQUIPMENT_ARMS,// 5
+ ITEM_EQUIPMENT_HEAD,// 6
+ ITEM_EQUIPMENT_LEGS,// 7
+ ITEM_EQUIPMENT_SHIELD,// 8
+ ITEM_EQUIPMENT_RING,// 9
+ ITEM_EQUIPMENT_NECKLACE,// 10
+ ITEM_EQUIPMENT_FEET,// 11
+ ITEM_EQUIPMENT_AMMO// 12
+};
+
+/**
+ * Enumeration of available weapon's types.
+ */
+enum WeaponType
+{
+ WPNTYPE_NONE = 0,
+ WPNTYPE_KNIFE,
+ WPNTYPE_SWORD,
+ WPNTYPE_POLEARM,
+ WPNTYPE_STAFF,
+ WPNTYPE_WHIP,
+ WPNTYPE_BOW,
+ WPNTYPE_SHOOTING,
+ WPNTYPE_MACE,
+ WPNTYPE_AXE,
+ WPNTYPE_THROWN
+};
+
/**
* Defines a class for storing item infos. This includes information used when
* the item is equipped.
@@ -48,7 +115,9 @@ class ItemInfo
* Constructor.
*/
ItemInfo():
- mType(""),
+#ifdef TMWSERV_SUPPORT
+ mType(ITEM_UNUSABLE),
+#endif
mWeight(0),
mView(0),
mAttackType(ACTION_DEFAULT)
@@ -64,7 +133,7 @@ class ItemInfo
void setName(const std::string &name)
{ mName = name; }
- const std::string& getName() const
+ const std::string &getName() const
{ return mName; }
void setParticleEffect(const std::string &particleEffect)
@@ -75,24 +144,32 @@ class ItemInfo
void setImageName(const std::string &imageName)
{ mImageName = imageName; }
- const std::string& getImageName() const
+ const std::string &getImageName() const
{ return mImageName; }
void setDescription(const std::string &description)
{ mDescription = description; }
- const std::string& getDescription() const
+ const std::string &getDescription() const
{ return mDescription; }
void setEffect(const std::string &effect)
{ mEffect = effect; }
- const std::string& getEffect() const { return mEffect; }
+ const std::string &getEffect() const { return mEffect; }
- void setType(const std::string& type)
+#ifdef TMWSERV_SUPPORT
+ void setType(short type)
{ mType = type; }
- const std::string& getType() const { return mType; }
+ short getType() const
+ { return mType; }
+#else
+ void setType(const std::string &type)
+ { mType = type; }
+
+ const std::string &getType() const { return mType; }
+#endif
void setWeight(short weight)
{ mWeight = weight; }
@@ -106,23 +183,33 @@ class ItemInfo
void setSprite(const std::string &animationFile, Gender gender)
{ mAnimationFiles[gender] = animationFile; }
- const std::string& getSprite(Gender gender) const;
+ const std::string &getSprite(Gender gender) const;
void setWeaponType(int);
SpriteAction getAttackType() const
{ return mAttackType; }
+ int getAttackRange() const
+ { return mAttackRange; }
+
+ void setAttackRange(int r)
+ { mAttackRange = r; }
+
void addSound(EquipmentSoundEvent event, const std::string &filename);
- const std::string& getSound(EquipmentSoundEvent event) const;
+ const std::string &getSound(EquipmentSoundEvent event) const;
protected:
std::string mImageName; /**< The filename of the icon image. */
std::string mName;
std::string mDescription; /**< Short description. */
std::string mEffect; /**< Description of effects. */
+#ifdef TMWSERV_SUPPORT
+ char mType; /**< Item type. */
+#else
std::string mType; /**< Item type. */
+#endif
std::string mParticle; /**< Particle effect used with this item */
short mWeight; /**< Weight in grams. */
int mView; /**< Item ID of how this item looks. */
@@ -130,6 +217,7 @@ class ItemInfo
// Equipment related members
SpriteAction mAttackType; /**< Attack type, in case of weapon. */
+ int mAttackRange; /**< Attack range, will be zero if non weapon. */
/** Maps gender to sprite filenames. */
std::map<int, std::string> mAnimationFiles;
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp
index e40acd77..50d7cf67 100644
--- a/src/resources/mapreader.cpp
+++ b/src/resources/mapreader.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,22 +19,22 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <cassert>
-#include <iostream>
-#include <zlib.h>
+#include "resources/animation.h"
+#include "resources/image.h"
+#include "resources/mapreader.h"
+#include "resources/resourcemanager.h"
-#include "animation.h"
-#include "image.h"
-#include "mapreader.h"
-#include "resourcemanager.h"
+#include "log.h"
+#include "map.h"
+#include "tileset.h"
-#include "../log.h"
-#include "../map.h"
-#include "../tileset.h"
+#include "utils/base64.h"
+#include "utils/stringutils.h"
+#include "utils/xml.h"
-#include "../utils/base64.h"
-#include "../utils/stringutils.h"
-#include "../utils/xml.h"
+#include <cassert>
+#include <iostream>
+#include <zlib.h>
const unsigned int DEFAULT_TILE_WIDTH = 32;
const unsigned int DEFAULT_TILE_HEIGHT = 32;
@@ -311,7 +310,8 @@ static void setTile(Map *map, MapLayer *layer, int x, int y, int gid)
layer->setTile(x, y, img);
} else {
// Set collision tile
- map->setWalk(x, y, (!set || (gid - set->getFirstGid() == 0)));
+ if (set && (gid - set->getFirstGid() != 0))
+ map->blockTile(x, y, Map::BLOCKTYPE_WALL);
}
}
@@ -361,12 +361,12 @@ void MapReader::readLayer(xmlNodePtr node, Map *map)
xmlNodePtr dataChild = childNode->xmlChildrenNode;
if (!dataChild)
continue;
-
+
int len = strlen((const char*)dataChild->content) + 1;
unsigned char *charData = new unsigned char[len + 1];
const char *charStart = (const char*)dataChild->content;
unsigned char *charIndex = charData;
-
+
while (*charStart) {
if (*charStart != ' ' && *charStart != '\t' &&
*charStart != '\n')
@@ -428,10 +428,10 @@ void MapReader::readLayer(xmlNodePtr node, Map *map)
}
}
else {
- // Read plain XML map file
- for_each_xml_child_node(childNode2, childNode)
- {
- if (!xmlStrEqual(childNode2->name, BAD_CAST "tile"))
+ // Read plain XML map file
+ for_each_xml_child_node(childNode2, childNode)
+ {
+ if (!xmlStrEqual(childNode2->name, BAD_CAST "tile"))
continue;
const int gid = XML::getProperty(childNode2, "gid", -1);
@@ -445,12 +445,12 @@ void MapReader::readLayer(xmlNodePtr node, Map *map)
}
}
}
-
+
if (y < h)
std::cerr << "TOO SMALL!\n";
if (x)
std::cerr << "TOO SMALL!\n";
-
+
// There can be only one data element
break;
}
@@ -524,7 +524,7 @@ Tileset *MapReader::readTileset(xmlNodePtr node,
// create animation
if (!set) continue;
- Animation *ani = new Animation();
+ Animation *ani = new Animation;
for (int i = 0; ;i++)
{
std::map<std::string, int>::iterator iFrame, iDelay;
diff --git a/src/resources/mapreader.h b/src/resources/mapreader.h
index 2f64aa8c..0ed553c3 100644
--- a/src/resources/mapreader.h
+++ b/src/resources/mapreader.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/resources/monsterdb.cpp b/src/resources/monsterdb.cpp
index b1965989..7bbf9288 100644
--- a/src/resources/monsterdb.cpp
+++ b/src/resources/monsterdb.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,14 +19,15 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "monsterdb.h"
-#include "monsterinfo.h"
+#include "resources/monsterdb.h"
-#include "../log.h"
+#include "resources/monsterinfo.h"
-#include "../utils/dtor.h"
-#include "../utils/gettext.h"
-#include "../utils/xml.h"
+#include "log.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/xml.h"
namespace
{
@@ -62,7 +62,7 @@ void MonsterDB::load()
continue;
}
- MonsterInfo *currentInfo = new MonsterInfo();
+ MonsterInfo *currentInfo = new MonsterInfo;
currentInfo->setName(XML::getProperty(monsterNode, "name", _("unnamed")));
@@ -96,8 +96,7 @@ void MonsterDB::load()
currentInfo->addSprite(
(const char*) spriteNode->xmlChildrenNode->content);
}
-
- if (xmlStrEqual(spriteNode->name, BAD_CAST "sound"))
+ else if (xmlStrEqual(spriteNode->name, BAD_CAST "sound"))
{
std::string event = XML::getProperty(spriteNode, "event", "");
const char *filename;
@@ -127,15 +126,16 @@ void MonsterDB::load()
currentInfo->getName().c_str());
}
}
-
- if (xmlStrEqual(spriteNode->name, BAD_CAST "attack"))
+ else if (xmlStrEqual(spriteNode->name, BAD_CAST "attack"))
{
- std::string event = XML::getProperty(
+ const int id = XML::getProperty(spriteNode, "id", 0);
+ const std::string particleEffect = XML::getProperty(
spriteNode, "particle-effect", "");
- currentInfo->addAttackParticleEffect(event);
+ SpriteAction spriteAction = SpriteDef::makeSpriteAction(
+ XML::getProperty(spriteNode, "action", "attack"));
+ currentInfo->addMonsterAttack(id, particleEffect, spriteAction);
}
-
- if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx"))
+ else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx"))
{
currentInfo->addParticleEffect(
(const char*) spriteNode->xmlChildrenNode->content);
diff --git a/src/resources/monsterdb.h b/src/resources/monsterdb.h
index e49901d5..27536ffc 100644
--- a/src/resources/monsterdb.h
+++ b/src/resources/monsterdb.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,7 +35,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.cpp b/src/resources/monsterinfo.cpp
index 725e9cf5..06a6d3b6 100644
--- a/src/resources/monsterinfo.cpp
+++ b/src/resources/monsterinfo.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,13 +19,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "monsterinfo.h"
+#include "resources/monsterinfo.h"
-#include "../utils/dtor.h"
+#include "utils/dtor.h"
MonsterInfo::MonsterInfo()
{
-
}
MonsterInfo::~MonsterInfo()
@@ -36,7 +34,7 @@ MonsterInfo::~MonsterInfo()
mSounds.clear();
}
-void MonsterInfo::addSound(MonsterSoundEvent event, std::string filename)
+void MonsterInfo::addSound(MonsterSoundEvent event, const std::string &filename)
{
if (mSounds.find(event) == mSounds.end())
{
@@ -46,24 +44,41 @@ void MonsterInfo::addSound(MonsterSoundEvent event, std::string filename)
mSounds[event]->push_back("sfx/" + filename);
}
+const std::string &MonsterInfo::getSound(MonsterSoundEvent event) const
+{
+ static std::string empty("");
+ std::map<MonsterSoundEvent, std::vector<std::string>* >::const_iterator i =
+ mSounds.find(event);
+ return (i == mSounds.end()) ? empty :
+ i->second->at(rand() % i->second->size());
+}
-std::string MonsterInfo::getSound(MonsterSoundEvent event) const
+const std::string &MonsterInfo::getAttackParticleEffect(int attackType) const
{
- std::map<MonsterSoundEvent, std::vector<std::string>* >::const_iterator i;
+ static std::string empty("");
+ std::map<int, MonsterAttack*>::const_iterator i =
+ mMonsterAttacks.find(attackType);
+ return (i == mMonsterAttacks.end()) ? empty : (*i).second->particleEffect;
+}
- i = mSounds.find(event);
+SpriteAction MonsterInfo::getAttackAction(int attackType) const
+{
+ std::map<int, MonsterAttack*>::const_iterator i =
+ mMonsterAttacks.find(attackType);
+ return (i == mMonsterAttacks.end()) ? ACTION_ATTACK : (*i).second->action;
+}
- if (i == mSounds.end())
- {
- return "";
- }
- else
- {
- return i->second->at(rand()%i->second->size());
- }
+void MonsterInfo::addMonsterAttack(int id,
+ const std::string &particleEffect,
+ SpriteAction action)
+{
+ MonsterAttack *a = new MonsterAttack;
+ a->particleEffect = particleEffect;
+ a->action = action;
+ mMonsterAttacks[id] = a;
}
-void MonsterInfo::addParticleEffect(std::string filename)
+void MonsterInfo::addParticleEffect(const std::string &filename)
{
mParticleEffects.push_back(filename);
}
diff --git a/src/resources/monsterinfo.h b/src/resources/monsterinfo.h
index 4a3208f4..f8dce13f 100644
--- a/src/resources/monsterinfo.h
+++ b/src/resources/monsterinfo.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,13 +22,13 @@
#ifndef MONSTERINFO_H
#define MONSTERINFO_H
+#include "being.h"
+
#include <list>
#include <map>
#include <string>
#include <vector>
-#include "../being.h"
-
enum MonsterSoundEvent
{
MONSTER_EVENT_HIT,
@@ -38,6 +37,12 @@ enum MonsterSoundEvent
MONSTER_EVENT_DIE
};
+struct MonsterAttack
+{
+ std::string particleEffect;
+ SpriteAction action;
+};
+
/**
* 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.
@@ -47,28 +52,23 @@ enum MonsterSoundEvent
class MonsterInfo
{
public:
- /**
- * Constructor.
- */
MonsterInfo();
- /**
- * Destructor.
- */
~MonsterInfo();
- void setName(std::string name) { mName = name; }
+ void setName(const std::string &name) { mName = name; }
- void addSprite(std::string filename) { mSprites.push_back(filename); }
+ void addSprite(const std::string &filename)
+ { mSprites.push_back(filename); }
void setTargetCursorSize(Being::TargetCursorSize targetCursorSize)
{ mTargetCursorSize = targetCursorSize; }
- void addSound(MonsterSoundEvent event, std::string filename);
+ void addSound(MonsterSoundEvent event, const std::string &filename);
- void addParticleEffect(std::string filename);
+ void addParticleEffect(const std::string &filename);
- const std::string& getName() const
+ const std::string &getName() const
{ return mName; }
const std::list<std::string>& getSprites() const
@@ -77,23 +77,26 @@ class MonsterInfo
Being::TargetCursorSize getTargetCursorSize() const
{ return mTargetCursorSize; }
- std::string getSound(MonsterSoundEvent event) const;
+ const std::string &getSound(MonsterSoundEvent event) const;
+
+ void addMonsterAttack(int id,
+ const std::string &particleEffect,
+ SpriteAction action);
- std::string getAttackParticleEffect() const { return mAttackParticle; }
+ const std::string &getAttackParticleEffect(int attackType) const;
- void addAttackParticleEffect(const std::string &particleEffect)
- { mAttackParticle = particleEffect; }
+ SpriteAction getAttackAction(int attackType) const;
const std::list<std::string>& getParticleEffects() const
{ return mParticleEffects; }
private:
std::string mName;
- std::string mAttackParticle;
std::list<std::string> mSprites;
Being::TargetCursorSize mTargetCursorSize;
std::map<MonsterSoundEvent, std::vector<std::string>* > mSounds;
+ std::map<int, MonsterAttack*> mMonsterAttacks;
std::list<std::string> mParticleEffects;
};
-#endif
+#endif // MONSTERINFO_H
diff --git a/src/resources/music.cpp b/src/resources/music.cpp
index 72094025..5937f96b 100644
--- a/src/resources/music.cpp
+++ b/src/resources/music.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,9 +19,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "music.h"
+#include "resources/music.h"
-#include "../log.h"
+#include "log.h"
Music::Music(Mix_Chunk *music):
mChunk(music),
diff --git a/src/resources/music.h b/src/resources/music.h
index f89c0fb2..88ef93d0 100644
--- a/src/resources/music.h
+++ b/src/resources/music.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,12 +22,13 @@
#ifndef MUSIC_H
#define MUSIC_H
+#include "resources/resource.h"
+
#ifdef __APPLE__
#include <SDL_mixer/SDL_mixer.h>
#else
#include <SDL_mixer.h>
#endif
-#include "resource.h"
/**
* Defines a class for loading and storing music.
diff --git a/src/resources/npcdb.cpp b/src/resources/npcdb.cpp
index 3e9decf1..6a880faa 100644
--- a/src/resources/npcdb.cpp
+++ b/src/resources/npcdb.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,12 +19,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "npcdb.h"
+#include "resources/npcdb.h"
-#include "../log.h"
+#include "log.h"
-#include "../utils/gettext.h"
-#include "../utils/xml.h"
+#include "utils/gettext.h"
+#include "utils/xml.h"
namespace
{
diff --git a/src/resources/npcdb.h b/src/resources/npcdb.h
index 394154fa..af6764bf 100644
--- a/src/resources/npcdb.h
+++ b/src/resources/npcdb.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/resources/resource.cpp b/src/resources/resource.cpp
index ca9a69c3..86e85c9b 100644
--- a/src/resources/resource.cpp
+++ b/src/resources/resource.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,10 +19,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <cassert>
+#include "resources/resource.h"
+
+#include "resources/resourcemanager.h"
-#include "resource.h"
-#include "resourcemanager.h"
+#include <cassert>
Resource::~Resource()
{
diff --git a/src/resources/resource.h b/src/resources/resource.h
index f8822d72..5b70c720 100644
--- a/src/resources/resource.h
+++ b/src/resources/resource.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -56,8 +55,8 @@ class Resource
/**
* Return the path identifying this resource.
*/
- const std::string&
- getIdPath() { return mIdPath; }
+ const std::string &getIdPath() const
+ { return mIdPath; }
protected:
/**
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index d6ab39a0..33d5e3e5 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,6 +19,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "resources/resourcemanager.h"
+
+#include "resources/dye.h"
+#include "resources/image.h"
+#include "resources/imageset.h"
+#include "resources/music.h"
+#include "resources/soundeffect.h"
+#include "resources/spritedef.h"
+
+#include "log.h"
+
#include <cassert>
#include <physfs.h>
#include <SDL_image.h>
@@ -27,16 +37,6 @@
#include <sys/time.h>
-#include "dye.h"
-#include "image.h"
-#include "imageset.h"
-#include "music.h"
-#include "resourcemanager.h"
-#include "soundeffect.h"
-#include "spritedef.h"
-
-#include "../log.h"
-
ResourceManager *ResourceManager::instance = NULL;
ResourceManager::ResourceManager()
@@ -214,7 +214,7 @@ std::string ResourceManager::getPath(const std::string &file)
return path;
}
-Resource *ResourceManager::get(std::string const &idPath, generator fun,
+Resource *ResourceManager::get(const std::string &idPath, generator fun,
void *data)
{
// Check if the id exists, and return the value if it does.
@@ -266,7 +266,7 @@ struct ResourceLoader
}
};
-Resource *ResourceManager::load(std::string const &path, loader fun)
+Resource *ResourceManager::load(const std::string &path, loader fun)
{
ResourceLoader l = { this, path, fun };
return get(path, ResourceLoader::load, &l);
@@ -308,7 +308,7 @@ struct DyedImageLoader
}
};
-Image *ResourceManager::getImage(std::string const &idPath)
+Image *ResourceManager::getImage(const std::string &idPath)
{
DyedImageLoader l = { this, idPath };
return static_cast<Image*>(get(idPath, DyedImageLoader::load, &l));
@@ -350,8 +350,7 @@ struct SpriteDefLoader
}
};
-SpriteDef *ResourceManager::getSprite
- (std::string const &path, int variant)
+SpriteDef *ResourceManager::getSprite(const std::string &path, int variant)
{
SpriteDefLoader l = { path, variant };
std::stringstream ss;
@@ -380,7 +379,8 @@ void ResourceManager::release(Resource *res)
ResourceManager *ResourceManager::getInstance()
{
// Create a new instance if necessary.
- if (instance == NULL) instance = new ResourceManager();
+ if (!instance)
+ instance = new ResourceManager;
return instance;
}
@@ -441,7 +441,7 @@ std::vector<std::string> ResourceManager::loadTextFile(const std::string &fileNa
return lines;
}
-SDL_Surface *ResourceManager::loadSDLSurface(const std::string& filename)
+SDL_Surface *ResourceManager::loadSDLSurface(const std::string &filename)
{
int fileSize;
void *buffer = loadFile(filename, fileSize);
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
index 10f6fffe..828c5b0a 100644
--- a/src/resources/resourcemanager.h
+++ b/src/resources/resourcemanager.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -116,7 +115,7 @@ class ResourceManager
* @return A valid resource or <code>NULL</code> if the resource could
* not be generated.
*/
- Resource *get(std::string const &idPath, generator fun, void *data);
+ Resource *get(const std::string &idPath, generator fun, void *data);
/**
* Loads a resource from a file and adds it to the resource map.
@@ -126,7 +125,7 @@ class ResourceManager
* @return A valid resource or <code>NULL</code> if the resource could
* not be loaded.
*/
- Resource *load(std::string const &path, loader fun);
+ Resource *load(const std::string &path, loader fun);
/**
* Convenience wrapper around ResourceManager::get for loading
@@ -156,7 +155,7 @@ class ResourceManager
* Creates a sprite definition based on a given path and the supplied
* variant.
*/
- SpriteDef *getSprite(std::string const &path, int variant = 0);
+ SpriteDef *getSprite(const std::string &path, int variant = 0);
/**
* Releases a resource, placing it in the set of orphaned resources.
@@ -184,7 +183,7 @@ class ResourceManager
* Loads the given filename as an SDL surface. The returned surface is
* expected to be freed by the caller using SDL_FreeSurface.
*/
- SDL_Surface *loadSDLSurface(const std::string& filename);
+ SDL_Surface *loadSDLSurface(const std::string &filename);
/**
* Returns an instance of the class, creating one if it does not
diff --git a/src/resources/soundeffect.cpp b/src/resources/soundeffect.cpp
index d1d24afb..bdb393ff 100644
--- a/src/resources/soundeffect.cpp
+++ b/src/resources/soundeffect.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,9 +19,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "soundeffect.h"
+#include "resources/soundeffect.h"
-#include "../log.h"
+#include "log.h"
SoundEffect::~SoundEffect()
{
diff --git a/src/resources/soundeffect.h b/src/resources/soundeffect.h
index fe14df02..dd5d166f 100644
--- a/src/resources/soundeffect.h
+++ b/src/resources/soundeffect.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,14 +22,14 @@
#ifndef SOUND_EFFECT_H
#define SOUND_EFFECT_H
+#include "resources/resource.h"
+
#ifdef __APPLE__
#include <SDL_mixer/SDL_mixer.h>
#else
#include <SDL_mixer.h>
#endif
-#include "resource.h"
-
/**
* Defines a class for loading and storing sound effects.
*/
@@ -73,4 +72,4 @@ class SoundEffect : public Resource
Mix_Chunk *mChunk;
};
-#endif
+#endif // SOUND_EFFECT_H
diff --git a/src/resources/spritedef.cpp b/src/resources/spritedef.cpp
index d6cc8960..30d8e778 100644
--- a/src/resources/spritedef.cpp
+++ b/src/resources/spritedef.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,20 +19,22 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <set>
+#include "resources/spritedef.h"
+
+#include "resources/action.h"
+#include "resources/animation.h"
+#include "resources/dye.h"
+#include "resources/image.h"
+#include "resources/imageset.h"
+#include "resources/resourcemanager.h"
-#include "action.h"
-#include "animation.h"
-#include "dye.h"
-#include "image.h"
-#include "imageset.h"
-#include "resourcemanager.h"
-#include "spritedef.h"
+#include "log.h"
-#include "../log.h"
-#include "../utils/xml.h"
+#include "utils/xml.h"
+
+#include <set>
-Action* SpriteDef::getAction(SpriteAction action) const
+Action *SpriteDef::getAction(SpriteAction action) const
{
Actions::const_iterator i = mActions.find(action);
@@ -46,7 +47,7 @@ Action* SpriteDef::getAction(SpriteAction action) const
return i->second;
}
-SpriteDef *SpriteDef::load(std::string const &animationFile, int variant)
+SpriteDef *SpriteDef::load(const std::string &animationFile, int variant)
{
std::string::size_type pos = animationFile.find('|');
std::string palettes;
@@ -121,7 +122,7 @@ void SpriteDef::loadSprite(xmlNodePtr spriteNode, int variant,
}
}
-void SpriteDef::loadImageSet(xmlNodePtr node, std::string const &palettes)
+void SpriteDef::loadImageSet(xmlNodePtr node, const std::string &palettes)
{
const std::string name = XML::getProperty(node, "name", "");
@@ -167,7 +168,7 @@ void SpriteDef::loadAction(xmlNodePtr node, int variant_offset)
actionName.c_str(), getIdPath().c_str());
return;
}
- Action *action = new Action();
+ Action *action = new Action;
mActions[actionType] = action;
// When first action set it as default direction
@@ -201,7 +202,7 @@ void SpriteDef::loadAnimation(xmlNodePtr animationNode,
return;
}
- Animation *animation = new Animation();
+ Animation *animation = new Animation;
action->setAnimation(directionType, animation);
// Get animation frames
@@ -320,7 +321,7 @@ SpriteDef::~SpriteDef()
}
}
-SpriteAction SpriteDef::makeSpriteAction(const std::string& action)
+SpriteAction SpriteDef::makeSpriteAction(const std::string &action)
{
if (action.empty() || action == "default") {
return ACTION_DEFAULT;
@@ -349,6 +350,36 @@ SpriteAction SpriteDef::makeSpriteAction(const std::string& action)
else if (action == "attack_throw") {
return ACTION_ATTACK_THROW;
}
+ else if (action == "special0") {
+ return ACTION_SPECIAL_0;
+ }
+ else if (action == "special1") {
+ return ACTION_SPECIAL_1;
+ }
+ else if (action == "special2") {
+ return ACTION_SPECIAL_2;
+ }
+ else if (action == "special3") {
+ return ACTION_SPECIAL_3;
+ }
+ else if (action == "special4") {
+ return ACTION_SPECIAL_4;
+ }
+ else if (action == "special5") {
+ return ACTION_SPECIAL_5;
+ }
+ else if (action == "special6") {
+ return ACTION_SPECIAL_6;
+ }
+ else if (action == "special7") {
+ return ACTION_SPECIAL_7;
+ }
+ else if (action == "special8") {
+ return ACTION_SPECIAL_8;
+ }
+ else if (action == "special9") {
+ return ACTION_SPECIAL_9;
+ }
else if (action == "cast_magic") {
return ACTION_CAST_MAGIC;
}
@@ -372,7 +403,7 @@ SpriteAction SpriteDef::makeSpriteAction(const std::string& action)
}
}
-SpriteDirection SpriteDef::makeSpriteDirection(const std::string& direction)
+SpriteDirection SpriteDef::makeSpriteDirection(const std::string &direction)
{
if (direction.empty() || direction == "default") {
return DIRECTION_DEFAULT;
@@ -391,5 +422,5 @@ SpriteDirection SpriteDef::makeSpriteDirection(const std::string& direction)
}
else {
return DIRECTION_INVALID;
- };
+ }
}
diff --git a/src/resources/spritedef.h b/src/resources/spritedef.h
index 040d96e2..45b5b043 100644
--- a/src/resources/spritedef.h
+++ b/src/resources/spritedef.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,13 +22,13 @@
#ifndef SPRITEDEF_H
#define SPRITEDEF_H
+#include "resources/resource.h"
+
#include <map>
#include <string>
#include <libxml/tree.h>
-#include "resource.h"
-
class Action;
class ImageSet;
@@ -44,6 +43,16 @@ enum SpriteAction
ACTION_ATTACK_STAB,
ACTION_ATTACK_BOW,
ACTION_ATTACK_THROW,
+ ACTION_SPECIAL_0,
+ ACTION_SPECIAL_1,
+ ACTION_SPECIAL_2,
+ ACTION_SPECIAL_3,
+ ACTION_SPECIAL_4,
+ ACTION_SPECIAL_5,
+ ACTION_SPECIAL_6,
+ ACTION_SPECIAL_7,
+ ACTION_SPECIAL_8,
+ ACTION_SPECIAL_9,
ACTION_CAST_MAGIC,
ACTION_USE_ITEM,
ACTION_SIT,
@@ -56,8 +65,8 @@ enum SpriteAction
enum SpriteDirection
{
DIRECTION_DEFAULT = 0,
- DIRECTION_DOWN,
DIRECTION_UP,
+ DIRECTION_DOWN,
DIRECTION_LEFT,
DIRECTION_RIGHT,
DIRECTION_INVALID
@@ -72,13 +81,24 @@ class SpriteDef : public Resource
/**
* Loads a sprite definition file.
*/
- static SpriteDef *load(std::string const &file, int variant);
+ static SpriteDef *load(const std::string &file, int variant);
/**
* Returns the specified action.
*/
Action *getAction(SpriteAction action) const;
+ /**
+ * Converts a string into a SpriteAction enum.
+ */
+ static SpriteAction makeSpriteAction(const std::string &action);
+
+ /**
+ * Converts a string into a SpriteDirection enum.
+ */
+ static SpriteDirection
+ makeSpriteDirection(const std::string &direction);
+
private:
/**
* Constructor.
@@ -99,7 +119,7 @@ class SpriteDef : public Resource
/**
* Loads an imageset element.
*/
- void loadImageSet(xmlNodePtr node, std::string const &palettes);
+ void loadImageSet(xmlNodePtr node, const std::string &palettes);
/**
* Loads an action element.
@@ -129,16 +149,6 @@ class SpriteDef : public Resource
*/
void substituteAction(SpriteAction complete, SpriteAction with);
- /**
- * Converts a string into a SpriteAction enum.
- */
- static SpriteAction makeSpriteAction(const std::string &action);
-
- /**
- * Converts a string into a SpriteDirection enum.
- */
- static SpriteDirection makeSpriteDirection(const std::string &direction);
-
typedef std::map<std::string, ImageSet*> ImageSets;
typedef ImageSets::iterator ImageSetIterator;
@@ -148,4 +158,4 @@ class SpriteDef : public Resource
Actions mActions;
};
-#endif
+#endif // SPRITEDEF_H
diff --git a/src/serverinfo.h b/src/serverinfo.h
index fc3ef032..c38d13c7 100644
--- a/src/serverinfo.h
+++ b/src/serverinfo.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/shopitem.cpp b/src/shopitem.cpp
index f1ef3dad..683cef7a 100644
--- a/src/shopitem.cpp
+++ b/src/shopitem.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,20 +21,25 @@
#include "shopitem.h"
-#include "utils/stringutils.h"
+#include "units.h"
-ShopItem::ShopItem (int inventoryIndex, int id, int quantity, int price) :
- Item (id, 0),
+#include "resources/iteminfo.h"
+
+ShopItem::ShopItem(int inventoryIndex, int id,
+ int quantity, int price) :
+ Item(id, 0),
mPrice(price)
{
- mDisplayName = getInfo().getName() + " (" + toString(mPrice) + " GP)";
+ mDisplayName = getInfo().getName() +
+ " (" + Units::formatCurrency(mPrice).c_str() + ")";
setInvIndex(inventoryIndex);
addDuplicate(inventoryIndex, quantity);
}
ShopItem::ShopItem (int id, int price) : Item (id, 0), mPrice(price)
{
- mDisplayName = getInfo().getName() + " (" + toString(mPrice) + " GP)";
+ mDisplayName = getInfo().getName() +
+ " (" + Units::formatCurrency(mPrice).c_str() + ")";
setInvIndex(-1);
addDuplicate(-1, 0);
}
@@ -81,4 +85,3 @@ int ShopItem::sellCurrentDuplicate(int quantity)
}
return sellCount;
}
-
diff --git a/src/shopitem.h b/src/shopitem.h
index afc48bf5..f552c0fe 100644
--- a/src/shopitem.h
+++ b/src/shopitem.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -118,12 +117,11 @@ class ShopItem : public Item
*
* @return the display name for the item in the shop list
*/
- const std::string& getDisplayName() const
+ const std::string &getDisplayName() const
{ return mDisplayName; }
protected:
int mPrice;
- int mIndex;
std::string mDisplayName;
/**
diff --git a/src/simpleanimation.cpp b/src/simpleanimation.cpp
index c3584ede..65d8e8e2 100644
--- a/src/simpleanimation.cpp
+++ b/src/simpleanimation.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,13 +34,13 @@ SimpleAnimation::SimpleAnimation(Animation *animation):
mAnimationPhase(0),
mCurrentFrame(mAnimation->getFrame(0))
{
-};
+}
SimpleAnimation::SimpleAnimation(xmlNodePtr animationNode):
mAnimationTime(0),
mAnimationPhase(0)
{
- mAnimation = new Animation();
+ mAnimation = new Animation;
ImageSet *imageset = ResourceManager::getInstance()->getImageSet(
XML::getProperty(animationNode, "imageset", ""),
diff --git a/src/simpleanimation.h b/src/simpleanimation.h
index 5583e449..e48644d4 100644
--- a/src/simpleanimation.h
+++ b/src/simpleanimation.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/sound.cpp b/src/sound.cpp
index 5b8dedef..6e0b0da0 100644
--- a/src/sound.cpp
+++ b/src/sound.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/sound.h b/src/sound.h
index 5c0c7ef8..c30ef7cd 100644
--- a/src/sound.h
+++ b/src/sound.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,6 +29,8 @@
#endif
#include <string>
+#include <string>
+
/** Sound engine
*
* \ingroup CORE
diff --git a/src/sprite.h b/src/sprite.h
index c2b0fc7c..a6384e94 100644
--- a/src/sprite.h
+++ b/src/sprite.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/statuseffect.cpp b/src/statuseffect.cpp
new file mode 100644
index 00000000..077fbb63
--- /dev/null
+++ b/src/statuseffect.cpp
@@ -0,0 +1,174 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <map>
+
+#include "gui/chat.h"
+#include "statuseffect.h"
+
+#include "log.h"
+#include "utils/xml.h"
+
+
+#define STATUS_EFFECTS_FILE "status-effects.xml"
+
+StatusEffect::StatusEffect() :
+ mPersistentParticleEffect(false)
+{}
+
+StatusEffect::~StatusEffect()
+{}
+
+void StatusEffect::playSFX()
+{
+ if (!mSFXEffect.empty())
+ sound.playSfx(mSFXEffect);
+}
+
+void StatusEffect::deliverMessage()
+{
+ if (!mMessage.empty())
+ localChatTab->chatLog(mMessage, BY_SERVER);
+}
+
+Particle *StatusEffect::getParticle()
+{
+ if (mParticleEffect.empty())
+ return NULL;
+ else
+ return particleEngine->addEffect(mParticleEffect, 0, 0);
+}
+
+AnimatedSprite *StatusEffect::getIcon()
+{
+ if (mIcon.empty())
+ return NULL;
+ else {
+ AnimatedSprite *sprite = AnimatedSprite::load(
+ "graphics/sprites/" + mIcon);
+ if (false && sprite) {
+ sprite->play(ACTION_DEFAULT);
+ sprite->reset();
+ }
+ return sprite;
+ }
+}
+
+SpriteAction StatusEffect::getAction()
+{
+ if (mAction.empty())
+ return ACTION_INVALID;
+ else
+ return SpriteDef::makeSpriteAction(mAction);
+}
+
+
+// -- initialisation and static parts --
+
+
+typedef std::map<int, StatusEffect *> status_effect_map[2];
+
+static status_effect_map statusEffects;
+static status_effect_map stunEffects;
+static std::map<int, int> blockEffectIndexMap;
+
+int StatusEffect::blockEffectIndexToEffectIndex(int blockIndex)
+{
+ if (blockEffectIndexMap.find(blockIndex) == blockEffectIndexMap.end())
+ return -1;
+ return blockEffectIndexMap[blockIndex];
+}
+
+StatusEffect *StatusEffect::getStatusEffect(int index, bool enabling)
+{
+ return statusEffects[enabling][index];
+}
+
+StatusEffect *StatusEffect::getStunEffect(int index, bool enabling)
+{
+ return stunEffects[enabling][index];
+}
+
+void StatusEffect::load()
+{
+ XML::Document doc(STATUS_EFFECTS_FILE);
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "status-effects"))
+ {
+ logger->log("Error loading status effects file: "
+ STATUS_EFFECTS_FILE);
+ return;
+ }
+
+ for_each_xml_child_node(node, rootNode)
+ {
+ status_effect_map *the_map = NULL;
+
+ int index = atoi(XML::getProperty(node, "id", "-1").c_str());
+
+ if (xmlStrEqual(node->name, BAD_CAST "status-effect"))
+ {
+ the_map = &statusEffects;
+ int block_index = atoi(XML::getProperty(node, "block-id", "-1").c_str());
+
+ if (index >= 0 && block_index >= 0)
+ blockEffectIndexMap[block_index] = index;
+
+ } else if (xmlStrEqual(node->name, BAD_CAST "stun-effect"))
+ the_map = &stunEffects;
+
+ if (the_map) {
+ StatusEffect *startEffect = new StatusEffect;
+ StatusEffect *endEffect = new StatusEffect;
+
+ startEffect->mMessage = XML::getProperty(node, "start-message", "");
+ startEffect->mSFXEffect = XML::getProperty(node, "start-audio", "");
+ startEffect->mParticleEffect = XML::getProperty(node, "start-particle", "");
+ startEffect->mIcon = XML::getProperty(node, "icon", "");
+ startEffect->mAction = XML::getProperty(node, "action", "");
+ startEffect->mPersistentParticleEffect = (XML::getProperty(node, "persistent-particle-effect", "no")) != "no";
+
+ endEffect->mMessage = XML::getProperty(node, "end-message", "");
+ endEffect->mSFXEffect = XML::getProperty(node, "end-audio", "");
+ endEffect->mParticleEffect = XML::getProperty(node, "end-particle", "");
+
+ (*the_map)[1][index] = startEffect;
+ (*the_map)[0][index] = endEffect;
+ }
+ }
+}
+
+void unloadMap(std::map<int, StatusEffect *> map)
+{
+ std::map<int, StatusEffect *>::iterator it;
+
+ for (it = map.begin(); it != map.end(); it++)
+ delete (*it).second;
+}
+
+void StatusEffect::unload()
+{
+ unloadMap(statusEffects[0]);
+ unloadMap(statusEffects[1]);
+ unloadMap(stunEffects[0]);
+ unloadMap(stunEffects[1]);
+}
diff --git a/src/statuseffect.h b/src/statuseffect.h
new file mode 100644
index 00000000..f1af93d2
--- /dev/null
+++ b/src/statuseffect.h
@@ -0,0 +1,110 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef STATUS_EFFECT_H
+#define STATUS_EFFECT_H
+
+#include "resources/animation.h"
+#include "particle.h"
+#include "animatedsprite.h"
+#include "sound.h"
+
+class StatusEffect
+{
+public:
+ StatusEffect();
+ ~StatusEffect();
+
+ /**
+ * Plays the sound effect associated with this status effect, if possible.
+ */
+ void playSFX();
+
+ /**
+ * Delivers the chat message associated with this status effect, if
+ * possible.
+ */
+ void deliverMessage();
+
+ /**
+ * Creates the particle effect associated with this status effect, if
+ * possible.
+ */
+ Particle *getParticle();
+
+ /**
+ * Retrieves the status icon for this effect, if applicable
+ */
+ AnimatedSprite *getIcon();
+
+ /**
+ * Retrieves an action to perform, or ACTION_INVALID
+ */
+ SpriteAction getAction();
+
+ /**
+ * Determines whether the particle effect should be restarted when the
+ * being changes maps
+ */
+ bool particleEffectIsPersistent() const { return mPersistentParticleEffect; }
+
+
+ /**
+ * Retrieves a status effect.
+ *
+ * \param index Index of the status effect.
+ * \param enabling Whether to retrieve the activating effect (true) or
+ * the deactivating effect (false).
+ */
+ static StatusEffect *getStatusEffect(int index, bool enabling);
+
+ /**
+ * Retrieves a stun effect.
+ *
+ * \param index Index of the stun effect.
+ * \param enabling Whether to retrieve the activating effect (true) or
+ * the deactivating effect (false).
+ */
+ static StatusEffect *getStunEffect(int index, bool enabling);
+
+ /**
+ * Maps a block effect index to its corresponding effect index. Block
+ * effect indices are used for opt2/opt3/status.option blocks; their
+ * mapping to regular effect indices is handled in the config file.
+ *
+ * Returns -1 on failure.
+ */
+ static int blockEffectIndexToEffectIndex(int blocKIndex);
+
+ static void load();
+
+ static void unload();
+private:
+
+ std::string mMessage;
+ std::string mSFXEffect;
+ std::string mParticleEffect;
+ std::string mIcon;
+ std::string mAction;
+ bool mPersistentParticleEffect;
+};
+
+#endif // !defined(STATUS_EFFECT_H)
diff --git a/src/text.cpp b/src/text.cpp
index 4e697f15..83bd6c24 100644
--- a/src/text.cpp
+++ b/src/text.cpp
@@ -3,7 +3,7 @@
* Copyright (C) 2008 Douglas Boffey <DougABoffey@netscape.net>
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,29 +20,58 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "text.h"
+
#include <guichan/font.hpp>
-#include "text.h"
+#include "configuration.h"
#include "textmanager.h"
+#include "resources/resourcemanager.h"
+#include "resources/image.h"
#include "gui/gui.h"
#include "gui/palette.h"
#include "gui/textrenderer.h"
int Text::mInstances = 0;
+ImageRect Text::mBubble;
+Image *Text::mBubbleArrow;
Text::Text(const std::string &text, int x, int y,
- gcn::Graphics::Alignment alignment, const gcn::Color* color) :
+ gcn::Graphics::Alignment alignment,
+ const gcn::Color* color, bool isSpeech) :
mText(text),
- mColor(color)
+ mColor(color),
+ mIsSpeech(isSpeech)
{
if (textManager == 0)
{
- textManager = new TextManager();
+ textManager = new TextManager;
+ ResourceManager *resman = ResourceManager::getInstance();
+ Image *sbImage = resman->getImage("graphics/gui/bubble.png|W:#"
+ + config.getValue("speechBubblecolor", "000000"));
+ mBubble.grid[0] = sbImage->getSubImage(0, 0, 5, 5);
+ mBubble.grid[1] = sbImage->getSubImage(5, 0, 5, 5);
+ mBubble.grid[2] = sbImage->getSubImage(10, 0, 5, 5);
+ mBubble.grid[3] = sbImage->getSubImage(0, 5, 5, 5);
+ mBubble.grid[4] = sbImage->getSubImage(5, 5, 5, 5);
+ mBubble.grid[5] = sbImage->getSubImage(10, 5, 5, 5);
+ mBubble.grid[6] = sbImage->getSubImage(0, 10, 5, 5);
+ mBubble.grid[7] = sbImage->getSubImage(5, 10, 5, 5);
+ mBubble.grid[8] = sbImage->getSubImage(10, 10, 5, 5);
+ mBubbleArrow = sbImage->getSubImage(0, 15, 15, 10);
+ const float bubbleAlpha = config.getValue("speechBubbleAlpha", 1.0);
+ for (int i = 0; i < 9; i++)
+ {
+ mBubble.grid[i]->setAlpha(bubbleAlpha);
+ }
+ mBubbleArrow->setAlpha(bubbleAlpha);
+ sbImage->decRef();
}
++mInstances;
mHeight = boldFont->getHeight();
mWidth = boldFont->getWidth(text);
+
switch (alignment)
{
case gcn::Graphics::LEFT:
@@ -60,11 +89,6 @@ Text::Text(const std::string &text, int x, int y,
textManager->addText(this);
}
-void Text::adviseXY(int x, int y)
-{
- textManager->moveText(this, x - mXOffset, y);
-}
-
Text::~Text()
{
textManager->removeText(this);
@@ -72,16 +96,44 @@ Text::~Text()
{
delete textManager;
textManager = 0;
+ delete mBubble.grid[0];
+ delete mBubble.grid[1];
+ delete mBubble.grid[2];
+ delete mBubble.grid[3];
+ delete mBubble.grid[4];
+ delete mBubble.grid[5];
+ delete mBubble.grid[6];
+ delete mBubble.grid[7];
+ delete mBubble.grid[8];
+ delete mBubbleArrow;
}
}
+void Text::adviseXY(int x, int y)
+{
+ textManager->moveText(this, x - mXOffset, y);
+}
+
void Text::draw(gcn::Graphics *graphics, int xOff, int yOff)
{
graphics->setFont(boldFont);
+ if (mIsSpeech) {
+ static_cast<Graphics*>(graphics)->drawImageRect(
+ mX - xOff - 5, mY - yOff - 5, mWidth + 10, mHeight + 10,
+ mBubble);
+ /*
+ if (mWidth >= 15) {
+ static_cast<Graphics*>(graphics)->drawImage(
+ mBubbleArrow, mX - xOff - 7 + mWidth / 2,
+ mY - yOff + mHeight + 4);
+ }
+ */
+ }
+
TextRenderer::renderText(graphics, mText,
mX - xOff, mY - yOff, gcn::Graphics::LEFT,
- *mColor, boldFont, true);
+ *mColor, boldFont, !mIsSpeech, true);
}
FlashText::FlashText(const std::string &text, int x, int y,
diff --git a/src/text.h b/src/text.h
index cf0aac48..a96096cc 100644
--- a/src/text.h
+++ b/src/text.h
@@ -3,7 +3,7 @@
* Copyright (C) 2008 Douglas Boffey <DougABoffey@netscape.net>
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,8 +24,8 @@
#define TEXT_H
#include <guichan/color.hpp>
-#include <guichan/graphics.hpp>
+#include "graphics.h"
#include "guichanfwd.h"
class TextManager;
@@ -40,7 +40,7 @@ class Text
*/
Text(const std::string &text, int x, int y,
gcn::Graphics::Alignment alignment,
- const gcn::Color *color);
+ const gcn::Color *color, bool isSpeech = false);
/**
* Destructor. The text is removed from the screen.
@@ -66,6 +66,11 @@ class Text
static int mInstances; /**< Instances of text. */
std::string mText; /**< The text to display. */
const gcn::Color *mColor; /**< The color of the text. */
+ bool mIsSpeech; /**< Is this text a speech bubble? */
+
+ protected:
+ static ImageRect mBubble; /**< Speech bubble graphic */
+ static Image *mBubbleArrow; /**< Speech bubble arrow graphic */
};
class FlashText : public Text
@@ -81,12 +86,12 @@ class FlashText : public Text
virtual ~FlashText() {}
/**
- * Flash the text for so many refreshes
+ * Flash the text for so many refreshes.
*/
void flash(int time) {mTime = time; }
/**
- * Draws the text
+ * Draws the text.
*/
virtual void draw(gcn::Graphics *graphics, int xOff, int yOff);
diff --git a/src/textmanager.cpp b/src/textmanager.cpp
index 0cf09478..6bc8f8b6 100644
--- a/src/textmanager.cpp
+++ b/src/textmanager.cpp
@@ -2,7 +2,7 @@
* Support for non-overlapping floating text
* Copyright (C) 2008 Douglas Boffey <DougABoffey@netscape.net>
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,10 +19,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "textmanager.h"
+
#include <cstring>
#include "text.h"
-#include "textmanager.h"
TextManager *textManager = 0;
diff --git a/src/textmanager.h b/src/textmanager.h
index d6485e34..ee8e1209 100644
--- a/src/textmanager.h
+++ b/src/textmanager.h
@@ -2,7 +2,7 @@
* Support for non-overlapping floating text
* Copyright (C) 2008 Douglas Boffey <DougABoffey@netscape.net>
*
- * This file is part of Aethyra.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/textparticle.cpp b/src/textparticle.cpp
index 957d67c0..04b7abe1 100644
--- a/src/textparticle.cpp
+++ b/src/textparticle.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2006 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/textparticle.h b/src/textparticle.h
index 1a49b5ef..8b7d3e01 100644
--- a/src/textparticle.h
+++ b/src/textparticle.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2006 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,8 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _TEXTPARTICLE_H
-#define _TEXTPARTICLE_H
+#ifndef TEXTPARTICLE_H
+#define TEXTPARTICLE_H
#include "guichanfwd.h"
#include "particle.h"
diff --git a/src/tileset.h b/src/tileset.h
index 28f7d9d5..d4de7ba5 100644
--- a/src/tileset.h
+++ b/src/tileset.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/aethyra.rc b/src/tmw.rc
index e9d32be9..d9689f28 100644
--- a/src/aethyra.rc
+++ b/src/tmw.rc
@@ -1,22 +1,23 @@
-#include <windows.h> // include for version info constants
-
-#include "winver.h"
-
-A ICON MOVEABLE PURE LOADONCALL DISCARDABLE "data/icons/aethyra.ico"
-
-1 VERSIONINFO
-FILEVERSION VER_MAJOR,VER_MINOR,VER_RELEASE,VER_BUILD
-PRODUCTVERSION VER_MAJOR,VER_MINOR,VER_RELEASE,VER_BUILD
-FILETYPE VFT_APP {
- BLOCK "StringFileInfo" {
- BLOCK "040904E4" {
- VALUE "CompanyName", "Aethyra Development Team"
- VALUE "FileVersion", PACKAGE_VERSION
- VALUE "FileDescription", "Aethyra Experiment"
- VALUE "LegalCopyright", "2009 (C)"
- VALUE "OriginalFilename", "aethyra.exe"
- VALUE "ProductName", "Aethyra MMORPG"
- VALUE "ProductVersion", PACKAGE_VERSION
- }
- }
+#include <windows.h> // include for version info constants
+
+#include "winver.h"
+
+A ICON MOVEABLE PURE LOADONCALL DISCARDABLE "data/icons/tmw.ico"
+
+1 VERSIONINFO
+FILEVERSION VER_MAJOR,VER_MINOR,VER_RELEASE,VER_BUILD
+PRODUCTVERSION VER_MAJOR,VER_MINOR,VER_RELEASE,VER_BUILD
+FILETYPE VFT_APP {
+ BLOCK "StringFileInfo" {
+ BLOCK "040904E4" {
+ VALUE "CompanyName", "The Mana World Development Team"
+ VALUE "FileVersion", PACKAGE_VERSION
+ VALUE "FileDescription", "The Mana World"
+ VALUE "LegalCopyright", "2004-2009 (C)"
+ VALUE "OriginalFilename", "tmw.exe"
+ VALUE "ProductName", "The Mana World MMORPG"
+ VALUE "ProductVersion", PACKAGE_VERSION
+ }
+ }
}
+
diff --git a/src/units.cpp b/src/units.cpp
new file mode 100644
index 00000000..acdbd564
--- /dev/null
+++ b/src/units.cpp
@@ -0,0 +1,234 @@
+/*
+ * Support for custom units
+ * Copyright (C) 2009 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "units.h"
+
+#include "log.h"
+
+#include "utils/strprintf.h"
+#include "utils/stringutils.h"
+#include "utils/xml.h"
+
+#include <cmath>
+#include <climits>
+#include <vector>
+
+struct UnitLevel {
+ std::string symbol;
+ int count;
+ int round;
+};
+
+struct UnitDescription {
+ std::vector<struct UnitLevel> levels;
+ double conversion;
+ bool mix;
+};
+
+enum UnitType {
+ UNIT_WEIGHT = 0,
+ UNIT_CURRENCY = 1,
+ UNIT_END
+};
+
+struct UnitDescription units[UNIT_END];
+
+void Units::loadUnits()
+{
+ { // Setup default weight
+ struct UnitDescription ud;
+
+ ud.conversion = 1.0;
+ ud.mix = false;
+
+ struct UnitLevel bu;
+ bu.symbol = "g";
+ bu.count = 1;
+ bu.round = 0;
+
+ ud.levels.push_back(bu);
+
+ struct UnitLevel ul;
+ ul.symbol = "kg";
+ ul.count = 1000;
+ ul.round = 2;
+
+ ud.levels.push_back(ul);
+
+ units[UNIT_WEIGHT] = ud;
+ }
+
+ { // Setup default currency
+ struct UnitDescription ud;
+
+ ud.conversion = 1.0;
+ ud.mix = false;
+
+ struct UnitLevel bu;
+ bu.symbol = "¤";
+ bu.count = 1;
+ bu.round = 0;
+
+ ud.levels.push_back(bu);
+
+ units[UNIT_CURRENCY] = ud;
+ }
+
+ XML::Document doc("units.xml");
+ xmlNodePtr root = doc.rootNode();
+
+ if (!root || !xmlStrEqual(root->name, BAD_CAST "units"))
+ {
+ logger->log("Error loading unit definition file: units.xml");
+ return;
+ }
+
+ for_each_xml_child_node(node, root)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "unit"))
+ {
+ struct UnitDescription ud;
+ int level = 1;
+ const std::string type = XML::getProperty(node, "type", "");
+ ud.conversion = XML::getProperty(node, "conversion", 1.0);
+ ud.mix = XML::getProperty(node, "mix", "no") == "yes";
+
+ struct UnitLevel bu;
+ bu.symbol = XML::getProperty(node, "base", "¤");
+ bu.count = 1;
+ bu.round = XML::getProperty(node, "round", 2);
+
+ ud.levels.push_back(bu);
+
+ for_each_xml_child_node(uLevel, node)
+ {
+ if (xmlStrEqual(uLevel->name, BAD_CAST "level"))
+ {
+ struct UnitLevel ul;
+ ul.symbol = XML::getProperty(uLevel, "symbol",
+ strprintf("¤%d",level));
+ ul.count = XML::getProperty(uLevel, "count", -1);
+ ul.round = XML::getProperty(uLevel, "round", bu.round);
+
+ if (ul.count > 0)
+ {
+ ud.levels.push_back(ul);
+ level++;
+ }
+ else
+ {
+ logger->log("Error bad unit count: %d for %s in %s",
+ ul.count, ul.symbol.c_str(), bu.symbol.c_str());
+ }
+ }
+ }
+
+ // Add one more level for saftey
+ struct UnitLevel ll;
+ ll.symbol = "";
+ ll.count = INT_MAX;
+ ll.round = 0;
+
+ ud.levels.push_back(ll);
+
+ if (type == "weight")
+ units[UNIT_WEIGHT] = ud;
+ else if (type == "currency")
+ units[UNIT_CURRENCY] = ud;
+ else
+ logger->log("Error unknown unit type: %s", type.c_str());
+ }
+ }
+}
+
+std::string formatUnit(int value, int type)
+{
+ struct UnitDescription ud = units[type];
+ struct UnitLevel ul;
+
+ // Shortcut for 0; do the same for values less than 0 (for now)
+ if (value <= 0) {
+ ul = ud.levels[0];
+ return strprintf("0%s", ul.symbol.c_str());
+ } else {
+ double amount = ud.conversion * value;
+
+ // If only the first level is needed, act like mix if false
+ if (ud.mix && ud.levels.size() > 0 && ud.levels[1].count < amount)
+ {
+ std::string output;
+ struct UnitLevel pl = ud.levels[0];
+ ul = ud.levels[1];
+ int levelAmount = (int) amount;
+ int nextAmount;
+
+ levelAmount /= ul.count;
+
+ amount -= levelAmount * ul.count;
+
+ if (amount > 0) {
+ output = strprintf("%.*f%s", pl.round, amount,
+ pl.symbol.c_str());
+ }
+
+ for (unsigned int i = 2; i < ud.levels.size(); i++)
+ {
+ pl = ul;
+ ul = ud.levels[i];
+
+ nextAmount = levelAmount / ul.count;
+ levelAmount %= ul.count;
+
+ if (levelAmount > 0) output = strprintf("%d%s",
+ levelAmount, pl.symbol.c_str()) + output;
+
+ if (!nextAmount) break;
+ levelAmount = nextAmount;
+ }
+
+ return output;
+ }
+ else
+ {
+ for (unsigned int i = 0; i < ud.levels.size(); i++)
+ {
+ ul = ud.levels[i];
+ if (amount < ul.count && ul.count > 0) {
+ ul = ud.levels[i - 1];
+ break;
+ }
+ amount /= ul.count;
+ }
+
+ return strprintf("%.*f%s", ul.round, amount, ul.symbol.c_str());
+ }
+ }
+}
+
+std::string Units::formatCurrency(int value)
+{
+ return formatUnit(value, UNIT_CURRENCY);
+}
+
+std::string Units::formatWeight(int value)
+{
+ return formatUnit(value, UNIT_WEIGHT);
+}
diff --git a/src/units.h b/src/units.h
new file mode 100644
index 00000000..6aa07b70
--- /dev/null
+++ b/src/units.h
@@ -0,0 +1,46 @@
+/*
+ * Support for custom units
+ * Copyright (C) 2009 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef UNITS_H
+#define UNITS_H
+
+#include <string>
+
+class Units
+{
+ public:
+ /**
+ * Loads and parses the units.xml file (if found).
+ */
+ static void loadUnits();
+
+ /**
+ * Formats the given number in the correct currency format.
+ */
+ static std::string formatCurrency(int value);
+
+ /**
+ * Formats the given number in the correct weight/mass format.
+ */
+ static std::string formatWeight(int value);
+};
+
+#endif // UNITS_H
diff --git a/src/utils/base64.cpp b/src/utils/base64.cpp
index 9d8ba836..298841be 100644
--- a/src/utils/base64.cpp
+++ b/src/utils/base64.cpp
@@ -27,11 +27,11 @@
+----------------------------------------------------------------------+
*/
+#include "utils/base64.h"
+
#include <stdlib.h>
#include <string.h>
-#include "base64.h"
-
static char base64_table[] =
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
diff --git a/src/utils/dtor.h b/src/utils/dtor.h
index 96ce63d4..e7240d12 100644
--- a/src/utils/dtor.h
+++ b/src/utils/dtor.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -40,7 +39,7 @@ public std::unary_function <std::pair<T1, T2>, void>
void operator()(std::pair<T1, T2> &pair) { delete pair.second; }
};
- template<class Cont>
+template<class Cont>
inline dtor<typename Cont::value_type> make_dtor(Cont const&)
{
return dtor<typename Cont::value_type>();
@@ -52,5 +51,4 @@ inline void delete_all(Container &c)
std::for_each(c.begin(), c.end(), make_dtor(c));
}
-
#endif
diff --git a/src/utils/gettext.h b/src/utils/gettext.h
index f7286187..55e72555 100644
--- a/src/utils/gettext.h
+++ b/src/utils/gettext.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -42,4 +41,4 @@
#endif
-#endif
+#endif // UTILS_GETTEXT_H
diff --git a/src/utils/mutex.h b/src/utils/mutex.h
index 569b6808..41701709 100644
--- a/src/utils/mutex.h
+++ b/src/utils/mutex.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2008 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,9 +22,9 @@
#ifndef MUTEX_H
#define MUTEX_H
-#include <SDL_thread.h>
+#include "log.h"
-#include "../log.h"
+#include <SDL_thread.h>
/**
* A mutex provides mutual exclusion of access to certain data that is
diff --git a/src/utils/sha256.cpp b/src/utils/sha256.cpp
new file mode 100644
index 00000000..4f23e01a
--- /dev/null
+++ b/src/utils/sha256.cpp
@@ -0,0 +1,276 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file has been slighly modified as part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * InspIRCd: (C) 2002-2008 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+/* m_sha256 - Based on m_opersha256 written by Special <john@yarbbles.com>
+ * Modified and improved by Craig Edwards, December 2006.
+ *
+ *
+ * FIPS 180-2 SHA-224/256/384/512 implementation
+ * Last update: 05/23/2005
+ * Issue date: 04/30/2005
+ *
+ * Copyright (C) 2005 Olivier Gay <olivier.gay@a3.epfl.ch>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "utils/sha256.h"
+
+#include <memory.h>
+
+#ifdef HAS_STDINT
+#include <stdint.h>
+#endif
+#ifndef HAS_STDINT
+typedef unsigned int uint32_t;
+#endif
+
+#define SHA256_BLOCK_SIZE (512 / 8)
+
+/** An sha 256 context, used by original m_opersha256 */
+class SHA256Context
+{
+ public:
+ unsigned int tot_len;
+ unsigned int len;
+ unsigned char block[2 * SHA256_BLOCK_SIZE];
+ uint32_t h[8];
+};
+
+#define SHA256_DIGEST_SIZE (256 / 8)
+
+#define SHFR(x, n) (x >> n)
+#define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
+#define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
+#define CH(x, y, z) ((x & y) ^ (~x & z))
+#define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
+
+#define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
+#define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
+#define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3))
+#define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))
+
+#define UNPACK32(x, str) \
+{ \
+ *((str) + 3) = (uint8_t) ((x) ); \
+ *((str) + 2) = (uint8_t) ((x) >> 8); \
+ *((str) + 1) = (uint8_t) ((x) >> 16); \
+ *((str) + 0) = (uint8_t) ((x) >> 24); \
+}
+
+#define PACK32(str, x) \
+{ \
+ *(x) = ((uint32_t) *((str) + 3) ) \
+ | ((uint32_t) *((str) + 2) << 8) \
+ | ((uint32_t) *((str) + 1) << 16) \
+ | ((uint32_t) *((str) + 0) << 24); \
+}
+
+/* Macros used for loops unrolling */
+
+#define SHA256_SCR(i) \
+{ \
+ w[i] = SHA256_F4(w[i - 2]) + w[i - 7] \
+ + SHA256_F3(w[i - 15]) + w[i - 16]; \
+}
+
+const unsigned int sha256_h0[8] =
+{
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+ 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+};
+
+uint32_t sha256_k[64] =
+{
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+void SHA256Init(SHA256Context *ctx)
+{
+ for (int i = 0; i < 8; i++)
+ ctx->h[i] = sha256_h0[i];
+ ctx->len = 0;
+ ctx->tot_len = 0;
+}
+
+void SHA256Transform(SHA256Context *ctx,
+ unsigned char *message,
+ unsigned int block_nb)
+{
+ uint32_t w[64];
+ uint32_t wv[8];
+ unsigned char *sub_block;
+ for (unsigned int i = 1; i <= block_nb; i++)
+ {
+ int j;
+ sub_block = message + ((i - 1) << 6);
+
+ for (j = 0; j < 16; j++)
+ PACK32(&sub_block[j << 2], &w[j]);
+ for (j = 16; j < 64; j++)
+ SHA256_SCR(j);
+ for (j = 0; j < 8; j++)
+ wv[j] = ctx->h[j];
+ for (j = 0; j < 64; j++)
+ {
+ uint32_t t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) + sha256_k[j] + w[j];
+ uint32_t t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
+ wv[7] = wv[6];
+ wv[6] = wv[5];
+ wv[5] = wv[4];
+ wv[4] = wv[3] + t1;
+ wv[3] = wv[2];
+ wv[2] = wv[1];
+ wv[1] = wv[0];
+ wv[0] = t1 + t2;
+ }
+ for (j = 0; j < 8; j++)
+ ctx->h[j] += wv[j];
+ }
+}
+
+void SHA256Update(SHA256Context *ctx,
+ unsigned char *message,
+ unsigned int len)
+{
+ /*
+ * XXX here be dragons!
+ * After many hours of pouring over this, I think I've found the problem.
+ * When Special created our module from the reference one, he used:
+ *
+ * unsigned int rem_len = SHA256_BLOCK_SIZE - ctx->len;
+ *
+ * instead of the reference's version of:
+ *
+ * unsigned int tmp_len = SHA256_BLOCK_SIZE - ctx->len;
+ * unsigned int rem_len = len < tmp_len ? len : tmp_len;
+ *
+ * I've changed back to the reference version of this code, and it seems to work with no errors.
+ * So I'm inclined to believe this was the problem..
+ * -- w00t (January 06, 2008)
+ */
+ unsigned int tmp_len = SHA256_BLOCK_SIZE - ctx->len;
+ unsigned int rem_len = len < tmp_len ? len : tmp_len;
+
+ memcpy(&ctx->block[ctx->len], message, rem_len);
+ if (ctx->len + len < SHA256_BLOCK_SIZE)
+ {
+ ctx->len += len;
+ return;
+ }
+ unsigned int new_len = len - rem_len;
+ unsigned int block_nb = new_len / SHA256_BLOCK_SIZE;
+ unsigned char *shifted_message = message + rem_len;
+ SHA256Transform(ctx, ctx->block, 1);
+ SHA256Transform(ctx, shifted_message, block_nb);
+ rem_len = new_len % SHA256_BLOCK_SIZE;
+ memcpy(ctx->block, &shifted_message[block_nb << 6],rem_len);
+ ctx->len = rem_len;
+ ctx->tot_len += (block_nb + 1) << 6;
+}
+
+void SHA256Final(SHA256Context *ctx, unsigned char *digest)
+{
+ unsigned int block_nb = (1 + ((SHA256_BLOCK_SIZE - 9) < (ctx->len % SHA256_BLOCK_SIZE)));
+ unsigned int len_b = (ctx->tot_len + ctx->len) << 3;
+ unsigned int pm_len = block_nb << 6;
+ memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
+ ctx->block[ctx->len] = 0x80;
+ UNPACK32(len_b, ctx->block + pm_len - 4);
+ SHA256Transform(ctx, ctx->block, block_nb);
+ for (int i = 0 ; i < 8; i++)
+ UNPACK32(ctx->h[i], &digest[i << 2]);
+}
+
+std::string SHA256Hash(const char *src, int len)
+{
+ // Generate the hash
+ unsigned char bytehash[SHA256_DIGEST_SIZE];
+ SHA256Context ctx;
+ SHA256Init(&ctx);
+ SHA256Update(&ctx, (unsigned char *)src, (unsigned int)len);
+ SHA256Final(&ctx, bytehash);
+ // Convert it to hex
+ const char* hxc = "0123456789abcdef";
+ std::string hash = "";
+ for (int i = 0; i < SHA256_DIGEST_SIZE; i++)
+ {
+ hash += hxc[bytehash[i] / 16];
+ hash += hxc[bytehash[i] % 16];
+ }
+ return hash;
+}
+
+std::string sha256(const std::string &string)
+{
+ return SHA256Hash(string.c_str(), string.length());
+}
diff --git a/src/utils/sha256.h b/src/utils/sha256.h
new file mode 100644
index 00000000..d0543cbf
--- /dev/null
+++ b/src/utils/sha256.h
@@ -0,0 +1,35 @@
+/*
+ * The Mana World
+ * Copyright (C) 2007 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef UTILS_SHA256_H
+#define UTILS_SHA256_H
+
+#include <string>
+
+/**
+ * Returns the SHA-256 hash for the given string.
+ *
+ * @param string the string to create the SHA-256 hash for
+ * @return the SHA-256 hash for the given string.
+ */
+std::string sha256(const std::string &string);
+
+#endif // UTILS_SHA256_H
diff --git a/src/utils/stringutils.cpp b/src/utils/stringutils.cpp
index d414d665..6a88a12e 100644
--- a/src/utils/stringutils.cpp
+++ b/src/utils/stringutils.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "stringutils.h"
+#include "utils/stringutils.h"
#include <algorithm>
diff --git a/src/utils/stringutils.h b/src/utils/stringutils.h
index 7d8df748..8b8b7bc2 100644
--- a/src/utils/stringutils.h
+++ b/src/utils/stringutils.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/utils/strprintf.cpp b/src/utils/strprintf.cpp
index f90e6258..d960bc96 100644
--- a/src/utils/strprintf.cpp
+++ b/src/utils/strprintf.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,11 +19,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "utils/strprintf.h"
+
#include <cstdarg>
#include <cstdio>
-#include "strprintf.h"
-
std::string strprintf(char const *format, ...)
{
char buf[256];
@@ -46,4 +45,3 @@ std::string strprintf(char const *format, ...)
delete [] buf2;
return res;
}
-
diff --git a/src/utils/strprintf.h b/src/utils/strprintf.h
index 1d33c3f7..78e7a04c 100644
--- a/src/utils/strprintf.h
+++ b/src/utils/strprintf.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/utils/xml.cpp b/src/utils/xml.cpp
index 562f69e3..7a6f75de 100644
--- a/src/utils/xml.cpp
+++ b/src/utils/xml.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,16 +19,16 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "xml.h"
+#include "utils/xml.h"
-#include "../log.h"
+#include "log.h"
-#include "../resources/resourcemanager.h"
+#include "resources/resourcemanager.h"
namespace XML
{
Document::Document(const std::string &filename):
- mDoc(NULL)
+ mDoc(0)
{
int size;
ResourceManager *resman = ResourceManager::getInstance();
@@ -88,7 +87,8 @@ namespace XML
return ret;
}
- std::string getProperty(xmlNodePtr node, const char *name, const std::string &def)
+ std::string getProperty(xmlNodePtr node, const char *name,
+ const std::string &def)
{
xmlChar *prop = xmlGetProp(node, BAD_CAST name);
if (prop) {
@@ -108,4 +108,5 @@ namespace XML
return NULL;
}
-}
+
+} // namespace XML
diff --git a/src/utils/xml.h b/src/utils/xml.h
index b7d67924..e7075279 100644
--- a/src/utils/xml.h
+++ b/src/utils/xml.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2004 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,10 +22,10 @@
#ifndef XML_H
#define XML_H
-#include <string>
-
#include <libxml/tree.h>
+#include <string>
+
/**
* XML helper functions.
*/
@@ -82,7 +81,8 @@ namespace XML
/**
* Gets a string property from an xmlNodePtr.
*/
- std::string getProperty(xmlNodePtr node, const char *name, const std::string &def);
+ std::string getProperty(xmlNodePtr node, const char *name,
+ const std::string &def);
/**
* Finds the first child node with the given name
@@ -93,4 +93,4 @@ namespace XML
#define for_each_xml_child_node(var, parent) \
for (xmlNodePtr var = parent->xmlChildrenNode; var; var = var->next)
-#endif
+#endif // XML_H
diff --git a/src/vector.cpp b/src/vector.cpp
index bbfb1a70..9b573e88 100644
--- a/src/vector.cpp
+++ b/src/vector.cpp
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/vector.h b/src/vector.h
index 48933155..6dd461ac 100644
--- a/src/vector.h
+++ b/src/vector.h
@@ -1,9 +1,8 @@
/*
- * Aethyra
+ * The Mana World
* Copyright (C) 2007 The Mana World Development Team
*
- * This file is part of Aethyra based on original code
- * from The Mana World.
+ * This file is part of The Mana World.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/winver.h b/src/winver.h
index a10e2e76..4996bdfb 100644
--- a/src/winver.h
+++ b/src/winver.h
@@ -1,6 +1,6 @@
-/* VERSION DEFINITIONS */
-#define VER_MAJOR 0
-#define VER_MINOR 0
-#define VER_RELEASE 29
-#define VER_BUILD 0
+/* VERSION DEFINITIONS */
+#define VER_MAJOR 0
+#define VER_MINOR 0
+#define VER_RELEASE 29
+#define VER_BUILD 0
#define PACKAGE_VERSION "0.0.29"