diff options
author | Philipp Sehmisch <crush@themanaworld.org> | 2009-08-16 17:47:51 +0200 |
---|---|---|
committer | Philipp Sehmisch <crush@themanaworld.org> | 2009-08-16 17:47:51 +0200 |
commit | e0ba8f7f67ddd08c54f0d453a316b3620d52529d (patch) | |
tree | 7324fa33f2c6af04067b77e0ce7f73d9effed1c6 | |
parent | 346d68307553c18777df4c49f9b3fe57955c5c0d (diff) | |
parent | 6460413ee2f50be561fd0824e3eaa9c2c09415b1 (diff) | |
download | mana-e0ba8f7f67ddd08c54f0d453a316b3620d52529d.tar.gz mana-e0ba8f7f67ddd08c54f0d453a316b3620d52529d.tar.bz2 mana-e0ba8f7f67ddd08c54f0d453a316b3620d52529d.tar.xz mana-e0ba8f7f67ddd08c54f0d453a316b3620d52529d.zip |
Merged changes from last month with a commit I forgot to commit before I went on vacation.
194 files changed, 3857 insertions, 3251 deletions
@@ -22,6 +22,7 @@ Eugenio Favalli <elvenprogrammer gmail.com> Eric Scrivner <zenogais gmail.com> Fate <fate.tmw googlemail.com> Fredrik Reveny <chetic gmail.com> +Freeyorp <Freeyorp101 NOSPAM hotmail.com> Guillaume Melquiond (Silene) <guillaume.melquiond gmail.com> Ira Rice <irarice gmail.com> Jan-Fabian Humann (Mra) <malastare gmx.net> diff --git a/data/graphics/gui/Makefile.am b/data/graphics/gui/Makefile.am index a2bafb29..842522ab 100644 --- a/data/graphics/gui/Makefile.am +++ b/data/graphics/gui/Makefile.am @@ -22,13 +22,17 @@ gui_DATA = \ item_shortcut_bgr.png \ mouse.png \ radioin.png \ + radioin_highlight.png \ radioout.png \ + radioout_highlight.png \ resize.png \ selection.png \ slider.png \ - sticky_button.png \ + slider_hilight.png \ speechbubble.xml \ + sticky_button.png \ tab.png \ + tab_hilight.png \ tabselected.png \ target-cursor-blue-l.png \ target-cursor-blue-m.png \ @@ -41,6 +45,7 @@ gui_DATA = \ vscroll_down_highlight.png \ vscroll_down_pressed.png \ vscroll_grey.png \ + vscroll_highlight.png \ vscroll_up_default.png \ vscroll_up_highlight.png \ vscroll_up_pressed.png \ diff --git a/data/graphics/gui/button.png b/data/graphics/gui/button.png Binary files differindex 9ebbea63..4f6a5a81 100644 --- a/data/graphics/gui/button.png +++ b/data/graphics/gui/button.png diff --git a/data/graphics/gui/button_disabled.png b/data/graphics/gui/button_disabled.png Binary files differindex 0ce3aa6f..2a8fdf43 100644 --- a/data/graphics/gui/button_disabled.png +++ b/data/graphics/gui/button_disabled.png diff --git a/data/graphics/gui/buttonhi.png b/data/graphics/gui/buttonhi.png Binary files differindex c4772634..24c09718 100644 --- a/data/graphics/gui/buttonhi.png +++ b/data/graphics/gui/buttonhi.png diff --git a/data/graphics/gui/buttonpress.png b/data/graphics/gui/buttonpress.png Binary files differindex e9cd1765..d192534a 100644 --- a/data/graphics/gui/buttonpress.png +++ b/data/graphics/gui/buttonpress.png diff --git a/data/graphics/gui/checkbox.png b/data/graphics/gui/checkbox.png Binary files differindex 669ecf03..b68893fc 100644 --- a/data/graphics/gui/checkbox.png +++ b/data/graphics/gui/checkbox.png diff --git a/data/graphics/gui/close_button.png b/data/graphics/gui/close_button.png Binary files differindex f87cc2a9..a4f802e0 100644 --- a/data/graphics/gui/close_button.png +++ b/data/graphics/gui/close_button.png diff --git a/data/graphics/gui/deepbox.png b/data/graphics/gui/deepbox.png Binary files differindex 084b5f61..6b63168a 100644 --- a/data/graphics/gui/deepbox.png +++ b/data/graphics/gui/deepbox.png diff --git a/data/graphics/gui/gui.xml b/data/graphics/gui/gui.xml index f27dbc7f..015c6ce3 100644 --- a/data/graphics/gui/gui.xml +++ b/data/graphics/gui/gui.xml @@ -1,18 +1,19 @@ <skinset name="Default" image="window.png"> <widget type="Window"> + <!-- <option name="padding" value="5" /> --> <!-- Top Row --> - <part type="top-left-corner" xpos="0" ypos="0" width="4" height="4" /> - <part type="top-edge" xpos="4" ypos="0" width="32" height="4" /> - <part type="top-right-corner" xpos="36" ypos="0" width="4" height="4" /> + <part type="top-left-corner" xpos="0" ypos="0" width="10" height="10" /> + <part type="top-edge" xpos="11" ypos="0" width="127" height="10" /> + <part type="top-right-corner" xpos="139" ypos="0" width="12" height="10" /> <!-- Middle Row --> - <part type="left-edge" xpos="0" ypos="4" width="4" height="216" /> - <part type="bg-quad" xpos="4" ypos="4" width="32" height="216" /> - <part type="right-edge" xpos="36" ypos="4" width="4" height="216" /> + <part type="left-edge" xpos="0" ypos="11" width="10" height="81" /> + <part type="bg-quad" xpos="11" ypos="11" width="127" height="81" /> + <part type="right-edge" xpos="139" ypos="11" width="12" height="81" /> <!-- Bottom Row --> - <part type="bottom-left-corner" xpos="0" ypos="220" width="4" height="4" /> - <part type="bottom-edge" xpos="4" ypos="220" width="32" height="4" /> - <part type="bottom-right-corner" xpos="36" ypos="220" width="4" height="4" /> + <part type="bottom-left-corner" xpos="0" ypos="93" width="10" height="12" /> + <part type="bottom-edge" xpos="11" ypos="93" width="127" height="12" /> + <part type="bottom-right-corner" xpos="139" ypos="93" width="12" height="12" /> </widget> </skinset> diff --git a/data/graphics/gui/hscroll_left_default.png b/data/graphics/gui/hscroll_left_default.png Binary files differindex 2f763d30..07e5e078 100644 --- a/data/graphics/gui/hscroll_left_default.png +++ b/data/graphics/gui/hscroll_left_default.png diff --git a/data/graphics/gui/hscroll_left_highlight.png b/data/graphics/gui/hscroll_left_highlight.png Binary files differindex 6be5ae25..c77427f8 100644 --- a/data/graphics/gui/hscroll_left_highlight.png +++ b/data/graphics/gui/hscroll_left_highlight.png diff --git a/data/graphics/gui/hscroll_left_pressed.png b/data/graphics/gui/hscroll_left_pressed.png Binary files differindex b8ebcb46..081eaa3a 100644 --- a/data/graphics/gui/hscroll_left_pressed.png +++ b/data/graphics/gui/hscroll_left_pressed.png diff --git a/data/graphics/gui/hscroll_right_default.png b/data/graphics/gui/hscroll_right_default.png Binary files differindex 33fdddd0..ee74c071 100644 --- a/data/graphics/gui/hscroll_right_default.png +++ b/data/graphics/gui/hscroll_right_default.png diff --git a/data/graphics/gui/hscroll_right_highlight.png b/data/graphics/gui/hscroll_right_highlight.png Binary files differindex e9e633ea..9f8911e4 100644 --- a/data/graphics/gui/hscroll_right_highlight.png +++ b/data/graphics/gui/hscroll_right_highlight.png diff --git a/data/graphics/gui/hscroll_right_pressed.png b/data/graphics/gui/hscroll_right_pressed.png Binary files differindex 53972f2b..6ef987a5 100644 --- a/data/graphics/gui/hscroll_right_pressed.png +++ b/data/graphics/gui/hscroll_right_pressed.png diff --git a/data/graphics/gui/item_shortcut_bgr.png b/data/graphics/gui/item_shortcut_bgr.png Binary files differindex 0543e38a..5b3c5e7c 100644 --- a/data/graphics/gui/item_shortcut_bgr.png +++ b/data/graphics/gui/item_shortcut_bgr.png diff --git a/data/graphics/gui/radioin.png b/data/graphics/gui/radioin.png Binary files differindex 12e027fe..8d0e5f74 100644 --- a/data/graphics/gui/radioin.png +++ b/data/graphics/gui/radioin.png diff --git a/data/graphics/gui/radioin_highlight.png b/data/graphics/gui/radioin_highlight.png Binary files differnew file mode 100644 index 00000000..c020f0ba --- /dev/null +++ b/data/graphics/gui/radioin_highlight.png diff --git a/data/graphics/gui/radioout.png b/data/graphics/gui/radioout.png Binary files differindex 5eb67bd8..70a25256 100644 --- a/data/graphics/gui/radioout.png +++ b/data/graphics/gui/radioout.png diff --git a/data/graphics/gui/radioout_highlight.png b/data/graphics/gui/radioout_highlight.png Binary files differnew file mode 100644 index 00000000..957a1fa6 --- /dev/null +++ b/data/graphics/gui/radioout_highlight.png diff --git a/data/graphics/gui/resize.png b/data/graphics/gui/resize.png Binary files differindex 6b31ac64..dfe79ebf 100644 --- a/data/graphics/gui/resize.png +++ b/data/graphics/gui/resize.png diff --git a/data/graphics/gui/selection.png b/data/graphics/gui/selection.png Binary files differindex 78827daf..a117a78a 100644 --- a/data/graphics/gui/selection.png +++ b/data/graphics/gui/selection.png diff --git a/data/graphics/gui/slider.png b/data/graphics/gui/slider.png Binary files differindex 465ad0e8..df9abe56 100644 --- a/data/graphics/gui/slider.png +++ b/data/graphics/gui/slider.png diff --git a/data/graphics/gui/slider_hilight.png b/data/graphics/gui/slider_hilight.png Binary files differnew file mode 100644 index 00000000..8b7d2be6 --- /dev/null +++ b/data/graphics/gui/slider_hilight.png diff --git a/data/graphics/gui/sticky_button.png b/data/graphics/gui/sticky_button.png Binary files differindex 8c570573..2708dd99 100644 --- a/data/graphics/gui/sticky_button.png +++ b/data/graphics/gui/sticky_button.png diff --git a/data/graphics/gui/tab.png b/data/graphics/gui/tab.png Binary files differindex 91eadf08..689981a9 100644 --- a/data/graphics/gui/tab.png +++ b/data/graphics/gui/tab.png diff --git a/data/graphics/gui/tab_hilight.png b/data/graphics/gui/tab_hilight.png Binary files differnew file mode 100644 index 00000000..d0585e8f --- /dev/null +++ b/data/graphics/gui/tab_hilight.png diff --git a/data/graphics/gui/tabselected.png b/data/graphics/gui/tabselected.png Binary files differindex e2983060..72a48973 100644 --- a/data/graphics/gui/tabselected.png +++ b/data/graphics/gui/tabselected.png diff --git a/data/graphics/gui/vscroll_down_default.png b/data/graphics/gui/vscroll_down_default.png Binary files differindex c4292489..0ec2a3ee 100644 --- a/data/graphics/gui/vscroll_down_default.png +++ b/data/graphics/gui/vscroll_down_default.png diff --git a/data/graphics/gui/vscroll_down_highlight.png b/data/graphics/gui/vscroll_down_highlight.png Binary files differindex ac88f7c7..d2934daa 100644 --- a/data/graphics/gui/vscroll_down_highlight.png +++ b/data/graphics/gui/vscroll_down_highlight.png diff --git a/data/graphics/gui/vscroll_down_pressed.png b/data/graphics/gui/vscroll_down_pressed.png Binary files differindex 9dcc89f6..6aa44ba6 100644 --- a/data/graphics/gui/vscroll_down_pressed.png +++ b/data/graphics/gui/vscroll_down_pressed.png diff --git a/data/graphics/gui/vscroll_grey.png b/data/graphics/gui/vscroll_grey.png Binary files differindex f99da467..3f65a883 100644 --- a/data/graphics/gui/vscroll_grey.png +++ b/data/graphics/gui/vscroll_grey.png diff --git a/data/graphics/gui/vscroll_highlight.png b/data/graphics/gui/vscroll_highlight.png Binary files differnew file mode 100644 index 00000000..9802044c --- /dev/null +++ b/data/graphics/gui/vscroll_highlight.png diff --git a/data/graphics/gui/vscroll_up_default.png b/data/graphics/gui/vscroll_up_default.png Binary files differindex 1cecc351..73a4266f 100644 --- a/data/graphics/gui/vscroll_up_default.png +++ b/data/graphics/gui/vscroll_up_default.png diff --git a/data/graphics/gui/vscroll_up_highlight.png b/data/graphics/gui/vscroll_up_highlight.png Binary files differindex 7b5009f3..6fc3884d 100644 --- a/data/graphics/gui/vscroll_up_highlight.png +++ b/data/graphics/gui/vscroll_up_highlight.png diff --git a/data/graphics/gui/vscroll_up_pressed.png b/data/graphics/gui/vscroll_up_pressed.png Binary files differindex 2320ec42..bfa8e175 100644 --- a/data/graphics/gui/vscroll_up_pressed.png +++ b/data/graphics/gui/vscroll_up_pressed.png diff --git a/data/graphics/gui/window.png b/data/graphics/gui/window.png Binary files differindex f0ef1af4..671b7740 100644 --- a/data/graphics/gui/window.png +++ b/data/graphics/gui/window.png diff --git a/data/graphics/images/login_wallpaper.png b/data/graphics/images/login_wallpaper.png Binary files differindex 7af4f913..abb023f2 100644 --- a/data/graphics/images/login_wallpaper.png +++ b/data/graphics/images/login_wallpaper.png diff --git a/po/POTFILES.in b/po/POTFILES.in index 0ff7bda6..39959413 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -14,7 +14,8 @@ src/gui/charcreatedialog.cpp src/gui/charselectdialog.cpp src/gui/chat.cpp src/gui/confirmdialog.cpp -src/gui/connection.cpp +src/gui/connectiondialog.cpp +src/gui/debugwindow.cpp src/gui/equipmentwindow.cpp src/gui/guildwindow.cpp src/gui/help.cpp @@ -27,6 +28,7 @@ src/gui/minimap.cpp src/gui/npcdialog.cpp src/gui/npcpostdialog.cpp src/gui/okdialog.cpp +src/gui/outfitwindow.cpp src/gui/palette.cpp src/gui/partywindow.cpp src/gui/popupmenu.cpp @@ -46,9 +48,8 @@ src/gui/setup_joystick.cpp src/gui/setup_keyboard.cpp src/gui/setup_players.cpp src/gui/setup_video.cpp -src/gui/skill.cpp src/gui/skilldialog.cpp -src/gui/status.cpp +src/gui/statuswindow.cpp src/gui/storagewindow.cpp src/gui/textdialog.cpp src/gui/trade.cpp @@ -71,9 +72,10 @@ src/net/ea/generalhandler.cpp src/net/ea/gui/partytab.cpp src/net/ea/inventoryhandler.cpp src/net/ea/loginhandler.cpp +src/net/ea/maphandler.cpp src/net/ea/partyhandler.cpp src/net/ea/playerhandler.cpp -src/net/ea/skillhandler.cpp +src/net/ea/specialhandler.cpp src/net/ea/tradehandler.cpp src/net/tmwserv/beinghandler.cpp src/net/tmwserv/charserverhandler.cpp @@ -84,6 +86,7 @@ src/net/tmwserv/loginhandler.cpp src/net/tmwserv/partyhandler.cpp src/net/tmwserv/playerhandler.cpp src/net/tmwserv/tradehandler.cpp +src/playerrelations.cpp src/resources/itemdb.cpp src/resources/monsterdb.cpp src/utils/gettext.h @@ -11,7 +11,7 @@ msgstr "" "Report-Msgid-Bugs-To: themanaworld-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2009-06-09 21:24+0200\n" "PO-Revision-Date: 2009-01-09 12:36+0000\n" -"Last-Translator: Bjørn Lindeijer <bjorn@lindeijer.nl>\n" +"Last-Translator: Marco Castelluccio <markos30@hotmail.it>\n" "Language-Team: Italian\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -21,23 +21,23 @@ msgstr "" #: src/commandhandler.cpp:113 src/commandhandler.cpp:273 msgid "Unknown command." -msgstr "" +msgstr "Comando sconosciuto." #: src/commandhandler.cpp:142 msgid "-- Help --" -msgstr "" +msgstr "-- Aiuto --" #: src/commandhandler.cpp:143 msgid "/help > Display this help" -msgstr "" +msgstr "/help > Mostra questo aiuto" #: src/commandhandler.cpp:145 msgid "/where > Display map name" -msgstr "" +msgstr "/where > Mostra il nome della mappa" #: src/commandhandler.cpp:146 msgid "/who > Display number of online users" -msgstr "" +msgstr "/who > Mostra il numero degli utenti online" #: src/commandhandler.cpp:147 msgid "/me > Tell something about yourself" @@ -45,39 +45,39 @@ msgstr "" #: src/commandhandler.cpp:149 msgid "/clear > Clears this window" -msgstr "" +msgstr "/clear > Pulisci questa finestra" #: src/commandhandler.cpp:151 msgid "/msg > Send a private message to a user" -msgstr "" +msgstr "/msg > Invia un messaggio privato a un utente" #: src/commandhandler.cpp:152 msgid "/whisper > Alias of msg" -msgstr "" +msgstr "/whisper > Alias di msg" #: src/commandhandler.cpp:153 msgid "/w > Alias of msg" -msgstr "" +msgstr "/w > Alias di msg" #: src/commandhandler.cpp:154 msgid "/query > Makes a tab for private messages with another user" -msgstr "" +msgstr "/query > Crea una scheda per i messaggi privati con un altro utente" #: src/commandhandler.cpp:155 msgid "/q > Alias of query" -msgstr "" +msgstr "/q > Alias di query" #: src/commandhandler.cpp:157 msgid "/list > Display all public channels" -msgstr "" +msgstr "/list > Mostra tutti i canali pubblici" #: src/commandhandler.cpp:158 msgid "/join > Join or create a channel" -msgstr "" +msgstr "/join > Entra o crea un canale" #: src/commandhandler.cpp:160 msgid "/party > Invite a user to party" -msgstr "" +msgstr "/party > Invita un utente in un party" #: src/commandhandler.cpp:162 msgid "/record > Start recording the chat to an external file" @@ -277,7 +277,7 @@ msgstr "" #: src/commandhandler.cpp:340 msgid "Cannot send empty whispers!" -msgstr "" +msgstr "Impossibile inviare sussurri vuoti!" #: src/commandhandler.cpp:348 #, c-format @@ -289,7 +289,7 @@ msgstr "" #: src/commandhandler.cpp:362 #, c-format msgid "Requesting to join channel %s." -msgstr "" +msgstr "Richiesa di entrare nel canale %s." #: src/commandhandler.cpp:394 msgid "Return toggles chat." @@ -314,12 +314,12 @@ msgstr "" #: src/engine.cpp:88 msgid "Could not load map" -msgstr "" +msgstr "Impossibile caricare la mappa" #: src/engine.cpp:89 #, c-format msgid "Error while loading %s" -msgstr "" +msgstr "Errore durante il caricamento di %s" #: src/game.cpp:237 msgid "General" @@ -327,19 +327,19 @@ msgstr "" #: src/game.cpp:404 msgid "Screenshot saved to ~/" -msgstr "" +msgstr "Screenshot salvata in ~/" #: src/game.cpp:409 msgid "Saving screenshot failed!" -msgstr "" +msgstr "Salvataggio screenshot fallito!" #: src/game.cpp:485 msgid "The connection to the server was lost, the program will now quit" -msgstr "" +msgstr "Connessione al server persa. Prego, riavviare il gioco" #: src/game.cpp:491 msgid "Network Error" -msgstr "" +msgstr "Errore di Rete" #: src/game.cpp:657 src/gui/buy.cpp:71 src/gui/quitdialog.cpp:32 #: src/gui/quitdialog.cpp:35 src/gui/quitdialog.cpp:36 src/gui/sell.cpp:73 @@ -349,7 +349,7 @@ msgstr "Esci" #: src/game.cpp:658 msgid "Are you sure you want to quit?" -msgstr "" +msgstr "Sicuro di voler uscire?" #: src/game.cpp:665 msgid "no" @@ -365,11 +365,11 @@ msgstr "" #: src/gui/buddywindow.cpp:35 msgid "Buddy" -msgstr "" +msgstr "Amico" #: src/gui/buddywindow.cpp:38 msgid "Buddy List" -msgstr "" +msgstr "Lista Amici" #: src/gui/buy.cpp:46 src/gui/buy.cpp:70 src/gui/buysell.cpp:40 msgid "Buy" @@ -379,11 +379,11 @@ msgstr "Compra" #: src/gui/sell.cpp:278 #, c-format msgid "Price: %s / Total: %s" -msgstr "" +msgstr "Prezzo: %s / Totale: %s" #: src/gui/buy.cpp:72 src/gui/sell.cpp:74 msgid "Max" -msgstr "" +msgstr "Massimo" #: src/gui/buy.cpp:73 src/gui/buy.cpp:223 src/gui/buy.cpp:241 #: src/gui/sell.cpp:75 src/gui/sell.cpp:250 src/gui/sell.cpp:264 @@ -399,7 +399,7 @@ msgstr "Effetto : %s" #: src/gui/buysell.cpp:34 msgid "Shop" -msgstr "" +msgstr "Negozio" #: src/gui/buysell.cpp:40 src/gui/sell.cpp:46 src/gui/sell.cpp:72 msgid "Sell" @@ -414,12 +414,12 @@ msgstr "Vendi" #: src/gui/setup.cpp:73 src/gui/textdialog.cpp:37 #: src/gui/unregisterdialog.cpp:53 src/gui/updatewindow.cpp:112 msgid "Cancel" -msgstr "Cancella" +msgstr "Annulla" #: src/gui/changeemaildialog.cpp:43 src/gui/changeemaildialog.cpp:52 #: src/gui/charselectdialog.cpp:115 msgid "Change Email Address" -msgstr "" +msgstr "Cambia indirizzo email" #: src/gui/changeemaildialog.cpp:47 src/gui/changepassworddialog.cpp:51 #: src/gui/charselectdialog.cpp:107 @@ -429,21 +429,21 @@ msgstr "" #: src/gui/changeemaildialog.cpp:49 msgid "Type New Email Address twice:" -msgstr "" +msgstr "Inserisci il nuovo indirizzo email due volte:" #: src/gui/changepassworddialog.cpp:46 src/gui/changepassworddialog.cpp:55 #: src/gui/charselectdialog.cpp:110 msgid "Change Password" -msgstr "" +msgstr "Cambia password" #: src/gui/changepassworddialog.cpp:60 src/gui/login.cpp:52 #: src/gui/register.cpp:61 src/gui/unregisterdialog.cpp:50 msgid "Password:" -msgstr "Password:" +msgstr "" #: src/gui/changepassworddialog.cpp:62 msgid "Type new password twice:" -msgstr "" +msgstr "Inserisci la nuova password due volte:" #: src/gui/charcreatedialog.cpp:54 msgid "Create Character" @@ -452,11 +452,11 @@ msgstr "Crea Personaggio" #: src/gui/charcreatedialog.cpp:66 src/gui/login.cpp:51 #: src/gui/register.cpp:60 msgid "Name:" -msgstr "Nome :" +msgstr "Nome:" #: src/gui/charcreatedialog.cpp:69 msgid "Hair Color:" -msgstr "Colore Capelli" +msgstr "Colore Capelli:" #: src/gui/charcreatedialog.cpp:72 msgid "Hair Style:" @@ -464,20 +464,20 @@ msgstr "Stile Capelli:" #: src/gui/charcreatedialog.cpp:73 msgid "Create" -msgstr "Create" +msgstr "Crea" #: src/gui/charcreatedialog.cpp:75 src/gui/register.cpp:75 msgid "Male" -msgstr "" +msgstr "Maschio" #: src/gui/charcreatedialog.cpp:76 src/gui/register.cpp:76 msgid "Female" -msgstr "" +msgstr "Femmina" #: src/gui/charcreatedialog.cpp:94 src/gui/charcreatedialog.cpp:234 #, c-format msgid "Please distribute %d points" -msgstr "Prego distribuisci %d points" +msgstr "Prego distribuire %d punti" #: src/gui/charcreatedialog.cpp:172 src/gui/register.cpp:222 #: src/gui/serverdialog.cpp:163 src/main.cpp:1517 @@ -496,19 +496,19 @@ msgstr "Statistiche personaggio OK" #: src/gui/charcreatedialog.cpp:238 #, c-format msgid "Please remove %d points" -msgstr "Prego rimuovi %d punti" +msgstr "Prego rimuovere %d punti" #: src/gui/charselectdialog.cpp:77 msgid "Confirm Character Delete" -msgstr "" +msgstr "Conferma Eliminazione Personaggio" #: src/gui/charselectdialog.cpp:78 msgid "Are you sure you want to delete this character?" -msgstr "Sei sicuro di voler cancellare questo personaggio?" +msgstr "Sei sicuro di voler eliminare questo personaggio?" #: src/gui/charselectdialog.cpp:95 msgid "Account and Character Management" -msgstr "" +msgstr "Gestione Account e Personaggio" #: src/gui/charselectdialog.cpp:103 src/gui/login.cpp:74 #: src/gui/okdialog.cpp:42 src/gui/quitdialog.cpp:39 @@ -530,7 +530,7 @@ msgstr "Prossimo" #: src/gui/unregisterdialog.cpp:49 #, c-format msgid "Name: %s" -msgstr "Nome : %s" +msgstr "Nome: %s" #: src/gui/charselectdialog.cpp:109 src/gui/charselectdialog.cpp:118 #: src/gui/charselectdialog.cpp:298 src/gui/charselectdialog.cpp:318 @@ -563,14 +563,14 @@ msgstr "Monete: %d" #: src/gui/charselectdialog.cpp:320 #, c-format msgid "Job Level: %d" -msgstr "" +msgstr "Livello Job: %d" #: src/gui/charselectdialog.cpp:155 src/gui/charselectdialog.cpp:303 #: src/gui/charselectdialog.cpp:322 src/gui/status.cpp:57 #: src/gui/status.cpp:182 #, c-format msgid "Money: %s" -msgstr "" +msgstr "Soldi: %s" #: src/gui/chat.cpp:73 src/gui/palette.cpp:93 msgid "Chat" @@ -579,7 +579,7 @@ msgstr "" #: src/gui/chat.cpp:326 #, c-format msgid "%d players are present." -msgstr "" +msgstr "Sono presenti %d giocatori." #: src/gui/chat.cpp:327 msgid "Present: " @@ -592,7 +592,7 @@ msgstr "" #: src/gui/chat.cpp:471 #, c-format msgid "Whispering to %s: %s" -msgstr "" +msgstr "Sussurrando a %s: %s" #: src/gui/confirmdialog.cpp:42 msgid "Yes" @@ -617,27 +617,27 @@ msgstr "Rimuovi" #: src/gui/guildwindow.cpp:50 src/gui/guildwindow.cpp:54 msgid "Guild" -msgstr "" +msgstr "Gilda" #: src/gui/guildwindow.cpp:63 msgid "Create Guild" -msgstr "" +msgstr "Crea Gilda" #: src/gui/guildwindow.cpp:64 msgid "Invite User" -msgstr "" +msgstr "Invita Utente" #: src/gui/guildwindow.cpp:65 msgid "Quit Guild" -msgstr "" +msgstr "Lascia Gilda" #: src/gui/help.cpp:34 msgid "Help" -msgstr "" +msgstr "Aiuto" #: src/gui/help.cpp:47 src/gui/npcdialog.cpp:44 src/gui/storagewindow.cpp:68 msgid "Close" -msgstr "" +msgstr "Chiudi" #: src/gui/inventorywindow.cpp:54 src/gui/windowmenu.cpp:61 msgid "Inventory" @@ -663,11 +663,11 @@ msgstr "Lascia" #: src/gui/inventorywindow.cpp:92 src/gui/storagewindow.cpp:78 msgid "Slots:" -msgstr "" +msgstr "Spazi:" #: src/gui/inventorywindow.cpp:93 msgid "Weight:" -msgstr "" +msgstr "Peso:" #: src/gui/itemamount.cpp:95 msgid "Ok" @@ -675,7 +675,7 @@ msgstr "Ok" #: src/gui/itemamount.cpp:97 msgid "All" -msgstr "" +msgstr "Tutti" #: src/gui/itemamount.cpp:123 msgid "Select amount of items to trade." @@ -687,11 +687,11 @@ msgstr "Seleziona la quantità di oggetti da lasciare." #: src/gui/itemamount.cpp:129 msgid "Select amount of items to store." -msgstr "" +msgstr "Seleziona la quantità di oggetti da depositare." #: src/gui/itemamount.cpp:132 msgid "Select amount of items to retrieve." -msgstr "" +msgstr "Seleziona la quantità di oggetti da recuperare." #: src/gui/itemamount.cpp:135 msgid "Select amount of items to split." @@ -699,7 +699,7 @@ msgstr "Seleziona la quantità di oggetti da lasciare." #: src/gui/itempopup.cpp:91 msgid "Weight: " -msgstr "" +msgstr "Peso: " #: src/gui/login.cpp:48 msgid "Login" @@ -708,7 +708,7 @@ msgstr "Autenticazione" #: src/gui/login.cpp:54 src/gui/register.cpp:64 src/gui/serverdialog.cpp:76 #: src/gui/widgets/chattab.cpp:135 msgid "Server:" -msgstr "Server:" +msgstr "" #: src/gui/login.cpp:55 src/gui/register.cpp:65 src/gui/serverdialog.cpp:77 msgid "Port:" @@ -716,11 +716,11 @@ msgstr "Porta:" #: src/gui/login.cpp:56 msgid "Recent:" -msgstr "" +msgstr "Recente:" #: src/gui/login.cpp:73 msgid "Remember Username" -msgstr "" +msgstr "Ricorda Username" #: src/gui/login.cpp:76 src/gui/register.cpp:56 src/gui/register.cpp:80 msgid "Register" @@ -746,11 +746,11 @@ msgstr "" #: src/gui/minimap.cpp:45 src/gui/minimap.cpp:84 #, fuzzy msgid "Map" -msgstr "Mini mappa" +msgstr "Mappa" #: src/gui/npcdialog.cpp:42 msgid "Waiting for server" -msgstr "" +msgstr "In attesa del server" #: src/gui/npcdialog.cpp:45 #, fuzzy @@ -759,7 +759,7 @@ msgstr "Esci" #: src/gui/npcdialog.cpp:48 src/gui/npcpostdialog.cpp:39 msgid "NPC" -msgstr "NPC" +msgstr "PNG" #: src/gui/npcdialog.cpp:104 msgid "Reset" @@ -767,11 +767,11 @@ msgstr "" #: src/gui/npcpostdialog.cpp:44 msgid "To:" -msgstr "" +msgstr "A:" #: src/gui/npcpostdialog.cpp:51 msgid "Send" -msgstr "" +msgstr "Invia" #: src/gui/npcpostdialog.cpp:85 msgid "Failed to send as sender or letter invalid." @@ -779,7 +779,7 @@ msgstr "" #: src/gui/palette.cpp:81 src/gui/setup_video.cpp:142 msgid "Text" -msgstr "" +msgstr "Testo" #: src/gui/palette.cpp:82 msgid "Text Shadow" @@ -795,7 +795,7 @@ msgstr "" #: src/gui/palette.cpp:86 msgid "Background" -msgstr "" +msgstr "Sfondo" #: src/gui/palette.cpp:88 msgid "Highlight" @@ -807,11 +807,11 @@ msgstr "" #: src/gui/palette.cpp:90 msgid "Item too expensive" -msgstr "" +msgstr "Oggetto troppo caro" #: src/gui/palette.cpp:91 msgid "Item is equipped" -msgstr "" +msgstr "Oggetto equipaggiato" #: src/gui/palette.cpp:94 msgid "GM" @@ -819,15 +819,15 @@ msgstr "" #: src/gui/palette.cpp:95 msgid "Player" -msgstr "" +msgstr "Giocatore" #: src/gui/palette.cpp:96 msgid "Whisper" -msgstr "" +msgstr "Sussurro" #: src/gui/palette.cpp:97 msgid "Is" -msgstr "" +msgstr "E'" #: src/gui/palette.cpp:98 src/gui/partywindow.cpp:48 #: src/gui/partywindow.cpp:75 src/net/ea/gui/partytab.cpp:39 @@ -852,23 +852,23 @@ msgstr "" #: src/gui/palette.cpp:104 msgid "Other Players' Names" -msgstr "" +msgstr "Nomi Giocatori" #: src/gui/palette.cpp:105 msgid "Own Name" -msgstr "" +msgstr "Proprio Nome" #: src/gui/palette.cpp:106 msgid "GM Names" -msgstr "" +msgstr "Nomi GM" #: src/gui/palette.cpp:107 msgid "NPCs" -msgstr "" +msgstr "PNG" #: src/gui/palette.cpp:108 msgid "Monsters" -msgstr "" +msgstr "Mostri" #: src/gui/palette.cpp:110 msgid "Unknown Item Type" @@ -898,11 +898,11 @@ msgstr "" #: src/gui/palette.cpp:116 msgid "Pants" -msgstr "" +msgstr "Pantaloni" #: src/gui/palette.cpp:117 msgid "Shoes" -msgstr "" +msgstr "Scarpe" #: src/gui/palette.cpp:118 msgid "2 Handed Weapons" @@ -915,7 +915,7 @@ msgstr "Abilità " #: src/gui/palette.cpp:120 msgid "Rings" -msgstr "" +msgstr "Anelli" #: src/gui/palette.cpp:121 msgid "Necklaces" @@ -927,7 +927,7 @@ msgstr "" #: src/gui/palette.cpp:123 msgid "Ammo" -msgstr "" +msgstr "Munizioni" #: src/gui/palette.cpp:125 msgid "Particle Effects" @@ -985,35 +985,35 @@ msgstr "" #: src/gui/partywindow.cpp:182 #, c-format msgid "%s has invited you to join their party." -msgstr "" +msgstr "%s ti ha invitato a entrare nel loro party." #: src/gui/partywindow.cpp:185 #, c-format msgid "%s has invited you to join the %s party." -msgstr "" +msgstr "%s ti ha invitato a entrare nel party %s." #: src/gui/partywindow.cpp:191 msgid "Accept Party Invite" -msgstr "" +msgstr "Accetta Invito Party" #: src/gui/partywindow.cpp:204 #, c-format msgid "Accepted invite from %s." -msgstr "" +msgstr "Invito di %s accettato." #: src/gui/partywindow.cpp:211 #, c-format msgid "Rejected invite from %s." -msgstr "" +msgstr "Invito di %s rifiutato." #: src/gui/popupmenu.cpp:77 msgid "@@name|Add name to chat@@" -msgstr "" +msgstr "@@name|Aggiungi il name alla chat@@" #: src/gui/popupmenu.cpp:89 #, c-format msgid "@@trade|Trade With %s@@" -msgstr "@@trade|Scambia Con %s@@" +msgstr "@@trade|Scambia con %s@@" #: src/gui/popupmenu.cpp:90 src/gui/popupmenu.cpp:138 #, c-format @@ -1033,7 +1033,7 @@ msgstr "" #: src/gui/popupmenu.cpp:100 #, c-format msgid "@@ignore|Ignore %s@@" -msgstr "" +msgstr "@@ignore|Ignora %s@@" #: src/gui/popupmenu.cpp:104 src/gui/popupmenu.cpp:109 #, c-format @@ -1043,35 +1043,35 @@ msgstr "" #: src/gui/popupmenu.cpp:105 #, c-format msgid "@@ignore|Completely ignore %s@@" -msgstr "" +msgstr "@@ignore|Ignora completamente %s@@" #: src/gui/popupmenu.cpp:116 #, c-format msgid "@@guild|Invite %s to join your guild@@" -msgstr "" +msgstr "@@guild|Invita %s a entrare nella tua gilda@@" #: src/gui/popupmenu.cpp:119 #, c-format msgid "@@party|Invite %s to join your party@@" -msgstr "" +msgstr "@@party|Invita %s a entrare nel tuo party@@" #: src/gui/popupmenu.cpp:124 msgid "@@admin-kick|Kick player@@" -msgstr "" +msgstr "@@admin-kick|Caccia giocatore@@" #: src/gui/popupmenu.cpp:132 #, c-format msgid "@@talk|Talk To %s@@" -msgstr "" +msgstr "@@talk|Parla a %s@@" #: src/gui/popupmenu.cpp:141 msgid "@@admin-kick|Kick monster@@" -msgstr "" +msgstr "@@admin-kick|Caccia mostro@@" #: src/gui/popupmenu.cpp:152 src/gui/popupmenu.cpp:170 #: src/gui/popupmenu.cpp:383 msgid "@@cancel|Cancel@@" -msgstr "@@cancel|Cancella@@" +msgstr "@@cancel|Annulla@@" #: src/gui/popupmenu.cpp:165 #, fuzzy, c-format @@ -1080,11 +1080,11 @@ msgstr "@@pickup|Raccogli %s@@" #: src/gui/popupmenu.cpp:166 src/gui/popupmenu.cpp:381 msgid "@@chat|Add to chat@@" -msgstr "" +msgstr "@@chat|Aggiungi alla chat@@" #: src/gui/popupmenu.cpp:356 msgid "@@use|Unequip@@" -msgstr "" +msgstr "@@use|Rimuovi@@" #: src/gui/popupmenu.cpp:358 msgid "@@use|Equip@@" @@ -1109,7 +1109,7 @@ msgstr "@@usa|Usa@@" #: src/gui/popupmenu.cpp:379 msgid "@@retrieve|Retrieve@@" -msgstr "" +msgstr "@@retrieve|Recupera@@" #: src/gui/quitdialog.cpp:37 msgid "Switch server" @@ -1181,7 +1181,7 @@ msgstr "Le password non corrispondono." #: src/gui/serverdialog.cpp:74 msgid "Choose your server" -msgstr "" +msgstr "Scegli il server" #: src/gui/serverdialog.cpp:164 msgid "Please type both the address and the port of a server." @@ -1189,7 +1189,7 @@ msgstr "Per favore inserisci l'indirizzo e la porta del server." #: src/gui/serverselectdialog.cpp:59 msgid "Select Server" -msgstr "" +msgstr "Scegli il server" #: src/gui/setup.cpp:65 src/gui/windowmenu.cpp:69 src/main.cpp:939 msgid "Setup" @@ -1225,11 +1225,11 @@ msgstr "" #: src/gui/setup_colors.cpp:50 msgid "Colors" -msgstr "" +msgstr "Colori" #: src/gui/setup_colors.cpp:71 msgid "Type: " -msgstr "" +msgstr "Tipo: " #: src/gui/setup_colors.cpp:82 src/gui/setup_colors.cpp:430 msgid "Static" @@ -1256,15 +1256,15 @@ msgstr "" #: src/gui/setup_colors.cpp:108 msgid "Red: " -msgstr "" +msgstr "Rosso: " #: src/gui/setup_colors.cpp:123 msgid "Green: " -msgstr "" +msgstr "Verde: " #: src/gui/setup_colors.cpp:138 msgid "Blue: " -msgstr "" +msgstr "Blu: " #: src/gui/setup_joystick.cpp:37 src/gui/setup_joystick.cpp:78 msgid "Press the button to start calibration" @@ -2600,19 +2600,19 @@ msgstr "" #: src/net/ea/playerhandler.cpp:96 src/net/tmwserv/beinghandler.cpp:312 msgid "You are dead." -msgstr "" +msgstr "Sei morto." #: src/net/ea/playerhandler.cpp:97 src/net/tmwserv/beinghandler.cpp:313 msgid "We regret to inform you that your character was killed in battle." -msgstr "" +msgstr "Ci dispiace informarti che il tuo personaggio è stato ucciso in battaglia. Ora dormi sepolto in un campo di grano, non è la rosa non è il tulipano che ti fan veglia dall'ombra dei fossi, ma sono mille papaveri rossi." #: src/net/ea/playerhandler.cpp:99 src/net/tmwserv/beinghandler.cpp:314 msgid "You are not that alive anymore." -msgstr "" +msgstr "Non sei più cosi vivo." #: src/net/ea/playerhandler.cpp:100 src/net/tmwserv/beinghandler.cpp:315 msgid "The cold hands of the grim reaper are grabbing for your soul." -msgstr "" +msgstr "Le fredde mani della morte nera si stanno aggrappando alla tua squallida anima." #: src/net/ea/playerhandler.cpp:101 src/net/tmwserv/beinghandler.cpp:316 msgid "Game Over!" @@ -2626,70 +2626,70 @@ msgstr "" msgid "" "No, kids. Your character did not really die. It... err... went to a better " "place." -msgstr "" +msgstr "No, piccolo. Il tuo personaggio non è veramente morto. Lui... ehm... è andato in un posto migliore." #: src/net/ea/playerhandler.cpp:105 src/net/tmwserv/beinghandler.cpp:318 msgid "" "Your plan of breaking your enemies weapon by bashing it with your throat " "failed." -msgstr "" +msgstr "Il tuo piano di rompere le armi nemiche colpendole con la tua gola è fallito." #: src/net/ea/playerhandler.cpp:107 src/net/tmwserv/beinghandler.cpp:319 msgid "I guess this did not run too well." -msgstr "" +msgstr "Sembra proprio che non ha funzionato tanto bene." #: src/net/ea/playerhandler.cpp:109 src/net/tmwserv/beinghandler.cpp:320 msgid "Do you want your possessions identified?" -msgstr "" +msgstr "Vuoi che i tuoi beni vengano identificati?" #: src/net/ea/playerhandler.cpp:111 src/net/tmwserv/beinghandler.cpp:321 msgid "Sadly, no trace of you was ever found..." -msgstr "" +msgstr "Tristemente, nessuna traccia di te è stata mai ritrovata..." #: src/net/ea/playerhandler.cpp:113 src/net/tmwserv/beinghandler.cpp:322 msgid "Annihilated." -msgstr "" +msgstr "Annichilato." #: src/net/ea/playerhandler.cpp:115 src/net/tmwserv/beinghandler.cpp:323 msgid "Looks like you got your head handed to you." -msgstr "" +msgstr "Sembra che almeno la tua testa ti sia stata restituita." #: src/net/ea/playerhandler.cpp:117 src/net/tmwserv/beinghandler.cpp:324 msgid "" "You screwed up again, dump your body down the tubes and get you another one." -msgstr "" +msgstr "Sei stato accartocciato di nuovo, scarica il tuo corpo nelle fogne e cercatene un altro." #: src/net/ea/playerhandler.cpp:120 msgid "You're not dead yet. You're just resting." -msgstr "" +msgstr "Ma quando mai! Non sei mica morto! Stai solo riposando..." #: src/net/ea/playerhandler.cpp:121 msgid "You are no more." -msgstr "" +msgstr "Non sei più." #: src/net/ea/playerhandler.cpp:122 msgid "You have ceased to be." -msgstr "" +msgstr "Hai cessato di esistere." #: src/net/ea/playerhandler.cpp:123 msgid "You've expired and gone to meet your maker." -msgstr "" +msgstr "Il Clostridium botulinum ti ha infettato (in parole povere per te che sei ignorante, sei scaduto) e sei andato a trovare il tuo artefice metafisico." #: src/net/ea/playerhandler.cpp:124 msgid "You're a stiff." -msgstr "" +msgstr "Ci dispiace molto, ma sei appena diventato un cadavere." #: src/net/ea/playerhandler.cpp:125 msgid "Bereft of life, you rest in peace." -msgstr "" +msgstr "Privo di vita, requiescas in pace." #: src/net/ea/playerhandler.cpp:126 msgid "If you weren't so animated, you'd be pushing up the daisies." -msgstr "" +msgstr "Se non fossi così animato, staresti raccogliendo le margheritine." #: src/net/ea/playerhandler.cpp:127 msgid "Your metabolic processes are now history." -msgstr "" +msgstr "I tuoi processi metabolici ora sono storia." #: src/net/ea/playerhandler.cpp:128 msgid "You're off the twig." @@ -2697,7 +2697,7 @@ msgstr "" #: src/net/ea/playerhandler.cpp:129 msgid "You've kicked the bucket." -msgstr "" +msgstr "Sei crepato. Malamente." #: src/net/ea/playerhandler.cpp:130 msgid "" @@ -2707,7 +2707,7 @@ msgstr "" #: src/net/ea/playerhandler.cpp:132 msgid "You are an ex-player." -msgstr "" +msgstr "Sei un ex-giocatore." #: src/net/ea/playerhandler.cpp:133 msgid "You're pining for the fjords." @@ -2715,24 +2715,24 @@ msgstr "" #: src/net/ea/playerhandler.cpp:246 src/net/ea/playerhandler.cpp:270 msgid "Message" -msgstr "" +msgstr "Messaggio" #: src/net/ea/playerhandler.cpp:247 msgid "" "You are carrying more than half your weight. You are unable to regain health." -msgstr "" +msgstr "Stai portando più della metà del tuo peso. Non puoi riacquistare salute." #: src/net/ea/playerhandler.cpp:290 msgid "You picked up " -msgstr "" +msgstr "Hai preso " #: src/net/ea/playerhandler.cpp:413 msgid "Equip arrows first." -msgstr "" +msgstr "Equipaggia prima delle freccie." #: src/net/ea/skillhandler.cpp:139 msgid "Trade failed!" -msgstr "" +msgstr "Scambio fallito!" #: src/net/ea/skillhandler.cpp:142 msgid "Emote failed!" @@ -2752,11 +2752,11 @@ msgstr "" #: src/net/ea/skillhandler.cpp:154 msgid "Cannot shout!" -msgstr "" +msgstr "Non puoi gridare!" #: src/net/ea/skillhandler.cpp:163 msgid "You have not yet reached a high enough lvl!" -msgstr "" +msgstr "Non hai raggiunto un livello abbastanza alto!" #: src/net/ea/skillhandler.cpp:166 msgid "Insufficient HP!" @@ -2859,11 +2859,11 @@ msgstr "" #: src/net/ea/tradehandler.cpp:220 src/net/tmwserv/tradehandler.cpp:147 msgid "Trade canceled." -msgstr "" +msgstr "Scambio annullato." #: src/net/ea/tradehandler.cpp:227 src/net/tmwserv/tradehandler.cpp:154 msgid "Trade completed." -msgstr "" +msgstr "Scambio completato." #: src/net/tmwserv/beinghandler.cpp:328 msgid " Press OK to respawn" @@ -2871,11 +2871,11 @@ msgstr "" #: src/net/tmwserv/beinghandler.cpp:329 msgid "You died" -msgstr "" +msgstr "Sei morto" #: src/net/tmwserv/charserverhandler.cpp:219 msgid "No gameservers are available." -msgstr "" +msgstr "Nessun gameserver disponibile." #: src/net/tmwserv/charserverhandler.cpp:258 msgid "Willpower:" @@ -2884,7 +2884,7 @@ msgstr "Volontà :" #: src/net/tmwserv/chathandler.cpp:158 src/net/tmwserv/guildhandler.cpp:250 #, c-format msgid "Topic: %s" -msgstr "" +msgstr "Argomento: %s" #: src/net/tmwserv/generalhandler.cpp:87 #, fuzzy, c-format @@ -2893,23 +2893,23 @@ msgstr "Volontà :" #: src/net/tmwserv/guildhandler.cpp:74 msgid "Guild created." -msgstr "" +msgstr "Gilda creata." #: src/net/tmwserv/guildhandler.cpp:79 msgid "Error creating guild." -msgstr "" +msgstr "Errore nella creazione della gilda." #: src/net/tmwserv/guildhandler.cpp:89 msgid "Invite sent." -msgstr "" +msgstr "Invito inviato." #: src/net/tmwserv/guildhandler.cpp:194 msgid "Member was promoted successfully." -msgstr "" +msgstr "Membro promosso con successo." #: src/net/tmwserv/guildhandler.cpp:199 msgid "Failed to promote member." -msgstr "" +msgstr "Impossibile promuovere membro." #: src/net/tmwserv/loginhandler.cpp:80 msgid "Wrong magic_token" @@ -2917,60 +2917,60 @@ msgstr "" #: src/net/tmwserv/loginhandler.cpp:83 src/net/tmwserv/loginhandler.cpp:182 msgid "Already logged in" -msgstr "" +msgstr "Login già effettuato" #: src/net/tmwserv/loginhandler.cpp:86 src/net/tmwserv/loginhandler.cpp:185 msgid "Server is full" -msgstr "" +msgstr "Il server è pieno" #: src/net/tmwserv/loginhandler.cpp:110 msgid "New password incorrect" -msgstr "" +msgstr "Nuova password non corretta" #: src/net/tmwserv/loginhandler.cpp:116 src/net/tmwserv/loginhandler.cpp:146 msgid "Account not connected. Please login first." -msgstr "" +msgstr "Account non connesso. Per favore, effettuare prima il login" #: src/net/tmwserv/loginhandler.cpp:140 msgid "New email address incorrect" -msgstr "" +msgstr "Nuovo indirizzo email non corretto" #: src/net/tmwserv/loginhandler.cpp:143 msgid "Old email address incorrect" -msgstr "" +msgstr "Vecchio indirizzo email non corretto" #: src/net/tmwserv/loginhandler.cpp:149 msgid "The new Email Address already exists." -msgstr "" +msgstr "Nuovo indirizzo email già presente." #: src/net/tmwserv/loginhandler.cpp:176 src/net/tmwserv/loginhandler.cpp:208 msgid "Client version is too old" -msgstr "" +msgstr "Versione del client troppo vecchia" #: src/net/tmwserv/loginhandler.cpp:179 msgid "Wrong username or password" -msgstr "" +msgstr "Username o password non corretti" #: src/net/tmwserv/loginhandler.cpp:211 msgid "Wrong username, password or email address" -msgstr "" +msgstr "Username, passowrd o indirizzo email non corretti" #: src/net/tmwserv/loginhandler.cpp:214 msgid "Username already exists" -msgstr "" +msgstr "Username già presente" #: src/net/tmwserv/loginhandler.cpp:217 msgid "Email address already exists" -msgstr "" +msgstr "Indirizzo email già presente" #: src/net/tmwserv/partyhandler.cpp:86 msgid "Joined party." -msgstr "" +msgstr "Entrato nel party." #: src/net/tmwserv/partyhandler.cpp:103 #, c-format msgid "%s joined the party." -msgstr "" +msgstr "%s è entrato nel party." #: src/net/tmwserv/tradehandler.cpp:93 msgid "Accepting incoming trade requests." @@ -2983,7 +2983,7 @@ msgstr "" #: src/net/tmwserv/tradehandler.cpp:133 #, c-format msgid "Trading with %s" -msgstr "" +msgstr "Commercia con %s" #: src/resources/itemdb.cpp:52 #, c-format diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 91fe8e06..43726f9d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -110,6 +110,8 @@ SET(SRCS gui/widgets/textfield.h gui/widgets/textpreview.cpp gui/widgets/textpreview.h + gui/widgets/vertcontainer.cpp + gui/widgets/vertcontainer.h gui/widgets/whispertab.cpp gui/widgets/whispertab.h gui/widgets/window.cpp @@ -213,10 +215,14 @@ SET(SRCS gui/shortcutcontainer.h gui/shortcutwindow.cpp gui/shortcutwindow.h + gui/skilldialog.cpp + gui/skilldialog.h gui/skin.cpp gui/skin.h gui/speechbubble.cpp gui/speechbubble.h + gui/statuswindow.cpp + gui/statuswindow.h gui/storagewindow.cpp gui/storagewindow.h gui/table.cpp @@ -258,7 +264,7 @@ SET(SRCS net/partyhandler.h net/playerhandler.h net/serverinfo.h - net/skillhandler.h + net/specialhandler.h net/tradehandler.h resources/action.cpp resources/action.h @@ -298,6 +304,8 @@ SET(SRCS resources/resource.h resources/resourcemanager.cpp resources/resourcemanager.h + resources/sdlrescalefacility.h + resources/sdlrescalefacility.cpp resources/soundeffect.h resources/soundeffect.cpp resources/spritedef.h @@ -416,10 +424,6 @@ SET(SRCS ) SET(SRCS_EA - gui/skill.cpp - gui/skill.h - gui/status.cpp - gui/status.h net/ea/gui/partytab.cpp net/ea/gui/partytab.h net/ea/adminhandler.cpp @@ -455,8 +459,8 @@ SET(SRCS_EA net/ea/playerhandler.cpp net/ea/playerhandler.h net/ea/protocol.h - net/ea/skillhandler.cpp - net/ea/skillhandler.h + net/ea/specialhandler.cpp + net/ea/specialhandler.h net/ea/tradehandler.cpp net/ea/tradehandler.h ) @@ -478,10 +482,6 @@ SET(SRCS_TMW 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 @@ -543,8 +543,8 @@ SET(SRCS_TMW net/tmwserv/playerhandler.cpp net/tmwserv/playerhandler.h net/tmwserv/protocol.h - net/tmwserv/skillhandler.cpp - net/tmwserv/skillhandler.h + net/tmwserv/specialhandler.cpp + net/tmwserv/specialhandler.h net/tmwserv/tradehandler.cpp net/tmwserv/tradehandler.h guild.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 23de64bc..25fdb140 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -59,6 +59,8 @@ tmw_SOURCES = gui/widgets/avatar.cpp \ gui/widgets/textfield.h \ gui/widgets/textpreview.cpp \ gui/widgets/textpreview.h \ + gui/widgets/vertcontainer.cpp \ + gui/widgets/vertcontainer.h \ gui/widgets/whispertab.cpp \ gui/widgets/whispertab.h \ gui/widgets/window.cpp \ @@ -162,10 +164,14 @@ tmw_SOURCES = gui/widgets/avatar.cpp \ gui/shortcutcontainer.h \ gui/shortcutwindow.cpp \ gui/shortcutwindow.h \ + gui/skilldialog.cpp \ + gui/skilldialog.h \ gui/skin.cpp \ gui/skin.h \ gui/speechbubble.cpp \ gui/speechbubble.h \ + gui/statuswindow.cpp \ + gui/statuswindow.h \ gui/storagewindow.cpp \ gui/storagewindow.h \ gui/table.cpp \ @@ -207,7 +213,7 @@ tmw_SOURCES = gui/widgets/avatar.cpp \ net/partyhandler.h \ net/playerhandler.h \ net/serverinfo.h \ - net/skillhandler.h \ + net/specialhandler.h \ net/tradehandler.h \ resources/action.cpp \ resources/action.h \ @@ -247,6 +253,8 @@ tmw_SOURCES = gui/widgets/avatar.cpp \ resources/resource.h \ resources/resourcemanager.cpp \ resources/resourcemanager.h \ + resources/sdlrescalefacility.cpp \ + resources/sdlrescalefacility.h \ resources/soundeffect.h \ resources/soundeffect.cpp \ resources/spritedef.h \ @@ -382,10 +390,6 @@ tmw_SOURCES += \ 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 \ @@ -447,8 +451,8 @@ tmw_SOURCES += \ net/tmwserv/playerhandler.cpp \ net/tmwserv/playerhandler.h \ net/tmwserv/protocol.h \ - net/tmwserv/skillhandler.cpp \ - net/tmwserv/skillhandler.h \ + net/tmwserv/specialhandler.cpp \ + net/tmwserv/specialhandler.h \ net/tmwserv/tradehandler.cpp \ net/tmwserv/tradehandler.h \ guild.cpp \ @@ -458,10 +462,6 @@ endif if SERVER_EATHENA tmw_CXXFLAGS += -DEATHENA_SUPPORT tmw_SOURCES += \ - gui/skill.cpp \ - gui/skill.h \ - gui/status.cpp \ - gui/status.h \ net/ea/gui/partytab.cpp \ net/ea/gui/partytab.h \ net/ea/adminhandler.cpp \ @@ -497,8 +497,8 @@ tmw_SOURCES += \ net/ea/playerhandler.cpp \ net/ea/playerhandler.h \ net/ea/protocol.h \ - net/ea/skillhandler.cpp \ - net/ea/skillhandler.h \ + net/ea/specialhandler.cpp \ + net/ea/specialhandler.h \ net/ea/tradehandler.cpp \ net/ea/tradehandler.h endif diff --git a/src/being.cpp b/src/being.cpp index ea587afb..23b87e6c 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -49,7 +49,6 @@ #include "gui/speechbubble.h" #include "utils/dtor.h" -#include "utils/gettext.h" #include "utils/stringutils.h" #include "utils/xml.h" @@ -66,7 +65,6 @@ static const int DEFAULT_HEIGHT = 32; Being::Being(int id, int job, Map *map): #ifdef EATHENA_SUPPORT - mX(0), mY(0), mWalkTime(0), #endif mEmotion(0), mEmotionTime(0), @@ -100,6 +98,7 @@ Being::Being(int id, int job, Map *map): mWalkSpeed(150), #endif mPx(0), mPy(0), + mX(0), mY(0), mUsedTargetCursor(NULL) { setMap(map); @@ -148,37 +147,21 @@ void Being::setDestination(Uint16 destX, Uint16 destY) #endif #ifdef TMWSERV_SUPPORT - -void Being::adjustCourse(int srcX, int srcY) -{ - setDestination(srcX, srcY, mDest.x, mDest.y); -} - void Being::setDestination(int dstX, int dstY) { - setDestination(mPos.x, mPos.y, dstX, dstY); -} + mDest.x = dstX; + mDest.y = dstY; + int srcX = mPos.x; + int srcY = mPos.y; -Path Being::findPath() -{ - Path path; + Path thisPath; if (mMap) { - path = mMap->findPath(mPos.x / 32, mPos.y / 32, - mDest.x / 32, mDest.y / 32, getWalkMask()); + thisPath = mMap->findPath(mPos.x / 32, mPos.y / 32, + mDest.x / 32, mDest.y / 32, getWalkMask()); } - return path; -} - -void Being::setDestination(int srcX, int srcY, int dstX, int dstY) -{ - mDest.x = dstX; - mDest.y = dstY; - - Path thisPath = findPath(); - if (thisPath.empty()) { setPath(Path()); @@ -188,16 +171,13 @@ void Being::setDestination(int srcX, int srcY, int dstX, int dstY) // FIXME: Look into making this code neater. // Interpolate the offsets. Also convert from tile based to pixel based - // Note: I divided the offsets by 32 then muilpied it back to get the top left - // Conner of where the tile is. (If you know a better way then please change it) - // Find the starting offset - int startX = srcX - ((srcX / 32) * 32 + 16); - int startY = srcY - ((srcY / 32) * 32 + 16); + int startX = (srcX % 32); + int startY = (srcY % 32); // Find the ending offset - int endX = dstX - ((dstX / 32) * 32 + 16); - int endY = dstY - ((dstY / 32) * 32 + 16); + int endX = (dstX % 32); + int endY = (dstY % 32); // Find the distance, and divide it by the number of steps int changeX = (endX - startX) / thisPath.size(); @@ -209,8 +189,8 @@ void Being::setDestination(int srcX, int srcY, int dstX, int dstY) int i = 0; while(it != thisPath.end()) { - it->x = (it->x * 32 + 16) + startX + (changeX * i); - it->y = (it->y * 32 + 16) + startY + (changeY * i); + it->x = (it->x * 32) + startX + (changeX * i); + it->y = (it->y * 32) + startY + (changeY * i); i++; it++; } @@ -228,7 +208,7 @@ void Being::setPath(const Path &path) { mPath = path; #ifdef TMWSERV_SUPPORT -// std::cout << this << " New path: " << path << std::endl; + std::cout << this << " New path: " << path << std::endl; #else if (mAction != WALK && mAction != DEAD) { diff --git a/src/being.h b/src/being.h index 9213a2dc..6e90b39d 100644 --- a/src/being.h +++ b/src/being.h @@ -149,7 +149,6 @@ class Being : public Sprite, public ConfigListener enum { DOWN = 1, LEFT = 2, UP = 4, RIGHT = 8 }; #ifdef EATHENA_SUPPORT - Uint16 mX, mY; /**< Tile coordinates */ int mFrame; int mWalkTime; #endif @@ -184,30 +183,30 @@ class Being : public Sprite, public ConfigListener virtual void setDestination(Uint16 destX, Uint16 destY); #else /** - * Returns the path to the being's current destination + * Creates a path for the being from current position to ex and ey */ - virtual Path findPath(); + void setDestination(int ex, int ey); /** - * Creates a path for the being from sx,sy to ex,ey + * Returns the destination for this being. */ - void setDestination(int sx, int sy, int ex, int ey); + const Vector &getDestination() const { return mDest; } +#endif /** - * Creates a path for the being from current position to ex and ey + * Returns the tile x or y coord */ - void setDestination(int ex, int ey); + int getTileX() const + { return mX; } - /** - * Adjusts course to expected start point. - */ - void adjustCourse(int srcX, int srcY); + int getTileY() const + { return mY; } /** - * Returns the destination for this being. + * Sets the tile x or y coord */ - const Vector &getDestination() const { return mDest; } -#endif + void setTileCoords(int x, int y) + { mX = x; mY = y; } /** * Puts a "speech balloon" above this being for the specified amount @@ -603,6 +602,7 @@ class Being : public Sprite, public ConfigListener Vector mPos; Vector mDest; int mPx, mPy; /**< Position in pixels */ + int mX, mY; /**< Position on tile */ /** Target cursor being used */ SimpleAnimation* mUsedTargetCursor; diff --git a/src/beingmanager.cpp b/src/beingmanager.cpp index 284f1343..0b8f71b5 100644 --- a/src/beingmanager.cpp +++ b/src/beingmanager.cpp @@ -40,14 +40,9 @@ class FindBeingFunctor 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)); } @@ -242,7 +237,7 @@ Being *BeingManager::findNearestLivingBeing(int x, int y, int maxdist, 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); + int d = abs(being->getTileX() - x) + abs(being->getTileY() - y); #endif if ((being->getType() == type || type == Being::UNKNOWN) @@ -268,8 +263,8 @@ Being *BeingManager::findNearestLivingBeing(Being *aroundBeing, int maxdist, int y = apos.y; maxdist = maxdist * 32; #else - int x = aroundBeing->mX; - int y = aroundBeing->mY; + int x = aroundBeing->getTileX(); + int y = aroundBeing->getTileY(); #endif for (Beings::const_iterator i = mBeings.begin(), i_end = mBeings.end(); @@ -280,7 +275,7 @@ Being *BeingManager::findNearestLivingBeing(Being *aroundBeing, int maxdist, 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); + int d = abs(being->getTileX() - x) + abs(being->getTileY() - y); #endif if ((being->getType() == type || type == Being::UNKNOWN) diff --git a/src/commandhandler.cpp b/src/commandhandler.cpp index d2a303e8..e64da120 100644 --- a/src/commandhandler.cpp +++ b/src/commandhandler.cpp @@ -207,7 +207,7 @@ void CommandHandler::handleHelp(const std::string &args, ChatTab *tab) else if (args == "ignore") { tab->chatLog(_("Command: /ignore <player>")); - tab->chatLog(_("This command ignores the given player reguardless of " + tab->chatLog(_("This command ignores the given player regardless of " "current relations.")); } else if (args == "join") @@ -397,7 +397,7 @@ void CommandHandler::handleParty(const std::string &args, ChatTab *tab) if (args != "") Net::getPartyHandler()->invite(args); else - tab->chatLog("Please specify a name.", BY_SERVER); + tab->chatLog(_("Please specify a name."), BY_SERVER); } void CommandHandler::handleMe(const std::string &args, ChatTab *tab) diff --git a/src/engine.cpp b/src/engine.cpp index d33607ec..f56f8a49 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -85,7 +85,7 @@ bool Engine::changeMap(const std::string &mapPath) if (!newMap) { logger->log("Error while loading %s", map_path.c_str()); - new OkDialog(_("Could not load map"), + new OkDialog(_("Could Not Load Map"), strprintf(_("Error while loading %s"), map_path.c_str())); } diff --git a/src/equipment.cpp b/src/equipment.cpp index f760067c..41722300 100644 --- a/src/equipment.cpp +++ b/src/equipment.cpp @@ -21,27 +21,14 @@ #include "equipment.h" #include "item.h" -#ifdef EATHENA_SUPPORT -#include "inventory.h" -#include "localplayer.h" -#endif #include <algorithm> Equipment::Equipment() -#ifdef EATHENA_SUPPORT - : mArrows(-1) -#endif { -#ifdef TMWSERV_SUPPORT std::fill_n(mEquipment, EQUIPMENT_SIZE, (Item*) 0); -#else - std::fill_n(mEquipment, EQUIPMENT_SIZE, -1); -#endif } -#ifdef TMWSERV_SUPPORT - Equipment::~Equipment() { clear(); @@ -55,29 +42,14 @@ void Equipment::clear() std::fill_n(mEquipment, EQUIPMENT_SIZE, (Item*) 0); } -void Equipment::setEquipment(int index, int id) +void Equipment::setEquipment(int index, int id, int quantity) { 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); - if (item) - item->setEquipped(true); -} + mEquipment[index] = (id > 0) ? new Item(id, quantity) : 0; -void Equipment::removeEquipment(int index) -{ - if (index >= 0 && index < EQUIPMENT_SIZE) - mEquipment[index] = -1; + if (mEquipment[index]) + mEquipment[index]->setInvIndex(index); } - -#endif diff --git a/src/equipment.h b/src/equipment.h index 5bebf78d..c7058269 100644 --- a/src/equipment.h +++ b/src/equipment.h @@ -22,11 +22,7 @@ #ifndef EQUIPMENT_H #define EQUIPMENT_H -#ifdef TMWSERV_SUPPORT #define EQUIPMENT_SIZE 11 -#else -#define EQUIPMENT_SIZE 10 -#endif class Item; @@ -38,63 +34,45 @@ class Equipment */ Equipment(); -#ifdef TMWSERV_SUPPORT /** * Destructor. */ ~Equipment(); -#endif + + enum EquipmentSlots + { + EQUIP_TORSO_SLOT = 0, + EQUIP_GLOVES_SLOT = 1, + EQUIP_HEAD_SLOT = 2, + EQUIP_LEGS_SLOT = 3, + EQUIP_FEET_SLOT = 4, + EQUIP_RING1_SLOT = 5, + EQUIP_RING2_SLOT = 6, + EQUIP_NECK_SLOT = 7, + EQUIP_FIGHT1_SLOT = 8, + EQUIP_FIGHT2_SLOT = 9, + EQUIP_PROJECTILE_SLOT = 10, + EQUIP_VECTOREND + }; /** * 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. - */ - void removeEquipment(int index); - - /** - * Returns the item used in the arrow slot. - */ - int getArrows() const { return mArrows; } - - /** - * Set the item used in the arrow slot. - */ - void setArrows(int arrows) { mArrows = arrows; } -#endif + void setEquipment(int index, int id, int quantity = 0); private: -#ifdef TMWSERV_SUPPORT Item *mEquipment[EQUIPMENT_SIZE]; -#else - int mEquipment[EQUIPMENT_SIZE]; - int mArrows; -#endif }; #endif diff --git a/src/game.cpp b/src/game.cpp index f1df57cc..ff0d84f7 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -62,8 +62,8 @@ #include "gui/sdlinput.h" #include "gui/sell.h" #include "gui/setup.h" -#include "gui/skill.h" -#include "gui/status.h" +#include "gui/skilldialog.h" +#include "gui/statuswindow.h" #include "gui/trade.h" #include "gui/viewport.h" #include "gui/windowmenu.h" @@ -206,6 +206,8 @@ int get_elapsed_time(int start_time) */ static void createGuiWindows() { + setupWindow->clearWindowsForReset(); + // Create dialogs chatWindow = new ChatWindow; buyDialog = new BuyDialog; @@ -214,17 +216,16 @@ static void createGuiWindows() partyWindow = new PartyWindow; #ifdef TMWSERV_SUPPORT magicDialog = new MagicDialog; - equipmentWindow = new EquipmentWindow(player_node->mEquipment.get()); buddyWindow = new BuddyWindow; guildWindow = new GuildWindow; #else buySellDialog = new BuySellDialog; - equipmentWindow = new EquipmentWindow; #endif + equipmentWindow = new EquipmentWindow(player_node->mEquipment.get()); npcDialog = new NpcDialog; npcPostDialog = new NpcPostDialog; storageWindow = new StorageWindow; - statusWindow = new StatusWindow(player_node); + statusWindow = new StatusWindow; miniStatusWindow = new MiniStatusWindow; inventoryWindow = new InventoryWindow; skillDialog = new SkillDialog; @@ -405,6 +406,7 @@ static bool saveScreenshot() if (success) { std::stringstream chatlogentry; + // TODO: Make it one complete gettext string below chatlogentry << _("Screenshot saved to ~/") << filenameSuffix.str(); localChatTab->chatLog(chatlogentry.str(), BY_SERVER); } @@ -763,8 +765,8 @@ void Game::handleInput() Uint16 x = (int) pos.x / 32; Uint16 y = (int) pos.y / 32; #else - Uint16 x = player_node->mX; - Uint16 y = player_node->mY; + Uint16 x = player_node->getTileX(); + Uint16 y = player_node->getTileY(); #endif FloorItem *item = floorItemManager->findByCoordinates(x, y); @@ -937,14 +939,9 @@ 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 diff --git a/src/graphics.cpp b/src/graphics.cpp index 58f643e9..75db11f4 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -120,11 +120,47 @@ bool Graphics::drawImage(Image *image, int x, int y) return drawImage(image, 0, 0, x, y, image->mBounds.w, image->mBounds.h); } +bool Graphics::drawRescaledImage(Image *image, int srcX, int srcY, + int dstX, int dstY, + int width, int height, + int desiredWidth, int desiredHeight, + bool useColor) +{ + // Check that preconditions for blitting are met. + if (!mScreen || !image) return false; + if (!image->mImage) return false; + + Image *tmpImage = image->SDLgetScaledImage(desiredWidth, desiredHeight); + bool returnValue = false; + if (!tmpImage) return false; + if (!tmpImage->mImage) return false; + + dstX += mClipStack.top().xOffset; + dstY += mClipStack.top().yOffset; + + srcX += image->mBounds.x; + srcY += image->mBounds.y; + + SDL_Rect dstRect; + SDL_Rect srcRect; + dstRect.x = dstX; dstRect.y = dstY; + srcRect.x = srcX; srcRect.y = srcY; + srcRect.w = width; + srcRect.h = height; + + returnValue = !(SDL_BlitSurface(tmpImage->mImage, &srcRect, mScreen, &dstRect) < 0); + + delete tmpImage; + + return returnValue; +} + bool Graphics::drawImage(Image *image, int srcX, int srcY, int dstX, int dstY, int width, int height, bool) { // Check that preconditions for blitting are met. - if (!mScreen || !image || !image->mImage) return false; + if (!mScreen || !image) return false; + if (!image->mImage) return false; dstX += mClipStack.top().xOffset; dstY += mClipStack.top().yOffset; @@ -154,7 +190,8 @@ void Graphics::drawImage(gcn::Image const *image, int srcX, int srcY, void Graphics::drawImagePattern(Image *image, int x, int y, int w, int h) { // Check that preconditions for blitting are met. - if (!mScreen || !image || !image->mImage) return; + if (!mScreen || !image) return; + if (!image->mImage) return; const int iw = image->getWidth(); const int ih = image->getHeight(); @@ -184,6 +221,48 @@ void Graphics::drawImagePattern(Image *image, int x, int y, int w, int h) } } +void Graphics::drawRescaledImagePattern(Image *image, int x, int y, + int w, int h, int scaledWidth, int scaledHeight) +{ + // Check that preconditions for blitting are met. + if (!mScreen || !image) return; + if (!image->mImage) return; + + if (scaledHeight == 0 || scaledWidth == 0) return; + + Image *tmpImage = image->SDLgetScaledImage(scaledWidth, scaledHeight); + if (!tmpImage) return; + + const int iw = tmpImage->getWidth(); + const int ih = tmpImage->getHeight(); + + if (iw == 0 || ih == 0) return; + + for (int py = 0; py < h; py += ih) // Y position on pattern plane + { + int dh = (py + ih >= h) ? h - py : ih; + int srcY = tmpImage->mBounds.y; + int dstY = y + py + mClipStack.top().yOffset; + + for (int px = 0; px < w; px += iw) // X position on pattern plane + { + int dw = (px + iw >= w) ? w - px : iw; + int srcX = tmpImage->mBounds.x; + int dstX = x + px + mClipStack.top().xOffset; + + SDL_Rect dstRect; + SDL_Rect srcRect; + dstRect.x = dstX; dstRect.y = dstY; + srcRect.x = srcX; srcRect.y = srcY; + srcRect.w = dw; srcRect.h = dh; + + SDL_BlitSurface(tmpImage->mImage, &srcRect, mScreen, &dstRect); + } + } + + delete tmpImage; +} + void Graphics::drawImageRect(int x, int y, int w, int h, Image *topLeft, Image *topRight, Image *bottomLeft, Image *bottomRight, diff --git a/src/graphics.h b/src/graphics.h index d0e70c24..b8e87af1 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -29,6 +29,9 @@ class ImageRect; struct SDL_Surface; +static const int defaultScreenWidth = 800; +static const int defaultScreenHeight = 600; + /** * 9 images defining a rectangle. 4 corners, 4 sides and a middle area. The * topology is as follows: @@ -105,6 +108,28 @@ class Graphics : public gcn::SDLGraphics int dstX, int dstY, int width, int height); /** + * Draws a resclaled version of the image + */ + bool drawRescaledImage(Image *image, int srcX, int srcY, + int dstX, int dstY, + int width, int height, + int desiredWidth, int desiredHeight) + { return drawRescaledImage(image, srcX, srcY, + dstX, dstY, + width, height, + desiredWidth, desiredHeight, + false); }; + + /** + * Draws a resclaled version of the image + */ + virtual bool drawRescaledImage(Image *image, int srcX, int srcY, + int dstX, int dstY, + int width, int height, + int desiredWidth, int desiredHeight, + bool useColor = false); + + /** * Blits an image onto the screen. * * @return <code>true</code> if the image was blitted properly @@ -121,6 +146,13 @@ class Graphics : public gcn::SDLGraphics int w, int h); /** + * Draw a pattern based on a rescaled version of the given image... + */ + virtual void drawRescaledImagePattern(Image *image, + int x, int y, int w, int h, + int scaledWidth, int scaledHeight); + + /** * Draws a rectangle using images. 4 corner images, 4 side images and 1 * image for the inside. */ diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp index 5b393a06..a2398472 100644 --- a/src/gui/buy.cpp +++ b/src/gui/buy.cpp @@ -27,6 +27,7 @@ #include "gui/widgets/scrollarea.h" #include "gui/widgets/slider.h" +#include "gui/setup.h" #include "gui/shop.h" #include "gui/shoplistbox.h" @@ -47,6 +48,7 @@ BuyDialog::BuyDialog(): mMoney(0), mAmountItems(0), mMaxItems(0) { setWindowName("Buy"); + setupWindow->registerWindowForReset(this); setResizable(true); setCloseButton(true); setMinWidth(260); @@ -65,8 +67,12 @@ BuyDialog::BuyDialog(): mMoneyLabel = new Label(strprintf(_("Price: %s / Total: %s"), "", "")); - mIncreaseButton = new Button("+", "+", this); - mDecreaseButton = new Button("-", "-", this); + // TRANSLATORS: This is a narrow symbol used to denote 'increasing'. + // You may change this symbol if your language uses another. + mIncreaseButton = new Button(_("+"), "inc", this); + // TRANSLATORS: This is a narrow symbol used to denote 'decreasing'. + // You may change this symbol if your language uses another. + mDecreaseButton = new Button(_("-"), "dec", this); mBuyButton = new Button(_("Buy"), "buy", this); mQuitButton = new Button(_("Quit"), "quit", this); mAddMaxButton = new Button(_("Max"), "max", this); @@ -160,13 +166,13 @@ void BuyDialog::action(const gcn::ActionEvent &event) mAmountItems = (int) mSlider->getValue(); updateButtonsAndLabels(); } - else if (event.getId() == "+" && mAmountItems < mMaxItems) + else if (event.getId() == "inc" && mAmountItems < mMaxItems) { mAmountItems++; mSlider->setValue(mAmountItems); updateButtonsAndLabels(); } - else if (event.getId() == "-" && mAmountItems > 1) + else if (event.getId() == "dec" && mAmountItems > 1) { mAmountItems--; mSlider->setValue(mAmountItems); diff --git a/src/gui/buysell.cpp b/src/gui/buysell.cpp index 53c2419a..c96c9f24 100644 --- a/src/gui/buysell.cpp +++ b/src/gui/buysell.cpp @@ -24,6 +24,7 @@ #include "npc.h" #include "gui/widgets/button.h" +#include "gui/setup.h" #include "net/net.h" #include "net/npchandler.h" @@ -35,6 +36,7 @@ BuySellDialog::BuySellDialog(): mBuyButton(0) { setWindowName("BuySell"); + setupWindow->registerWindowForReset(this); static const char *buttonNames[] = { N_("Buy"), N_("Sell"), N_("Cancel"), 0 diff --git a/src/gui/changeemaildialog.cpp b/src/gui/changeemaildialog.cpp index d36ab487..eb05e25e 100644 --- a/src/gui/changeemaildialog.cpp +++ b/src/gui/changeemaildialog.cpp @@ -46,7 +46,7 @@ ChangeEmailDialog::ChangeEmailDialog(Window *parent, LoginData *loginData): { gcn::Label *accountLabel = new Label(strprintf(_("Account: %s"), mLoginData->username.c_str())); - gcn::Label *newEmailLabel = new Label(_("Type New Email Address twice:")); + gcn::Label *newEmailLabel = new Label(_("Type new email address twice:")); mFirstEmailField = new TextField; mSecondEmailField = new TextField; mChangeEmailButton = new Button(_("Change Email Address"), "change_email", this); @@ -114,29 +114,29 @@ ChangeEmailDialog::action(const gcn::ActionEvent &event) logger->log("ChangeEmailDialog::Email change, Username is %s", username.c_str()); - std::stringstream errorMsg; + std::stringstream errorMessage; 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."; + errorMessage << strprintf(_("The new email address needs to be at " + "least %d characters long."), + LEN_MIN_PASSWORD); 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."; + errorMessage << strprintf(_("The new email address needs to be " + "less than %d characters long."), + LEN_MAX_PASSWORD); error = 1; } else if (newFirstEmail != newSecondEmail) { // Second Pass mismatch - errorMsg << "The email address entries mismatch."; + errorMessage << _("The email address entries mismatch."); error = 2; } @@ -151,7 +151,7 @@ ChangeEmailDialog::action(const gcn::ActionEvent &event) mWrongDataNoticeListener->setTarget(this->mSecondEmailField); } - OkDialog *dlg = new OkDialog("Error", errorMsg.str()); + OkDialog *dlg = new OkDialog(_("Error"), errorMessage.str()); dlg->addActionListener(mWrongDataNoticeListener); } else diff --git a/src/gui/changepassworddialog.cpp b/src/gui/changepassworddialog.cpp index 4be92b15..9d66d13a 100644 --- a/src/gui/changepassworddialog.cpp +++ b/src/gui/changepassworddialog.cpp @@ -96,36 +96,35 @@ void ChangePasswordDialog::action(const gcn::ActionEvent &event) logger->log("ChangePasswordDialog::Password change, Username is %s", username.c_str()); - std::stringstream errorMsg; + std::stringstream errorMessage; int error = 0; // Check old Password if (oldPassword.empty()) { // No old password - errorMsg << "Enter the old Password first."; + errorMessage << _("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."; + errorMessage << strprintf(_("The new password needs to be at least " + "%d characters long."), LEN_MIN_PASSWORD); 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."; + errorMessage << strprintf(_("The new password needs to be less " + "than %d characters long."), + LEN_MAX_PASSWORD); error = 2; } else if (newFirstPass != newSecondPass) { // Second Pass mismatch - errorMsg << "The new password entries mismatch."; + errorMessage << _("The new password entries mismatch."); error = 3; } @@ -144,7 +143,7 @@ void ChangePasswordDialog::action(const gcn::ActionEvent &event) mWrongDataNoticeListener->setTarget(this->mSecondPassField); } - OkDialog *dlg = new OkDialog("Error", errorMsg.str()); + OkDialog *dlg = new OkDialog(_("Error"), errorMessage.str()); dlg->addActionListener(mWrongDataNoticeListener); } else diff --git a/src/gui/charcreatedialog.cpp b/src/gui/charcreatedialog.cpp index 79ec5c1a..e09eee55 100644 --- a/src/gui/charcreatedialog.cpp +++ b/src/gui/charcreatedialog.cpp @@ -64,12 +64,16 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot): mNameField = new TextField(""); mNameLabel = new Label(_("Name:")); - mNextHairColorButton = new Button(">", "nextcolor", this); - mPrevHairColorButton = new Button("<", "prevcolor", this); - mHairColorLabel = new Label(_("Hair Color:")); - mNextHairStyleButton = new Button(">", "nextstyle", this); - mPrevHairStyleButton = new Button("<", "prevstyle", this); - mHairStyleLabel = new Label(_("Hair Style:")); + // TRANSLATORS: This is a narrow symbol used to denote 'next'. + // You may change this symbol if your language uses another. + mNextHairColorButton = new Button(_(">"), "nextcolor", this); + // TRANSLATORS: This is a narrow symbol used to denote 'previous'. + // You may change this symbol if your language uses another. + mPrevHairColorButton = new Button(_("<"), "prevcolor", this); + mHairColorLabel = new Label(_("Hair color:")); + mNextHairStyleButton = new Button(_(">"), "nextstyle", this); + mPrevHairStyleButton = new Button(_("<"), "prevstyle", this); + mHairStyleLabel = new Label(_("Hair style:")); mCreateButton = new Button(_("Create"), "create", this); mCancelButton = new Button(_("Cancel"), "cancel", this); mMale = new RadioButton(_("Male"), "gender"); diff --git a/src/gui/charselectdialog.cpp b/src/gui/charselectdialog.cpp index 63a25d45..69a627e1 100644 --- a/src/gui/charselectdialog.cpp +++ b/src/gui/charselectdialog.cpp @@ -36,6 +36,8 @@ #include "gui/changeemaildialog.h" #include "net/tmwserv/accountserver/account.h" +#else +#include "net/ea/protocol.h" #endif #include "gui/widgets/button.h" @@ -116,7 +118,7 @@ CharSelectDialog::CharSelectDialog(LockedArray<LocalPlayer*> *charInfo, mNameLabel = new Label(strprintf(_("Name: %s"), "")); mLevelLabel = new Label(strprintf(_("Level: %d"), 0)); - mMoneyLabel = new Label(strprintf(_("Money: %d"), 0)); + mMoneyLabel = new Label(strprintf(_("Money: %s"), "")); // Control that shows the Player mPlayerBox = new PlayerBox; @@ -296,9 +298,9 @@ void CharSelectDialog::updatePlayerInfo() mNameLabel->setCaption(strprintf(_("Name: %s"), pi->getName().c_str())); mLevelLabel->setCaption(strprintf(_("Level: %d"), pi->getLevel())); -#ifndef TMWSERV_SUPPORT +#ifdef EATHENA_SUPPORT mJobLevelLabel->setCaption(strprintf(_("Job Level: %d"), - pi->mJobLevel)); + pi->getAttributeBase(JOB))); #endif mMoneyLabel->setCaption(strprintf(_("Money: %s"), mMoney.c_str())); if (!mCharSelected) @@ -362,7 +364,10 @@ bool CharSelectDialog::selectByName(const std::string &name) LocalPlayer *player = mCharInfo->getEntry(); if (player && player->getName() == name) + { + mMoney = Units::formatCurrency(player->getMoney()); return true; + } mCharInfo->next(); } while (mCharInfo->getPos()); diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index 1ce1b77c..c337d33b 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -23,6 +23,7 @@ #include "gui/itemlinkhandler.h" #include "gui/recorder.h" +#include "gui/setup.h" #include "gui/sdlinput.h" #include "gui/widgets/chattab.h" @@ -39,6 +40,7 @@ #include "net/net.h" #include "utils/dtor.h" +#include "utils/gettext.h" #include "utils/stringutils.h" #include <guichan/focushandler.hpp> @@ -76,6 +78,8 @@ ChatWindow::ChatWindow(): { setWindowName("Chat"); + setupWindow->registerWindowForReset(this); + // no title presented, title bar is padding so window can be moved. gcn::Window::setTitleBarHeight(gcn::Window::getPadding() + 4); setShowTitle(false); @@ -138,9 +142,14 @@ void ChatWindow::adjustTabSize() ChatTab *tab = getFocused(); if (tab) { gcn::Widget *content = tab->mScrollArea; + bool scrollLock = false; + if(tab->mScrollArea->getVerticalMaxScroll() == tab->mScrollArea->getVerticalScrollAmount()) + scrollLock = true; content->setSize(mChatTabs->getWidth() - 2 * content->getFrameSize(), mChatTabs->getContainerHeight() - 2 * content->getFrameSize()); content->logic(); + if(scrollLock) + tab->mScrollArea->setVerticalScrollAmount(tab->mScrollArea->getVerticalMaxScroll()); } } @@ -323,8 +332,8 @@ void ChatWindow::doPresent() } } - std::string cpc = strprintf(_("%d players are present."), playercount); - std::string log = _("Present: ") + response + std::string("; ") + cpc; + std::string log = strprintf(_("Present: %s; %d players are present."), + response.c_str(), playercount); if (mRecorder->isRecording()) { @@ -360,6 +369,37 @@ void ChatWindow::scroll(int amount) tab->scroll(amount); } +void ChatWindow::mousePressed(gcn::MouseEvent &event) +{ + Window::mousePressed(event); + + if(event.isConsumed()) + return; + + mMoved = event.getY() <= mCurrentTab->getHeight(); + mDragOffsetX = event.getX(); + mDragOffsetY = event.getY(); + +} + +void ChatWindow::mouseDragged(gcn::MouseEvent &event) +{ + Window::mouseDragged(event); + + if(event.isConsumed()) + return; + + if(isMovable() && mMoved) + { + int newX = std::max(0, getX() + event.getX() - mDragOffsetX); + int newY = std::max(0, getY() + event.getY() - mDragOffsetY); + newX = std::min(graphics->getWidth() - getWidth(), newX); + newY = std::min(graphics->getHeight() - getHeight(), newY); + setPosition(newX, newY); + } +} + + void ChatWindow::keyPressed(gcn::KeyEvent &event) { if (event.getKey().getValue() == Key::DOWN) diff --git a/src/gui/chat.h b/src/gui/chat.h index 7080392e..2de3a634 100644 --- a/src/gui/chat.h +++ b/src/gui/chat.h @@ -150,6 +150,11 @@ class ChatWindow : public Window, /** Override to reset mTmpVisible */ void setVisible(bool visible); + + void mousePressed(gcn::MouseEvent &event); + void mouseDragged(gcn::MouseEvent &event); + + /** * Scrolls the chat window * diff --git a/src/gui/connectiondialog.cpp b/src/gui/connectiondialog.cpp index 1c3b7ff5..9e361173 100644 --- a/src/gui/connectiondialog.cpp +++ b/src/gui/connectiondialog.cpp @@ -31,7 +31,7 @@ #include "utils/gettext.h" ConnectionDialog::ConnectionDialog(State previousState): - Window("Info"), mProgress(0), mPreviousState(previousState) + Window(_("Info")), mProgress(0), mPreviousState(previousState) { setContentSize(200, 100); diff --git a/src/gui/debugwindow.cpp b/src/gui/debugwindow.cpp index f3dbe5e2..59c0f254 100644 --- a/src/gui/debugwindow.cpp +++ b/src/gui/debugwindow.cpp @@ -21,6 +21,7 @@ #include "gui/debugwindow.h" +#include "gui/setup.h" #include "gui/viewport.h" #include "gui/widgets/label.h" @@ -31,31 +32,33 @@ #include "particle.h" #include "map.h" +#include "utils/gettext.h" #include "utils/stringutils.h" DebugWindow::DebugWindow(): - Window("Debug") + Window(_("Debug")) { setWindowName("Debug"); + setupWindow->registerWindowForReset(this); setResizable(true); setCloseButton(true); setSaveVisible(true); setDefaultSize(400, 100, ImageRect::CENTER); - mFPSLabel = new Label("0 FPS"); - mMusicFileLabel = new Label("Music: "); - mMapLabel = new Label("Map: "); - mMiniMapLabel = new Label("Mini-Map: "); - mTileMouseLabel = new Label("Mouse: 0, 0"); - mParticleCountLabel = new Label("Particle count: 0"); + mFPSLabel = new Label(strprintf(_("%d FPS"), 0)); + mMusicFileLabel = new Label(strprintf(_("Music: %s"), "")); + mMapLabel = new Label(strprintf(_("Map: %s"), "")); + mMinimapLabel = new Label(strprintf(_("Minimap: %s"), "")); + mTileMouseLabel = new Label(strprintf(_("Tile: (%d, %d)"), 0, 0)); + mParticleCountLabel = new Label(strprintf(_("Particle count: %d"), 0)); place(0, 0, mFPSLabel, 3); place(3, 0, mTileMouseLabel); place(0, 1, mMusicFileLabel, 3); place(3, 1, mParticleCountLabel); place(0, 2, mMapLabel, 4); - place(0, 3, mMiniMapLabel, 4); + place(0, 3, mMinimapLabel, 4); loadWindowState(); } @@ -69,27 +72,28 @@ void DebugWindow::logic() int mouseTileX = (viewport->getMouseX() + viewport->getCameraX()) / 32; int mouseTileY = (viewport->getMouseY() + viewport->getCameraY()) / 32; - mFPSLabel->setCaption(toString(fps) + " FPS"); + mFPSLabel->setCaption(strprintf(_("%d FPS"), fps)); - mTileMouseLabel->setCaption("Tile: (" + toString(mouseTileX) + ", " + - toString(mouseTileY) + ")"); + mTileMouseLabel->setCaption(strprintf(_("Tile: (%d, %d)"), mouseTileX, + mouseTileY)); Map *currentMap = engine->getCurrentMap(); if (currentMap) { + // TODO: Add gettext support below const std::string music = "Music: " + currentMap->getProperty("music"); mMusicFileLabel->setCaption(music); const std::string minimap = - "MiniMap: " + currentMap->getProperty("minimap"); - mMiniMapLabel->setCaption(minimap); + "Minimap: " + currentMap->getProperty("minimap"); + mMinimapLabel->setCaption(minimap); const std::string map = "Map: " + currentMap->getProperty("_filename"); mMapLabel->setCaption(map); } - mParticleCountLabel->setCaption("Particle count: " + - toString(Particle::particleCount)); + mParticleCountLabel->setCaption(strprintf(_("Particle count: %d"), + Particle::particleCount)); } diff --git a/src/gui/debugwindow.h b/src/gui/debugwindow.h index e30107f9..e4c45bde 100644 --- a/src/gui/debugwindow.h +++ b/src/gui/debugwindow.h @@ -43,7 +43,7 @@ class DebugWindow : public Window void logic(); private: - gcn::Label *mMusicFileLabel, *mMapLabel, *mMiniMapLabel; + gcn::Label *mMusicFileLabel, *mMapLabel, *mMinimapLabel; gcn::Label *mTileMouseLabel, *mFPSLabel; gcn::Label *mParticleCountLabel; }; diff --git a/src/gui/emoteshortcutcontainer.cpp b/src/gui/emoteshortcutcontainer.cpp index 8e37be72..c087fc7e 100644 --- a/src/gui/emoteshortcutcontainer.cpp +++ b/src/gui/emoteshortcutcontainer.cpp @@ -39,8 +39,6 @@ #include "resources/resourcemanager.h" #include "utils/dtor.h" -#include "utils/gettext.h" -#include "utils/stringutils.h" static const int MAX_ITEMS = 12; diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp index 44006971..25de201c 100644 --- a/src/gui/equipmentwindow.cpp +++ b/src/gui/equipmentwindow.cpp @@ -25,6 +25,7 @@ #include "gui/itempopup.h" #include "gui/palette.h" #include "gui/playerbox.h" +#include "gui/setup.h" #include "gui/viewport.h" #include "equipment.h" @@ -50,31 +51,26 @@ static const int BOX_HEIGHT = 36; // Positions of the boxes, 2nd dimension is X and Y respectively. static const int boxPosition[][2] = { - { 50, 208 }, // EQUIP_LEGS_SLOT - { 8, 123 }, // EQUIP_FIGHT1_SLOT + { 90, 40 }, // EQUIP_TORSO_SLOT { 8, 78 }, // EQUIP_GLOVES_SLOT - { 129, 168 }, // EQUIP_RING2_SLOT + { 70, 0 }, // EQUIP_HEAD_SLOT + { 50, 208 }, // EQUIP_LEGS_SLOT + { 90, 208 }, // EQUIP_FEET_SLOT { 8, 168 }, // EQUIP_RING1_SLOT + { 129, 168 }, // EQUIP_RING2_SLOT + { 50, 40 }, // EQUIP_NECK_SLOT + { 8, 123 }, // EQUIP_FIGHT1_SLOT { 129, 123 }, // EQUIP_FIGHT2_SLOT - { 90, 208 }, // EQUIP_FEET_SLOT - { 50, 40 }, // EQUIP_CAPE_SLOT - { 70, 0 }, // EQUIP_HEAD_SLOT - { 90, 40 }, // EQUIP_TORSO_SLOT - { 129, 78 } // EQUIP_AMMO_SLOT + { 129, 78 } // EQUIP_PROJECTILE_SLOT }; -#ifdef TMWSERV_SUPPORT EquipmentWindow::EquipmentWindow(Equipment *equipment): -#else -EquipmentWindow::EquipmentWindow(): -#endif Window(_("Equipment")), -#ifdef TMWSERV_SUPPORT mEquipment(equipment), -#endif mSelected(-1) { mItemPopup = new ItemPopup; + setupWindow->registerWindowForReset(this); // Control that shows the Player PlayerBox *playerBox = new PlayerBox; @@ -96,16 +92,11 @@ EquipmentWindow::EquipmentWindow(): add(playerBox); add(mUnequip); - for (int i = 0; i < EQUIP_VECTOREND; i++) + for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++) { mEquipBox[i].posX = boxPosition[i][0] + getPadding(); mEquipBox[i].posY = boxPosition[i][1] + getTitleBarHeight(); } - -#ifdef EATHENA_SUPPORT - mEquipment = player_node->mEquipment.get(); - mInventory = player_node->getInventory(); -#endif } EquipmentWindow::~EquipmentWindow() @@ -122,7 +113,7 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) Window::drawChildren(graphics); - for (int i = 0; i < EQUIP_VECTOREND; i++) + for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++) { if (i == mSelected) { @@ -140,13 +131,7 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) g->drawRectangle(gcn::Rectangle(mEquipBox[i].posX, mEquipBox[i].posY, BOX_WIDTH, BOX_HEIGHT)); -#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. @@ -154,8 +139,7 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) g->drawImage(image, mEquipBox[i].posX + 2, mEquipBox[i].posY + 2); -#ifdef EATHENA_SUPPORT - if (i == EQUIP_AMMO_SLOT) + if (i == EQUIP_PROJECTILE_SLOT) { g->setColor(guiPalette->getColor(Palette::TEXT)); graphics->drawText(toString(item->getQuantity()), @@ -163,7 +147,6 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) mEquipBox[i].posY - getFont()->getHeight(), gcn::Graphics::CENTER); } -#endif } } } @@ -172,13 +155,7 @@ void EquipmentWindow::action(const gcn::ActionEvent &event) { if (event.getId() == "unequip" && mSelected > -1) { -#ifdef TMWSERV_SUPPORT // TODO: merge these! Item *item = mEquipment->getEquipment(mSelected); -#else - Item *item = (mSelected != EQUIP_AMMO_SLOT) ? - mInventory->getItem(mEquipment->getEquipment(mSelected)) : - mInventory->getItem(mEquipment->getArrows()); -#endif Net::getInventoryHandler()->unequipItem(item); setSelected(-1); } @@ -186,20 +163,14 @@ void EquipmentWindow::action(const gcn::ActionEvent &event) Item *EquipmentWindow::getItem(int x, int y) const { - for (int i = 0; i < EQUIP_VECTOREND; i++) + for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++) { gcn::Rectangle tRect(mEquipBox[i].posX, mEquipBox[i].posY, BOX_WIDTH, BOX_HEIGHT); if (tRect.isPointInRect(x, y)) { -#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; @@ -215,15 +186,9 @@ void EquipmentWindow::mousePressed(gcn::MouseEvent& mouseEvent) if (mouseEvent.getButton() == gcn::MouseEvent::LEFT) { // Checks if any of the presses were in the equip boxes. - for (int i = 0; i < EQUIP_VECTOREND; i++) + for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++) { -#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 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 8bc350a4..a7b2c0d1 100644 --- a/src/gui/equipmentwindow.h +++ b/src/gui/equipmentwindow.h @@ -24,11 +24,11 @@ #include "gui/widgets/window.h" +#include "equipment.h" #include "guichanfwd.h" #include <guichan/actionlistener.hpp> -class Equipment; class Inventory; class Item; class ItemPopup; @@ -44,11 +44,7 @@ class EquipmentWindow : public Window, public gcn::ActionListener /** * Constructor. */ -#ifdef TMWSERV_SUPPORT EquipmentWindow(Equipment *equipment); -#else - EquipmentWindow(); -#endif /** * Destructor. @@ -64,40 +60,6 @@ class EquipmentWindow : public Window, public gcn::ActionListener void mousePressed(gcn::MouseEvent& mouseEvent); -#ifdef TMWSERV_SUPPORT - enum EquipmentSlots - { - 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 EquipmentSlots - { - EQUIP_LEGS_SLOT = 0, - EQUIP_FIGHT1_SLOT, - EQUIP_GLOVES_SLOT, - EQUIP_RING2_SLOT, - EQUIP_RING1_SLOT, - EQUIP_FIGHT2_SLOT, - EQUIP_FEET_SLOT, - EQUIP_CAPE_SLOT, - EQUIP_HEAD_SLOT, - EQUIP_TORSO_SLOT, - EQUIP_AMMO_SLOT, - EQUIP_VECTOREND - }; -#endif - private: void mouseExited(gcn::MouseEvent &event); void mouseMoved(gcn::MouseEvent &event); @@ -107,9 +69,6 @@ class EquipmentWindow : public Window, public gcn::ActionListener void setSelected(int index); Equipment *mEquipment; -#ifdef EATHENA_SUPPORT - Inventory *mInventory; -#endif /** * Equipment box. @@ -120,12 +79,12 @@ class EquipmentWindow : public Window, public gcn::ActionListener int posY; }; - EquipBox mEquipBox[EQUIP_VECTOREND]; /**< Equipment Boxes. */ + EquipBox mEquipBox[Equipment::EQUIP_VECTOREND]; /**< Equipment Boxes. */ ItemPopup *mItemPopup; gcn::Button *mUnequip; - int mSelected; /**< Index of selected item. */ + int mSelected; /**< Index of selected item. */ }; extern EquipmentWindow *equipmentWindow; diff --git a/src/gui/guildwindow.cpp b/src/gui/guildwindow.cpp index 6dc86e13..05af7780 100644 --- a/src/gui/guildwindow.cpp +++ b/src/gui/guildwindow.cpp @@ -24,6 +24,7 @@ #include "gui/confirmdialog.h" #include "gui/guildlistbox.h" +#include "gui/setup.h" #include "gui/textdialog.h" #include "gui/widgets/button.h" @@ -41,6 +42,7 @@ #include "utils/dtor.h" #include "utils/gettext.h" +#include "utils/stringutils.h" #include <algorithm> @@ -58,6 +60,7 @@ GuildWindow::GuildWindow(): setMinWidth(200); setMinHeight(280); setDefaultSize(124, 41, 288, 330); + setupWindow->registerWindowForReset(this); // Set button events Id mGuildButton[0] = new Button(_("Create Guild"), "CREATE_GUILD", this); @@ -110,7 +113,8 @@ void GuildWindow::action(const gcn::ActionEvent &event) { // 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 = new TextDialog(_("Guild Name"), + _("Choose your guild's name."), this); guildDialog->setOKButtonActionId("CREATE_GUILD_OK"); guildDialog->addActionListener(this); } @@ -118,7 +122,8 @@ void GuildWindow::action(const gcn::ActionEvent &event) { // TODO - Give feedback on whether the invite succeeded mFocus = true; - inviteDialog = new TextDialog("Member Invite", "Who would you like to invite?", this); + inviteDialog = new TextDialog(_("Member Invite"), + _("Who would you like to invite?"), this); inviteDialog->setOKButtonActionId("INVITE_USER_OK"); inviteDialog->addActionListener(this); } @@ -128,7 +133,8 @@ void GuildWindow::action(const gcn::ActionEvent &event) if (guild) { Net::ChatServer::Guild::quitGuild(guild); - localChatTab->chatLog("Guild " + mGuildTabs->getSelectedTab()->getCaption() + " quit", BY_SERVER); + localChatTab->chatLog(strprintf(_("Guild %s quit."), + mGuildTabs->getSelectedTab()->getCaption().c_str()), BY_SERVER); } } else if (eventId == "CREATE_GUILD_OK") @@ -144,7 +150,8 @@ void GuildWindow::action(const gcn::ActionEvent &event) // Defocus dialog mFocus = false; - localChatTab->chatLog("Creating Guild called " + name, BY_SERVER); + localChatTab->chatLog(strprintf(_("Creating guild called %s."), + name.c_str()), BY_SERVER); guildDialog->scheduleDelete(); } else if (eventId == "INVITE_USER_OK") @@ -157,7 +164,7 @@ void GuildWindow::action(const gcn::ActionEvent &event) // Defocus dialog mFocus = false; - localChatTab->chatLog("Invited user " + name, BY_SERVER); + localChatTab->chatLog(strprintf(_("Invited user %s."), name.c_str()), BY_SERVER); inviteDialog->scheduleDelete(); } else if (eventId == "yes") @@ -233,10 +240,11 @@ short GuildWindow::getSelectedGuild() void GuildWindow::openAcceptDialog(const std::string &inviterName, const std::string &guildName) { - std::string msg = inviterName + " has invited you to join the guild " + guildName; + std::string msg = strprintf(_("%s has invited you to join the guild %s."), + inviterName.c_str(), guildName.c_str()); localChatTab->chatLog(msg, BY_SERVER); - acceptDialog = new ConfirmDialog("Accept Guild Invite", msg, this); + acceptDialog = new ConfirmDialog(_("Accept Guild Invite"), msg, this); acceptDialog->addActionListener(this); invitedGuild = guildName; diff --git a/src/gui/help.cpp b/src/gui/help.cpp index ddcf7b49..e28f64e3 100644 --- a/src/gui/help.cpp +++ b/src/gui/help.cpp @@ -25,6 +25,7 @@ #include "gui/widgets/browserbox.h" #include "gui/widgets/layout.h" #include "gui/widgets/scrollarea.h" +#include "gui/setup.h" #include "resources/resourcemanager.h" @@ -38,6 +39,7 @@ HelpWindow::HelpWindow(): setContentSize(455, 350); setWindowName("Help"); setResizable(true); + setupWindow->registerWindowForReset(this); setDefaultSize(500, 400, ImageRect::CENTER); diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index 06e43eac..50465a50 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -23,6 +23,7 @@ #include "gui/itemamount.h" #include "gui/itemcontainer.h" +#include "gui/setup.h" #include "gui/sdlinput.h" #include "gui/viewport.h" @@ -57,6 +58,7 @@ InventoryWindow::InventoryWindow(int invSize): mItemDesc(false) { setWindowName("Inventory"); + setupWindow->registerWindowForReset(this); setResizable(true); setCloseButton(true); setSaveVisible(true); diff --git a/src/gui/itemamount.cpp b/src/gui/itemamount.cpp index 87df46c1..20834c54 100644 --- a/src/gui/itemamount.cpp +++ b/src/gui/itemamount.cpp @@ -90,9 +90,9 @@ ItemAmountWindow::ItemAmountWindow(Usage usage, Window *parent, Item *item, mItemIcon = new Icon(image); // Buttons - Button *minusButton = new Button("-", "minus", this); - Button *plusButton = new Button("+", "plus", this); - Button *okButton = new Button(_("Ok"), "ok", this); + Button *minusButton = new Button(_("-"), "dec", this); + Button *plusButton = new Button(_("+"), "inc", this); + Button *okButton = new Button(_("OK"), "ok", this); Button *cancelButton = new Button(_("Cancel"), "cancel", this); Button *addAllButton = new Button(_("All"), "all", this); @@ -172,11 +172,11 @@ void ItemAmountWindow::action(const gcn::ActionEvent &event) { close(); } - else if (event.getId() == "plus" && amount < mMax) + else if (event.getId() == "inc" && amount < mMax) { amount++; } - else if (event.getId() == "minus" && amount > 1) + else if (event.getId() == "dec" && amount > 1) { amount--; } diff --git a/src/gui/itempopup.cpp b/src/gui/itempopup.cpp index e1822e03..39dc603a 100644 --- a/src/gui/itempopup.cpp +++ b/src/gui/itempopup.cpp @@ -88,8 +88,9 @@ void ItemPopup::setItem(const ItemInfo &item) mItemDesc->setTextWrapped(item.getDescription(), 196); mItemEffect->setTextWrapped(item.getEffect(), 196); - mItemWeight->setTextWrapped(_("Weight: ") + - Units::formatWeight(item.getWeight()), 196); + mItemWeight->setTextWrapped(strprintf(_("Weight: %s"), + Units::formatWeight(item.getWeight()).c_str()), + 196); int minWidth = mItemName->getWidth(); diff --git a/src/gui/login.cpp b/src/gui/login.cpp index 77f2e137..3b63eff1 100644 --- a/src/gui/login.cpp +++ b/src/gui/login.cpp @@ -70,7 +70,7 @@ LoginDialog::LoginDialog(LoginData *loginData): mServerDropDown = new DropDown(mServerList); #endif - mKeepCheck = new CheckBox(_("Remember Username"), 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); diff --git a/src/gui/magic.cpp b/src/gui/magic.cpp index c47faa18..6e314656 100644 --- a/src/gui/magic.cpp +++ b/src/gui/magic.cpp @@ -22,6 +22,7 @@ #include "gui/magic.h" #include "gui/widgets/button.h" +#include "gui/setup.h" #include "localplayer.h" @@ -35,6 +36,7 @@ MagicDialog::MagicDialog(): setCloseButton(true); setSaveVisible(true); setDefaultSize(255, 30, 175, 225); + setupWindow->registerWindowForReset(this); mSpellButtons.resize(4); diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp index d1c99b84..40526a22 100644 --- a/src/gui/minimap.cpp +++ b/src/gui/minimap.cpp @@ -31,6 +31,7 @@ #include "player.h" #include "gui/palette.h" +#include "gui/setup.h" #include "resources/image.h" #include "resources/resourcemanager.h" @@ -47,12 +48,13 @@ Minimap::Minimap(): mWidthProportion(0.5), mHeightProportion(0.5) { - setWindowName("MiniMap"); + setWindowName("Minimap"); mShow = config.getValue(getWindowName() + "Show", true); setDefaultSize(5, 25, 100, 100); // set this to false as the minimap window size is changed //depending on the map size setResizable(false); + setupWindow->registerWindowForReset(this); setDefaultVisible(true); setSaveVisible(true); diff --git a/src/gui/ministatus.cpp b/src/gui/ministatus.cpp index 65d2391d..4cb0e1ac 100644 --- a/src/gui/ministatus.cpp +++ b/src/gui/ministatus.cpp @@ -22,7 +22,7 @@ #include "gui/ministatus.h" #include "gui/gui.h" -#include "gui/status.h" +#include "gui/statuswindow.h" #include "gui/widgets/progressbar.h" @@ -33,34 +33,30 @@ #include "utils/stringutils.h" +extern volatile int tick_time; + MiniStatusWindow::MiniStatusWindow(): Popup("MiniStatus") { - mHpBar = new ProgressBar(0.0f, 100, 20, gcn::Color(0, 171, 34)); -#ifdef EATHENA_SUPPORT - mMpBar = new ProgressBar(0.0f, 100, 20, gcn::Color(26, 102, 230)); - mXpBar = new ProgressBar(0.0f, 100, 20, gcn::Color(143, 192, 211)); -#endif - + mHpBar = new ProgressBar((float) player_node->getHp() + / (float) player_node->getMaxHp(), + 100, 20, gcn::Color(0, 171, 34)); + mMpBar = new ProgressBar((float) player_node->getMaxMP() + / (float) player_node->getMaxMP(), + 100, 20, gcn::Color(26, 102, 230)); + mXpBar = new ProgressBar((float) player_node->getExp() + / player_node->getExpNeeded(), + 100, 20, gcn::Color(143, 192, 211)); 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 setVisible((bool) config.getValue(getPopupName() + "Visible", true)); } @@ -81,14 +77,37 @@ void MiniStatusWindow::eraseIcon(int index) mIcons.erase(mIcons.begin() + index); } -extern volatile int tick_time; +void MiniStatusWindow::drawIcons(Graphics *graphics) +{ + // Draw icons + int icon_x = mXpBar->getX() + mXpBar->getWidth() + 4; + for (unsigned int i = 0; i < mIcons.size(); i++) { + if (mIcons[i]) { + mIcons[i]->draw(graphics, icon_x, 3); + icon_x += 2 + mIcons[i]->getWidth(); + } + } +} -void MiniStatusWindow::update() +void MiniStatusWindow::update(int id) { - StatusWindow::updateHPBar(mHpBar); -#ifdef EATHENA_SUPPORT - StatusWindow::updateMPBar(mMpBar); - StatusWindow::updateXPBar(mXpBar); + if (id == StatusWindow::HP) + { + StatusWindow::updateHPBar(mHpBar); + } + else if (id == StatusWindow::MP) + { + StatusWindow::updateMPBar(mMpBar); + } + else if (id == StatusWindow::EXP) + { + StatusWindow::updateXPBar(mXpBar); + } +} + +void MiniStatusWindow::logic() +{ + Popup::logic(); // Displays the number of monsters to next lvl // (disabled for now but interesting idea) @@ -102,31 +121,8 @@ void MiniStatusWindow::update() << config.getValue("xpBarMonsterCounterName", "Monsters") <<" left..."; } */ -#endif for (unsigned int i = 0; i < mIcons.size(); i++) if (mIcons[i]) mIcons[i]->update(tick_time * 10); } - -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 56f53908..82ab0adc 100644 --- a/src/gui/ministatus.h +++ b/src/gui/ministatus.h @@ -40,8 +40,6 @@ class MiniStatusWindow : public Popup public: MiniStatusWindow(); - void draw(gcn::Graphics *graphics); - /** * Sets one of the icons. */ @@ -51,22 +49,24 @@ class MiniStatusWindow : public Popup void drawIcons(Graphics *graphics); - private: - /** - * Updates this dialog with values from player_node. - */ - void update(); + void update(int id); // Same types as status window + + void logic(); // Updates icons + void draw(gcn::Graphics *graphics) + { drawChildren(graphics); } + + private: /* * Mini Status Bars */ ProgressBar *mHpBar; -#ifdef EATHENA_SUPPORT ProgressBar *mMpBar; ProgressBar *mXpBar; -#endif std::vector<AnimatedSprite *> mIcons; }; +extern MiniStatusWindow *miniStatusWindow; + #endif diff --git a/src/gui/npcdialog.cpp b/src/gui/npcdialog.cpp index afcc150d..1956ba85 100644 --- a/src/gui/npcdialog.cpp +++ b/src/gui/npcdialog.cpp @@ -28,6 +28,7 @@ #include "gui/widgets/scrollarea.h" #include "gui/widgets/textbox.h" #include "gui/widgets/textfield.h" +#include "gui/setup.h" #include "npc.h" @@ -54,6 +55,7 @@ NpcDialog::NpcDialog() // Basic Window Setup setWindowName("NpcText"); setResizable(true); + setupWindow->registerWindowForReset(this); setMinWidth(200); setMinHeight(150); @@ -91,8 +93,8 @@ NpcDialog::NpcDialog() mButton = new Button("", "ok", this); //Setup more and less buttons (int input) - mPlusButton = new Button("+", "plus", this); - mMinusButton = new Button("-", "minus", this); + mPlusButton = new Button(_("+"), "inc", this); + mMinusButton = new Button(_("-"), "dec", this); int width = std::max(mButton->getFont()->getWidth(CAPTION_WAITING), mButton->getFont()->getWidth(CAPTION_NEXT)); @@ -154,7 +156,8 @@ void NpcDialog::action(const gcn::ActionEvent &event) if (mActionState == NPC_ACTION_NEXT) { nextDialog(); - addText("\n> Next\n"); + // TRANSLATORS: Please leave the \n sequences intact. + addText(_("\n> Next\n")); } else if (mActionState == NPC_ACTION_CLOSE) { @@ -209,11 +212,11 @@ void NpcDialog::action(const gcn::ActionEvent &event) mIntField->setValue(mDefaultInt); } } - else if (event.getId() == "plus") + else if (event.getId() == "inc") { mIntField->setValue(mIntField->getValue() + 1); } - else if (event.getId() == "minus") + else if (event.getId() == "dec") { mIntField->setValue(mIntField->getValue() - 1); } diff --git a/src/gui/outfitwindow.cpp b/src/gui/outfitwindow.cpp index f43e1440..d2e9468d 100644 --- a/src/gui/outfitwindow.cpp +++ b/src/gui/outfitwindow.cpp @@ -58,9 +58,9 @@ OutfitWindow::OutfitWindow(): setCloseButton(true); setDefaultSize(250, 250, 118, 180); //160 - mPreviousButton = new Button("<", "previous", this); - mNextButton = new Button(">", "next", this); - mCurrentLabel = new Label("Outfit: 1"); + mPreviousButton = new Button(_("<"), "previous", this); + mNextButton = new Button(_(">"), "next", this); + mCurrentLabel = new Label(strprintf(_("Outfit: %d"), 1)); mCurrentLabel->setAlignment(gcn::Graphics::CENTER); mUnequipCheck = new CheckBox(_("Unequip first"), config.getValue("OutfitUnequip", true)); @@ -140,7 +140,7 @@ void OutfitWindow::action(const gcn::ActionEvent &event) mCurrentOutfit = 9; } } - mCurrentLabel->setCaption("Outfit: " + toString(mCurrentOutfit + 1)); + mCurrentLabel->setCaption(strprintf(_("Outfit: %d"), mCurrentOutfit + 1)); } void OutfitWindow::wearOutfit(int outfit) @@ -153,14 +153,8 @@ void OutfitWindow::wearOutfit(int outfit) //non vis is 3,4,7 if (i != 3 && i != 4 && i != 7) { -#ifdef TMWSERV_SUPPORT if (!(item = player_node->mEquipment.get()->getEquipment(i))) continue; -#else - if (!(item = player_node->getInventory()->getItem( - player_node->mEquipment.get()->getEquipment(i)))) - continue; -#endif Net::getInventoryHandler()->unequipItem(item); } } diff --git a/src/gui/palette.cpp b/src/gui/palette.cpp index 4d1233e8..a807dcd6 100644 --- a/src/gui/palette.cpp +++ b/src/gui/palette.cpp @@ -82,18 +82,21 @@ Palette::Palette() : addColor(SHADOW, 0x000000, STATIC, indent + _("Text Shadow")); addColor(OUTLINE, 0x000000, STATIC, indent + _("Text Outline")); addColor(PROGRESS_BAR, 0xffffff, STATIC, indent + _("Progress Bar Labels")); + addColor(BUTTON, 0xc8ad00, STATIC, indent + _("Buttons")); + addColor(BUTTON_DISABLED, 0x828282, STATIC, indent + _("Disabled Buttons")); + addColor(TAB, 0xc8ad00, STATIC, indent + _("Tabs")); addColor(BACKGROUND, 0xffffff, STATIC, _("Background")); addColor(HIGHLIGHT, 0xebc873, STATIC, _("Highlight"), 'H'); addColor(TAB_HIGHLIGHT, 0xff0000, PULSE, indent + _("Tab Highlight")); - addColor(SHOP_WARNING, 0x910000, STATIC, indent + _("Item too expensive")); - addColor(ITEM_EQUIPPED, 0x000091, STATIC, indent + _("Item is equipped")); + addColor(SHOP_WARNING, 0x910000, STATIC, indent + _("Item Too Expensive")); + addColor(ITEM_EQUIPPED, 0x000091, STATIC, indent + _("Item Is Equipped")); addColor(CHAT, 0x000000, STATIC, _("Chat"), 'C'); addColor(GM, 0xff0000, STATIC, indent + _("GM"), 'G'); addColor(PLAYER, 0x1fa052, STATIC, indent + _("Player"), 'Y'); - addColor(WHISPER, 0x0000ff, STATIC, indent + _("Whisper"), 'W'); + addColor(WHISPER, 0x00feaf, STATIC, indent + _("Whisper"), 'W'); addColor(IS, 0xa08527, STATIC, indent + _("Is"), 'I'); addColor(PARTY, 0xf48055, STATIC, indent + _("Party"), 'P'); addColor(SERVER, 0x8415e2, STATIC, indent + _("Server"), 'S'); @@ -112,10 +115,10 @@ Palette::Palette() : addColor(HEAD, 0x527fa4, STATIC, indent + _("Hats")); addColor(USABLE, 0x268d24, STATIC, indent + _("Usables")); addColor(TORSO, 0xd12aa4, STATIC, indent + _("Shirts")); - addColor(ONEHAND, 0xf42a2a, STATIC, indent + _("1 Handed Weapons")); + addColor(ONEHAND, 0xf42a2a, STATIC, indent + _("One Handed Weapons")); addColor(LEGS, 0x699900, STATIC, indent + _("Pants")); addColor(FEET, 0xaa1d48, STATIC, indent + _("Shoes")); - addColor(TWOHAND, 0xf46d0e, STATIC, indent + _("2 Handed Weapons")); + addColor(TWOHAND, 0xf46d0e, STATIC, indent + _("Two Handed Weapons")); addColor(SHIELD, 0x9c2424, STATIC, indent + _("Shields")); addColor(RING, 0x0000ff, STATIC, indent + _("Rings")); addColor(NECKLACE, 0xff00ff, STATIC, indent + _("Necklaces")); @@ -126,9 +129,9 @@ Palette::Palette() : addColor(PICKUP_INFO, 0x28dc28, STATIC, indent + _("Pickup Notification")); addColor(EXP_INFO, 0xffff00, STATIC, indent + _("Exp Notification")); addColor(HIT_PLAYER_MONSTER, 0x0064ff, STATIC, - indent + _("Player hits Monster")); + indent + _("Player Hits Monster")); addColor(HIT_MONSTER_PLAYER, 0xff3232, STATIC, - indent + _("Monster hits Player")); + indent + _("Monster Hits Player")); addColor(HIT_CRITICAL, 0xff0000, RAINBOW, indent + _("Critical Hit")); addColor(MISS, 0xffff00, STATIC, indent + _("Misses")); diff --git a/src/gui/palette.h b/src/gui/palette.h index 1dec2a60..c68a4e1c 100644 --- a/src/gui/palette.h +++ b/src/gui/palette.h @@ -57,6 +57,9 @@ class Palette : public gcn::ListModel ENTRY(SHADOW)\ ENTRY(OUTLINE)\ ENTRY(PROGRESS_BAR)\ + ENTRY(BUTTON)\ + ENTRY(BUTTON_DISABLED)\ + ENTRY(TAB)\ ENTRY(BACKGROUND)\ ENTRY(HIGHLIGHT)\ ENTRY(TAB_HIGHLIGHT)\ diff --git a/src/gui/partywindow.cpp b/src/gui/partywindow.cpp index f66ffaac..d4b084ce 100644 --- a/src/gui/partywindow.cpp +++ b/src/gui/partywindow.cpp @@ -22,6 +22,7 @@ #include "gui/partywindow.h" #include "gui/widgets/chattab.h" +#include "gui/setup.h" #include "beingmanager.h" #include "player.h" @@ -56,6 +57,7 @@ PartyWindow::PartyWindow() : setMinWidth(120); setMinHeight(55); setDefaultSize(590, 200, 150, 60); + setupWindow->registerWindowForReset(this); loadWindowState(); } diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp index e12ca822..0f0df756 100644 --- a/src/gui/popupmenu.cpp +++ b/src/gui/popupmenu.cpp @@ -34,6 +34,7 @@ #include "graphics.h" #include "item.h" #include "localplayer.h" +#include "log.h" #include "npc.h" #include "playerrelations.h" @@ -72,10 +73,6 @@ void PopupMenu::showPopup(int x, int y, Being *being) mBeingId = being->getId(); mBrowserBox->clearRows(); - // Any being's name can be added to chat - if (being->getType() != Being::UNKNOWN) - mBrowserBox->addRow(_("@@name|Add name to chat@@")); - const std::string &name = being->getType() == Being::NPC ? being->getName().substr(0, being->getName().size() - 6) : being->getName(); @@ -86,42 +83,68 @@ void PopupMenu::showPopup(int x, int y, Being *being) { // Players can be traded with. Later also follow and // add as buddy will be options in this menu. - mBrowserBox->addRow(strprintf(_("@@trade|Trade With %s@@"), name.c_str())); - mBrowserBox->addRow(strprintf(_("@@attack|Attack %s@@"), name.c_str())); + mBrowserBox->addRow(strprintf("@@trade|%s@@", + strprintf(_("Trade with %s"), + name.c_str()).c_str())); + // TRANSLATORS: Attacking a player. + mBrowserBox->addRow(strprintf("@@attack|%s@@", + strprintf(_("Attack %s"), + name.c_str()).c_str())); mBrowserBox->addRow("##3---"); switch (player_relations.getRelation(name)) { case PlayerRelation::NEUTRAL: - mBrowserBox->addRow(strprintf(_("@@friend|Befriend %s@@"), name.c_str())); + mBrowserBox->addRow(strprintf("@@friend|%s@@", + strprintf(_("Befriend %s"), + name.c_str()).c_str())); case PlayerRelation::FRIEND: - mBrowserBox->addRow(strprintf(_("@@disregard|Disregard %s@@"), name.c_str())); - mBrowserBox->addRow(strprintf(_("@@ignore|Ignore %s@@"), name.c_str())); + mBrowserBox->addRow(strprintf("@@disregard|%s@@", + strprintf(_("Disregard %s"), + name.c_str()).c_str())); + mBrowserBox->addRow(strprintf("@@ignore|%s@@", + strprintf(_("Ignore %s"), + name.c_str()).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())); + mBrowserBox->addRow(strprintf("@@unignore|%s@@", + strprintf(_("Unignore %s"), + name.c_str()).c_str())); + mBrowserBox->addRow(strprintf("@@ignore|%s@@", + strprintf(_("Completely ignore %s"), + name.c_str()).c_str())); break; case PlayerRelation::IGNORED: - mBrowserBox->addRow(strprintf(_("@@unignore|Un-Ignore %s@@"), name.c_str())); + mBrowserBox->addRow(strprintf("@@unignore|%s@@", + strprintf(_("Unignore %s"), + name.c_str()).c_str())); break; } - //mBrowserBox->addRow(_(strprintf("@@follow|Follow %s@@"), name.c_str())); - //mBrowserBox->addRow(_("@@buddy|Add ") + name + " to Buddy List@@"); + /*mBrowserBox->addRow(strprintf("@@follow|%s@@", + strprintf(_("Follow %s"), + name.c_str()).c_str()));*/ + /*mBrowserBox->addRow(strprintf("@@buddy|%s@@", + strprintf(_("Add %s to Buddy List"), + name.c_str()).c_str()));*/ #ifdef TMWSERV_SUPPORT - mBrowserBox->addRow(strprintf(_("@@guild|Invite %s to join your guild@@"), name.c_str())); + mBrowserBox->addRow(strprintf("@@guild|%s@@", + strprintf(_("Invite %s to join your guild"), + name.c_str()).c_str())); #endif if (player_node->isInParty()) - mBrowserBox->addRow(strprintf(_("@@party|Invite %s to join your party@@"), name.c_str())); + mBrowserBox->addRow(strprintf("@@pickup|%s@@", + strprintf(_("Invite %s to join your party"), + name.c_str()).c_str())); if (player_node->isGM()) { mBrowserBox->addRow("##3---"); - mBrowserBox->addRow(_("@@admin-kick|Kick player@@")); + mBrowserBox->addRow(strprintf("@@admin-kick|%s@@", + _("Kick player"))); } } break; @@ -129,16 +152,21 @@ void PopupMenu::showPopup(int x, int y, Being *being) case Being::NPC: // NPCs can be talked to (single option, candidate for removal // unless more options would be added) - mBrowserBox->addRow(strprintf(_("@@talk|Talk To %s@@"), name.c_str())); + mBrowserBox->addRow(strprintf("@@talk|%s@@", + strprintf(_("Talk to %s"), + name.c_str()).c_str())); break; case Being::MONSTER: { // Monsters can be attacked - mBrowserBox->addRow(strprintf(_("@@attack|Attack %s@@"), name.c_str())); + mBrowserBox->addRow(strprintf("@@attack|%s@@", + strprintf(_("Attack %s"), + name.c_str()).c_str())); if (player_node->isGM()) - mBrowserBox->addRow(_("@@admin-kick|Kick monster@@")); + mBrowserBox->addRow(strprintf("@@admin-kick|%s@@", + _("Kick monster"))); } break; @@ -146,10 +174,11 @@ void PopupMenu::showPopup(int x, int y, Being *being) /* Other beings aren't interesting... */ return; } + mBrowserBox->addRow(strprintf("@@name|%s@@", _("Add name to chat"))); - //browserBox->addRow("@@look|Look To@@"); + //mBrowserBox->addRow(strprintf("@@look|%s@@", _("Look To"))); mBrowserBox->addRow("##3---"); - mBrowserBox->addRow(_("@@cancel|Cancel@@")); + mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel"))); showPopup(x, y); } @@ -162,12 +191,13 @@ void PopupMenu::showPopup(int x, int y, FloorItem *floorItem) // Floor item can be picked up (single option, candidate for removal) std::string name = ItemDB::get(mFloorItem->getItemId()).getName(); - mBrowserBox->addRow(strprintf(_("@@pickup|Pick up %s@@"), name.c_str())); - mBrowserBox->addRow(_("@@chat|Add to chat@@")); + mBrowserBox->addRow(strprintf("@@pickup|%s@@", strprintf(_("Pick up %s"), + name.c_str()).c_str())); + mBrowserBox->addRow(strprintf("@@chat|%s@@", _("Add to chat"))); - //browserBox->addRow("@@look|Look To@@"); + //mBrowserBox->addRow(strprintf("@@look|%s@@", _("Look To"))); mBrowserBox->addRow("##3---"); - mBrowserBox->addRow(_("@@cancel|Cancel@@")); + mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel"))); showPopup(x, y); } @@ -193,13 +223,11 @@ void PopupMenu::handleLink(const std::string &link) Net::getTradeHandler()->request(being); tradePartnerName = being->getName(); } -#ifdef EATHENA_SUPPORT // Attack action else if (link == "attack" && being) { player_node->attack(being, true); } -#endif else if (link == "unignore" && being && being->getType() == Being::PLAYER) @@ -332,7 +360,7 @@ void PopupMenu::handleLink(const std::string &link) // Unknown actions else if (link != "cancel") { - std::cout << link << std::endl; + logger->log("PopupMenu: Warning, unknown action '%s'", link.c_str()); } setVisible(false); @@ -353,34 +381,34 @@ void PopupMenu::showPopup(int x, int y, Item *item, bool isInventory) if (item->isEquipment()) { if (item->isEquipped()) - mBrowserBox->addRow(_("@@use|Unequip@@")); + mBrowserBox->addRow(strprintf("@@use|%s@@", _("Unequip"))); else - mBrowserBox->addRow(_("@@use|Equip@@")); + mBrowserBox->addRow(strprintf("@@use|%s@@", _("Equip"))); } else - mBrowserBox->addRow(_("@@use|Use@@")); + mBrowserBox->addRow(strprintf("@@use|%s@@", _("Use"))); - mBrowserBox->addRow(_("@@drop|Drop@@")); + mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop"))); if (Net::getInventoryHandler()->canSplit(item)) { - mBrowserBox->addRow(_("@@split|Split@@")); + mBrowserBox->addRow(strprintf("@@split|%s@@", _("Split"))); } if (player_node->getInStorage()) { - mBrowserBox->addRow(_("@@store|Store@@")); + mBrowserBox->addRow(strprintf("@@store|%s@@", _("Store"))); } } // Assume in storage for now // TODO: make this whole system more flexible, if needed else { - mBrowserBox->addRow(_("@@retrieve|Retrieve@@")); + mBrowserBox->addRow(strprintf("@@retrieve|%s@@", _("Retrieve"))); } - mBrowserBox->addRow(_("@@chat|Add to chat@@")); + mBrowserBox->addRow(strprintf("@@chat|%s@@", _("Add to chat"))); mBrowserBox->addRow("##3---"); - mBrowserBox->addRow(_("@@cancel|Cancel@@")); + mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel"))); showPopup(x, y); } diff --git a/src/gui/recorder.cpp b/src/gui/recorder.cpp index 3307d904..b2679553 100644 --- a/src/gui/recorder.cpp +++ b/src/gui/recorder.cpp @@ -28,6 +28,7 @@ #include "gui/widgets/layout.h" #include "gui/widgets/windowcontainer.h" +#include "utils/gettext.h" #include "utils/stringutils.h" #include <physfs.h> diff --git a/src/gui/register.cpp b/src/gui/register.cpp index 2b897641..f1313a5e 100644 --- a/src/gui/register.cpp +++ b/src/gui/register.cpp @@ -160,13 +160,13 @@ void RegisterDialog::action(const gcn::ActionEvent &event) const std::string user = mUserField->getText(); logger->log("RegisterDialog::register Username is %s", user.c_str()); - std::string errorMsg; + std::string errorMessage; int error = 0; if (user.length() < LEN_MIN_USERNAME) { // Name too short - errorMsg = strprintf + errorMessage = strprintf (_("The username needs to be at least %d characters long."), LEN_MIN_USERNAME); error = 1; @@ -174,7 +174,7 @@ void RegisterDialog::action(const gcn::ActionEvent &event) else if (user.length() > LEN_MAX_USERNAME - 1 ) { // Name too long - errorMsg = strprintf + errorMessage = strprintf (_("The username needs to be less than %d characters long."), LEN_MAX_USERNAME); error = 1; @@ -182,7 +182,7 @@ void RegisterDialog::action(const gcn::ActionEvent &event) else if (mPasswordField->getText().length() < LEN_MIN_PASSWORD) { // Pass too short - errorMsg = strprintf + errorMessage = strprintf (_("The password needs to be at least %d characters long."), LEN_MIN_PASSWORD); error = 2; @@ -190,7 +190,7 @@ void RegisterDialog::action(const gcn::ActionEvent &event) else if (mPasswordField->getText().length() > LEN_MAX_PASSWORD - 1 ) { // Pass too long - errorMsg = strprintf + errorMessage = strprintf (_("The password needs to be less than %d characters long."), LEN_MAX_PASSWORD); error = 2; @@ -198,7 +198,7 @@ void RegisterDialog::action(const gcn::ActionEvent &event) else if (mPasswordField->getText() != mConfirmField->getText()) { // Password does not match with the confirmation one - errorMsg = _("Passwords do not match."); + errorMessage = _("Passwords do not match."); error = 2; } @@ -219,7 +219,7 @@ void RegisterDialog::action(const gcn::ActionEvent &event) mWrongDataNoticeListener->setTarget(this->mPasswordField); } - OkDialog *dlg = new OkDialog(_("Error"), errorMsg); + OkDialog *dlg = new OkDialog(_("Error"), errorMessage); dlg->addActionListener(mWrongDataNoticeListener); } else diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp index 28288ef4..4082b881 100644 --- a/src/gui/sell.cpp +++ b/src/gui/sell.cpp @@ -21,6 +21,7 @@ #include "gui/sell.h" +#include "gui/setup.h" #include "gui/shop.h" #include "gui/shoplistbox.h" @@ -47,6 +48,7 @@ SellDialog::SellDialog(): mMaxItems(0), mAmountItems(0) { setWindowName("Sell"); + setupWindow->registerWindowForReset(this); setResizable(true); setCloseButton(true); setMinWidth(260); @@ -67,8 +69,8 @@ SellDialog::SellDialog(): mMoneyLabel = new Label(strprintf(_("Price: %s / Total: %s"), "", "")); - mIncreaseButton = new Button("+", "+", this); - mDecreaseButton = new Button("-", "-", this); + mIncreaseButton = new Button(_("+"), "inc", this); + mDecreaseButton = new Button(_("-"), "dec", this); mSellButton = new Button(_("Sell"), "sell", this); mQuitButton = new Button(_("Quit"), "quit", this); mAddMaxButton = new Button(_("Max"), "max", this); @@ -159,13 +161,13 @@ void SellDialog::action(const gcn::ActionEvent &event) mAmountItems = (int) mSlider->getValue(); updateButtonsAndLabels(); } - else if (event.getId() == "+" && mAmountItems < mMaxItems) + else if (event.getId() == "inc" && mAmountItems < mMaxItems) { mAmountItems++; mSlider->setValue(mAmountItems); updateButtonsAndLabels(); } - else if (event.getId() == "-" && mAmountItems > 1) + else if (event.getId() == "dec" && mAmountItems > 1) { mAmountItems--; mSlider->setValue(mAmountItems); diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp index 5d08a2ec..bd6b7d4b 100644 --- a/src/gui/serverdialog.cpp +++ b/src/gui/serverdialog.cpp @@ -71,7 +71,7 @@ void ServersListModel::addElement(Server server) } ServerDialog::ServerDialog(LoginData *loginData): - Window(_("Choose your server")), mLoginData(loginData) + Window(_("Choose Your Server")), mLoginData(loginData) { gcn::Label *serverLabel = new Label(_("Server:")); gcn::Label *portLabel = new Label(_("Port:")); diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp index aebcf61b..2f0d78ca 100644 --- a/src/gui/setup.cpp +++ b/src/gui/setup.cpp @@ -37,29 +37,7 @@ #include "utils/dtor.h" #include "utils/gettext.h" -extern Window *chatWindow; extern Window *statusWindow; -extern Window *buyDialog; -extern Window *sellDialog; -extern Window *buySellDialog; -extern Window *inventoryWindow; -extern Window *npcTextDialog; -extern Window *npcStringDialog; -extern Window *skillDialog; -extern Window *partyWindow; -extern Window *minimap; -extern Window *equipmentWindow; -extern Window *tradeWindow; -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")) @@ -137,29 +115,11 @@ void Setup::action(const gcn::ActionEvent &event) if (!statusWindow) return; - chatWindow->resetToDefaultSize(); - statusWindow->resetToDefaultSize(); - buyDialog->resetToDefaultSize(); - sellDialog->resetToDefaultSize(); -#ifdef EATHENA_SUPPORT - buySellDialog->resetToDefaultSize(); -#endif - inventoryWindow->resetToDefaultSize(); - skillDialog->resetToDefaultSize(); - partyWindow->resetToDefaultSize(); - minimap->resetToDefaultSize(); - equipmentWindow->resetToDefaultSize(); - tradeWindow->resetToDefaultSize(); - helpWindow->resetToDefaultSize(); - debugWindow->resetToDefaultSize(); - itemShortcutWindow->resetToDefaultSize(); - emoteShortcutWindow->resetToDefaultSize(); -#ifdef TMWSERV_SUPPORT - magicDialog->resetToDefaultSize(); - guildWindow->resetToDefaultSize(); -#else - storageWindow->resetToDefaultSize(); -#endif + for (std::list<Window*>::iterator it = mWindowsToReset.begin(); + it != mWindowsToReset.end(); it++) + { + (*it)->resetToDefaultSize(); + } } } @@ -168,4 +128,9 @@ void Setup::setInGame(bool inGame) mResetWindows->setEnabled(inGame); } +void Setup::registerWindowForReset(Window *window) +{ + mWindowsToReset.push_back(window); +} + Setup *setupWindow; diff --git a/src/gui/setup.h b/src/gui/setup.h index 630d5eaa..6000adfa 100644 --- a/src/gui/setup.h +++ b/src/gui/setup.h @@ -61,8 +61,14 @@ class Setup : public Window, public gcn::ActionListener */ void setInGame(bool inGame); + void registerWindowForReset(Window *window); + + void clearWindowsForReset() + { mWindowsToReset.clear(); } + private: std::list<SetupTab*> mTabs; + std::list<Window*> mWindowsToReset; gcn::Button *mResetWindows; }; diff --git a/src/gui/setup_audio.cpp b/src/gui/setup_audio.cpp index 9da74c2e..990a3ce8 100644 --- a/src/gui/setup_audio.cpp +++ b/src/gui/setup_audio.cpp @@ -91,7 +91,7 @@ void Setup_Audio::apply() } catch (const char *err) { - new OkDialog("Sound Engine", err); + new OkDialog(_("Sound Engine"), err); logger->log("Warning: %s", err); } } diff --git a/src/gui/setup_colors.cpp b/src/gui/setup_colors.cpp index efa03ba4..7e8b8946 100644 --- a/src/gui/setup_colors.cpp +++ b/src/gui/setup_colors.cpp @@ -68,7 +68,7 @@ Setup_Colors::Setup_Colors() : mPreviewBox->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER, gcn::ScrollArea::SHOW_NEVER); - mGradTypeLabel = new Label(_("Type: ")); + mGradTypeLabel = new Label(_("Type:")); mGradTypeSlider = new Slider(0, 3); mGradTypeSlider->setWidth(200); @@ -90,7 +90,7 @@ Setup_Colors::Setup_Colors() : mGradTypeText->setCaption(longText); - mGradDelayLabel = new Label(_("Delay: ")); + mGradDelayLabel = new Label(_("Delay:")); mGradDelayText = new TextField(); mGradDelayText->setWidth(40); @@ -105,7 +105,7 @@ Setup_Colors::Setup_Colors() : mGradDelaySlider->addActionListener(this); mGradDelaySlider->setEnabled(false); - mRedLabel = new Label(_("Red: ")); + mRedLabel = new Label(_("Red:")); mRedText = new TextField; mRedText->setWidth(40); @@ -120,7 +120,7 @@ Setup_Colors::Setup_Colors() : mRedSlider->addActionListener(this); mRedSlider->setEnabled(false); - mGreenLabel = new Label(_("Green: ")); + mGreenLabel = new Label(_("Green:")); mGreenText = new TextField; mGreenText->setWidth(40); @@ -135,7 +135,7 @@ Setup_Colors::Setup_Colors() : mGreenSlider->addActionListener(this); mGreenSlider->setEnabled(false); - mBlueLabel = new Label(_("Blue: ")); + mBlueLabel = new Label(_("Blue:")); mBlueText = new TextField; mBlueText->setWidth(40); @@ -262,6 +262,9 @@ void Setup_Colors::valueChanged(const gcn::SelectionEvent &event) mTextPreview->setOutline(true); mTextPreview->setShadow(false); break; + case Palette::BUTTON: + case Palette::BUTTON_DISABLED: + case Palette::TAB: case Palette::TAB_HIGHLIGHT: mTextPreview->setFont(gui->getFont()); mTextPreview->setTextColor(col); diff --git a/src/gui/setup_keyboard.cpp b/src/gui/setup_keyboard.cpp index 938c1c4e..d9117b8a 100644 --- a/src/gui/setup_keyboard.cpp +++ b/src/gui/setup_keyboard.cpp @@ -116,7 +116,7 @@ void Setup_Keyboard::apply() if (keyboard.hasConflicts()) { - new OkDialog(_("Key Conflict(s) Detected."), + new OkDialog(_("Key Conflict(s) Detected"), _("Resolve them, or gameplay may result in strange " "behaviour.")); } diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp index a9c892b2..f21f20e0 100644 --- a/src/gui/setup_video.cpp +++ b/src/gui/setup_video.cpp @@ -192,15 +192,17 @@ Setup_Video::Setup_Video(): mVisibleNamesEnabled)), mParticleEffectsCheckBox(new CheckBox(_("Particle effects"), mParticleEffectsEnabled)), - mNameCheckBox(new CheckBox(_("Show name"), mNameEnabled)), + mNameCheckBox(new CheckBox(_("Show own name"), mNameEnabled)), mPickupNotifyLabel(new Label(_("Show pickup notification"))), + // TRANSLATORS: Refers to "Show own name" mPickupChatCheckBox(new CheckBox(_("in chat"), mPickupChatEnabled)), + // TRANSLATORS: Refers to "Show own name" mPickupParticleCheckBox(new CheckBox(_("as particle"), mPickupParticleEnabled)), mSpeechSlider(new Slider(0, 3)), mSpeechLabel(new Label("")), mAlphaSlider(new Slider(0.2, 1.0)), - mFpsCheckBox(new CheckBox(_("FPS Limit:"))), + mFpsCheckBox(new CheckBox(_("FPS limit:"))), mFpsSlider(new Slider(10, 120)), mFpsField(new TextField), mOverlayDetail((int) config.getValue("OverlayDetail", 2)), @@ -219,7 +221,7 @@ Setup_Video::Setup_Video(): speechLabel = new Label(_("Overhead text")); alphaLabel = new Label(_("Gui opacity")); overlayDetailLabel = new Label(_("Ambient FX")); - particleDetailLabel = new Label(_("Particle Detail")); + particleDetailLabel = new Label(_("Particle detail")); fontSizeLabel = new Label(_("Font size")); mFontSizeDropDown = new DropDown(new FontSizeChoiceListModel); @@ -352,19 +354,27 @@ void Setup_Video::apply() fullscreen = !fullscreen; if (!graphics->setFullscreen(fullscreen)) { - std::stringstream error; - error << _("Failed to switch to ") << - (fullscreen ? _("windowed") : _("fullscreen")) << - _("mode and restoration of old mode also failed!") << - std::endl; - logger->error(error.str()); + std::stringstream errorMessage; + if (fullscreen) + { + errorMessage << _("Failed to switch to windowed mode " + "and restoration of old mode also " + "failed!") << std::endl; + } + else + { + errorMessage << _("Failed to switch to fullscreen mode " + "and restoration of old mode also " + "failed!") << std::endl; + } + logger->error(errorMessage.str()); } } #if defined(WIN32) || defined(__APPLE__) } else { - new OkDialog(_("Switching to full screen"), + new OkDialog(_("Switching to Full Screen"), _("Restart needed for changes to take effect.")); } #endif @@ -377,7 +387,7 @@ void Setup_Video::apply() config.setValue("opengl", mOpenGLCheckBox->isSelected()); // OpenGL can currently only be changed by restarting, notify user. - new OkDialog(_("Changing OpenGL"), + new OkDialog(_("Changing to OpenGL"), _("Applying change to OpenGL requires restart.")); } @@ -436,11 +446,17 @@ void Setup_Video::action(const gcn::ActionEvent &event) const int width = atoi(mode.substr(0, mode.find("x")).c_str()); const int height = atoi(mode.substr(mode.find("x") + 1).c_str()); + // TODO: Find out why the drawing area doesn't resize without a restart. if (width != graphics->getWidth() || height != graphics->getHeight()) { - // TODO: Find out why the drawing area doesn't resize without a restart. - new OkDialog(_("Screen resolution changed"), - _("Restart your client for the change to take effect.")); + if (width < graphics->getWidth() || height < graphics->getHeight()) + new OkDialog(_("Screen Resolution Changed"), + _("Restart your client for the change to take effect.") + + std::string("\n") + + _("Some windows may be moved to fit the lowered resolution.")); + else + new OkDialog(_("Screen Resolution Changed"), + _("Restart your client for the change to take effect.")); } config.setValue("screenwidth", width); @@ -464,7 +480,7 @@ void Setup_Video::action(const gcn::ActionEvent &event) mParticleEffectsCheckBox->isSelected()); if (engine) { - new OkDialog(_("Particle effect settings changed."), + new OkDialog(_("Particle Effect Settings Changed."), _("Changes will take effect on map change.")); } } diff --git a/src/gui/shortcutwindow.cpp b/src/gui/shortcutwindow.cpp index b9eda02c..8e7e0bee 100644 --- a/src/gui/shortcutwindow.cpp +++ b/src/gui/shortcutwindow.cpp @@ -25,6 +25,7 @@ #include "gui/widgets/layout.h" #include "gui/widgets/scrollarea.h" +#include "gui/setup.h" #include "configuration.h" @@ -42,6 +43,7 @@ ShortcutWindow::ShortcutWindow(const std::string &title, setResizable(true); setDefaultVisible(false); setSaveVisible(true); + setupWindow->registerWindowForReset(this); mItems = content; diff --git a/src/gui/skill.cpp b/src/gui/skill.cpp deleted file mode 100644 index 7698098c..00000000 --- a/src/gui/skill.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/* - * 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 "gui/skill.h" - -#include "gui/table.h" - -#include "gui/widgets/button.h" -#include "gui/widgets/label.h" -#include "gui/widgets/layout.h" -#include "gui/widgets/listbox.h" -#include "gui/widgets/scrollarea.h" -#include "gui/widgets/windowcontainer.h" - -#include "localplayer.h" -#include "log.h" - -#include "net/net.h" -#include "net/skillhandler.h" - -#include "utils/dtor.h" -#include "utils/gettext.h" -#include "utils/stringutils.h" -#include "utils/xml.h" - -static const char *SKILLS_FILE = "skills.xml"; - -struct SkillInfo -{ - std::string name; - bool modifiable; -}; - -static const SkillInfo fakeSkillInfo = { - _("Mystery Skill"), - false -}; - -std::vector<SkillInfo> skill_db; - -static void initSkillinfo(); - -class SkillGuiTableModel : public StaticTableModel -{ -public: - SkillGuiTableModel(SkillDialog *dialog) : - StaticTableModel(0, 3) - { - mEntriesNr = 0; - mDialog = dialog; - update(); - } - - virtual int getRows() const - { - return mEntriesNr; - } - - virtual int getColumnWidth(int index) const - { - if (index == 0) - return 160; - - return 35; - } - - virtual int getRowHeight() const - { - return 12; - } - - virtual void update() - { - mEntriesNr = mDialog->getSkills().size(); - resize(); - - for (int i = 0; i < mEntriesNr; i++) - { - SKILL *skill = mDialog->getSkills()[i]; - SkillInfo const *info; - char tmp[128]; - - if (skill->id >= 0 - && (unsigned int) skill->id < skill_db.size()) - info = &skill_db[skill->id]; - else - info = &fakeSkillInfo; - - sprintf(tmp, "%c%s", info->modifiable? ' ' : '*', info->name.c_str()); - gcn::Label *name_label = new Label(tmp); - - sprintf(tmp, "Lv:%i", skill->lv); - gcn::Label *lv_label = new Label(tmp); - - sprintf(tmp, "Sp:%i", skill->sp); - gcn::Label *sp_label = new Label(tmp); - - set(i, 0, name_label); - set(i, 1, lv_label); - set(i, 2, sp_label); - } - } - -private: - SkillDialog *mDialog; - int mEntriesNr; -}; - - -SkillDialog::SkillDialog(): - Window(_("Skills")) -{ - initSkillinfo(); - mTableModel = new SkillGuiTableModel(this); - mTable = new GuiTable(mTableModel); - mTable->setOpaque(false); - mTable->setLinewiseSelection(true); - mTable->setWrappingEnabled(true); - mTable->setActionEventId("skill"); - mTable->addActionListener(this); - - setWindowName("Skills"); - setCloseButton(true); - setDefaultSize(255, 260, ImageRect::CENTER); - - setMinHeight(50 + mTableModel->getHeight()); - setMinWidth(200); - - ScrollArea *skillScrollArea = new ScrollArea(mTable); - mPointsLabel = new Label(strprintf(_("Skill points: %d"), 0)); - mIncButton = new Button(_("Up"), "inc", this); - mUseButton = new Button(_("Use"), "use", this); - mUseButton->setEnabled(false); - - skillScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - - place(0, 0, skillScrollArea, 5).setPadding(3); - place(0, 1, mPointsLabel, 4); - place(3, 2, mIncButton); - place(4, 2, mUseButton); - - Layout &layout = getLayout(); - layout.setRowHeight(0, Layout::AUTO_SET); - - center(); - loadWindowState(); -} - -SkillDialog::~SkillDialog() -{ - delete_all(mSkillList); -} - -void SkillDialog::action(const gcn::ActionEvent &event) -{ - if (event.getId() == "inc") - { - // Increment skill - int selectedSkill = mTable->getSelectedRow(); - if (selectedSkill >= 0) - Net::getSkillHandler()->up(mSkillList[selectedSkill]->id); - } - else if (event.getId() == "skill" && mTable->getSelectedRow() > -1) - { - SKILL *skill = mSkillList[mTable->getSelectedRow()]; - SkillInfo const *info; - - if (skill->id >= 0 && (unsigned int) skill->id < skill_db.size()) - info = &skill_db[skill->id]; - else - info = &fakeSkillInfo; - - mIncButton->setEnabled(player_node->mSkillPoint > 0 && - info->modifiable); - } - else if (event.getId() == "close") - setVisible(false); -} - -void SkillDialog::update() -{ - mPointsLabel->setCaption(strprintf(_("Skill points: %d"), - player_node->mSkillPoint)); - - int selectedSkill = mTable->getSelectedRow(); - - if (selectedSkill >= 0) - { - int skillId = mSkillList[selectedSkill]->id; - bool modifiable; - - if (skillId >= 0 && (unsigned int) skillId < skill_db.size()) - modifiable = skill_db[skillId].modifiable; - else - modifiable = false; - - mIncButton->setEnabled(modifiable - && player_node->mSkillPoint > 0); - } - else - mIncButton->setEnabled(false); - - mTableModel->update(); - setMinHeight(50 + mTableModel->getHeight()); -} - -int SkillDialog::getNumberOfElements() -{ - return mSkillList.size(); -} - -bool SkillDialog::hasSkill(int id) -{ - for (unsigned int i = 0; i < mSkillList.size(); i++) - { - if (mSkillList[i]->id == id) - return true; - } - return false; -} - -void SkillDialog::addSkill(int id, int lvl, int mp) -{ - SKILL *tmp = new SKILL; - tmp->id = id; - tmp->lv = lvl; - tmp->sp = mp; - mSkillList.push_back(tmp); -} - -void SkillDialog::setSkill(int id, int lvl, int mp) -{ - for (unsigned int i = 0; i < mSkillList.size(); i++) - { - if (mSkillList[i]->id == id) - { - mSkillList[i]->lv = lvl; - mSkillList[i]->sp = mp; - } - } -} - -void SkillDialog::cleanList() -{ - delete_all(mSkillList); - mSkillList.clear(); -} - -static void initSkillinfo() -{ - SkillInfo emptySkillInfo = { "", false }; - - XML::Document doc(SKILLS_FILE); - xmlNodePtr root = doc.rootNode(); - - if (!root || !xmlStrEqual(root->name, BAD_CAST "skills")) - { - logger->log("Error loading skills file: %s", SKILLS_FILE); - skill_db.resize(2, emptySkillInfo); - skill_db[1].name = "Basic"; - skill_db[1].modifiable = true; - return; - } - - for_each_xml_child_node(node, root) - { - if (xmlStrEqual(node->name, BAD_CAST "skill")) - { - int index = atoi(XML::getProperty(node, "id", "-1").c_str()); - std::string name = XML::getProperty(node, "name", ""); - bool modifiable = !atoi(XML::getProperty(node, "fixed", "0").c_str()); - - if (index >= 0) - { - skill_db.resize(index + 1, emptySkillInfo); - skill_db[index].name = name; - skill_db[index].modifiable = modifiable; - } - } - } -} - diff --git a/src/gui/skill.h b/src/gui/skill.h deleted file mode 100644 index 0879f7e1..00000000 --- a/src/gui/skill.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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 "gui/widgets/window.h" - -#include <guichan/actionlistener.hpp> - -#include <vector> - -struct SKILL -{ - short id; /**< Index into "skill_db" array */ - short lv, sp; -}; - -class GuiTable; -class ScrollArea; -class SkillGuiTableModel; - -/** - * The skill dialog. - * - * \ingroup Interface - */ -class SkillDialog : public Window, public gcn::ActionListener -{ - public: - /** - * Constructor. - */ - SkillDialog(); - - /** - * Destructor. - */ - ~SkillDialog(); - - void action(const gcn::ActionEvent &event); - - void update(); - - int getNumberOfElements(); - - bool hasSkill(int id); - void addSkill(int id, int lv, int sp); - void setSkill(int id, int lv, int sp); - void cleanList(); - - const std::vector<SKILL*>& getSkills() const { return mSkillList; } - - private: - GuiTable *mTable; - ScrollArea *skillScrollArea; - SkillGuiTableModel *mTableModel; - gcn::Label *mPointsLabel; - gcn::Button *mIncButton; - gcn::Button *mUseButton; - - std::vector<SKILL*> mSkillList; -}; - -extern SkillDialog *skillDialog; - -#endif diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp index f0cd01ce..14e0e5a4 100644 --- a/src/gui/skilldialog.cpp +++ b/src/gui/skilldialog.cpp @@ -25,105 +25,78 @@ #include "gui/widgets/container.h" #include "gui/widgets/icon.h" #include "gui/widgets/label.h" +#include "gui/widgets/layouthelper.h" #include "gui/widgets/listbox.h" #include "gui/widgets/progressbar.h" #include "gui/widgets/scrollarea.h" +#include "gui/widgets/tab.h" #include "gui/widgets/tabbedarea.h" +#include "gui/widgets/vertcontainer.h" #include "gui/widgets/windowcontainer.h" +#include "gui/setup.h" #include "localplayer.h" +#include "log.h" + +#include "net/net.h" +#include "net/playerhandler.h" #include "utils/dtor.h" #include "utils/gettext.h" #include "utils/stringutils.h" +#include "utils/xml.h" #include <string> #include <vector> -class SkillTab : public Container, public gcn::ActionListener +class SkillEntry; + +struct SkillInfo +{ + unsigned short id; + std::string name; + std::string icon; + bool modifiable; + SkillEntry *display; +}; + +class SkillEntry : public Container, gcn::WidgetListener { public: - /** - * The type of this skill tab - */ - const std::string type; - - /** - * Constructor - */ - SkillTab(const std::string &type); - - /** - * Update this tab - */ + SkillEntry(SkillInfo *info); + + void widgetResized(const gcn::Event &event); + void update(); - /** - * Called when receiving actions from widget. - */ - void action(const gcn::ActionEvent &event) {} + protected: + friend class SkillDialog; + SkillInfo *mInfo; 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; + Icon *mIcon; + Label *mNameLabel; + Label *mLevelLabel; + Label *mExpLabel; + Button *mIncrease; + ProgressBar *mProgress; }; - SkillDialog::SkillDialog(): Window(_("Skills")) { setWindowName("Skills"); setCloseButton(true); + setResizable(true); setSaveVisible(true); setDefaultSize(windowContainer->getWidth() - 280, 30, 275, 425); + setupWindow->registerWindowForReset(this); - TabbedArea *panel = new TabbedArea; - panel->setDimension(gcn::Rectangle(5, 5, 270, 420)); - - SkillTab *tab; - - // Add each type of skill tab to the panel - tab = new SkillTab("Weapon"); - panel->addTab(_("Weapons"), tab); - mTabs.push_back(tab); + mTabs = new TabbedArea(); + mPointsLabel = new Label("0"); - tab = new SkillTab("Magic"); - panel->addTab(_("Magic"), tab); - mTabs.push_back(tab); - - tab = new SkillTab("Craft"); - panel->addTab(_("Crafts"), tab); - mTabs.push_back(tab); - - add(panel); - - update(); + place(0, 0, mTabs, 5, 5); + place(0, 5, mPointsLabel); setLocationRelativeTo(getParent()); loadWindowState(); @@ -131,13 +104,17 @@ SkillDialog::SkillDialog(): SkillDialog::~SkillDialog() { - delete_all(mTabs); + //delete_all(mTabs); } void SkillDialog::action(const gcn::ActionEvent &event) { - if (event.getId() == "skill") + if (event.getId() == "inc") { + SkillEntry *disp = dynamic_cast<SkillEntry*>(event.getSource()->getParent()); + + if (disp) + Net::getPlayerHandler()->increaseSkill(disp->mInfo->id); } else if (event.getId() == "close") { @@ -145,174 +122,254 @@ void SkillDialog::action(const gcn::ActionEvent &event) } } -void SkillDialog::draw(gcn::Graphics *g) +void SkillDialog::adjustTabSize() { - update(); + gcn::Widget *content = mTabs->getCurrentWidget(); + if (content) { + int width = mTabs->getWidth() - 2 * content->getFrameSize() - 2 * mTabs->getFrameSize(); + int height = mTabs->getContainerHeight() - 2 * content->getFrameSize(); + content->setSize(width, height); + content->setVisible(true); + content->logic(); + } +} + +void SkillDialog::widgetResized(const gcn::Event &event) +{ + Window::widgetResized(event); - Window::draw(g); + adjustTabSize(); } -void SkillDialog::update() +void SkillDialog::logic() { - for(std::list<SkillTab*>::const_iterator i = mTabs.begin(); - i != mTabs.end(); ++i) - { - (*i)->update(); + Window::logic(); + + Tab *tab = dynamic_cast<Tab*>(mTabs->getSelectedTab()); + if (tab != mCurrentTab) { + mCurrentTab = tab; + adjustTabSize(); } } -SkillTab::SkillTab(const std::string &type): type(type) +std::string SkillDialog::update(int id) { - 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); + SkillMap::iterator i = mSkills.find(id); - // Set the initial positions of the skill information - for (int a = 0; a < skillNum; a++) + if (i != mSkills.end()) { - mSkillIcons.at(a) = getIcon(a); - mSkillIcons.at(a)->setPosition(1, a*32); - add(mSkillIcons.at(a)); - - mSkillNameLabels.at(a) = new Label(""); - mSkillNameLabels.at(a)->setPosition(35, a*32 ); - add(mSkillNameLabels.at(a)); + SkillInfo *info = i->second; + info->display->update(); + return info->name; + } - mSkillProgress.at(a) = new ProgressBar(0.0f, 200, 20, gcn::Color(150, 150, 150)); - mSkillProgress.at(a)->setPosition(35, a*32 + 13); - add(mSkillProgress.at(a)); + return std::string(); +} - mSkillExpLabels.at(a) = new Label(""); - mSkillExpLabels.at(a)->setPosition(45, a*32 + 16); - add(mSkillExpLabels.at(a)); +void SkillDialog::update() +{ + mPointsLabel->setCaption(strprintf(_("Skill points available: %d"), + player_node->getSkillPoints())); + mPointsLabel->adjustSize(); - mSkillLevelLabels.at(a) = new Label(""); - mSkillLevelLabels.at(a)->setPosition(165, a*32); - add(mSkillLevelLabels.at(a)); + for (SkillMap::iterator it = mSkills.begin(); it != mSkills.end(); it++) + { + if ((*it).second->modifiable) + (*it).second->display->update(); } - - update(); } -int SkillTab::getSkillNum() +void SkillDialog::loadSkills(const std::string &file) { - int skillNum = 0; + // TODO: mTabs->clear(); + delete_all(mSkills); + mSkills.clear(); - if (type == "Weapon") + XML::Document doc(file); + xmlNodePtr root = doc.rootNode(); + + if (!root || !xmlStrEqual(root->name, BAD_CAST "skills")) { - skillNum = CHAR_SKILL_WEAPON_NB; - return skillNum; + logger->log("Error loading skills file: %s", file.c_str()); + return; } - else if (type == "Magic") + + int setCount = 0; + std::string setName; + ScrollArea *scroll; + VertContainer *container; + + for_each_xml_child_node(set, root) { - skillNum = CHAR_SKILL_MAGIC_NB; - return skillNum; + if (xmlStrEqual(set->name, BAD_CAST "set")) + { + setCount++; + setName = XML::getProperty(set, "name", strprintf(_("Skill Set %d"), setCount)); + + container = new VertContainer(32); + container->setOpaque(false); + scroll = new ScrollArea(container); + scroll->setOpaque(false); + scroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER); + scroll->setVerticalScrollPolicy(ScrollArea::SHOW_ALWAYS); + + mTabs->addTab(setName, scroll); + for_each_xml_child_node(node, set) + { + if (xmlStrEqual(node->name, BAD_CAST "skill")) + { + int id = atoi(XML::getProperty(node, "id", "-1").c_str()); + std::string name = XML::getProperty(node, "name", strprintf(_("Skill %d"), id)); + std::string icon = XML::getProperty(node, "icon", ""); + + SkillInfo *skill = new SkillInfo; + skill->id = id; + skill->name = name; + skill->icon = icon; + skill->modifiable = 0; + skill->display = new SkillEntry(skill); + + container->add(skill->display); + + mSkills[id] = skill; + } + } + } } - else if (type == "Craft") + + adjustTabSize(); + update(); +} + +void SkillDialog::setModifiable(int id, bool modifiable) +{ + SkillMap::iterator i = mSkills.find(id); + + if (i != mSkills.end()) { - skillNum = CHAR_SKILL_CRAFT_NB; - return skillNum; + SkillInfo *info = i->second; + info->modifiable = modifiable; + info->display->update(); } - else return skillNum; } -int SkillTab::getSkillBegin() +SkillEntry::SkillEntry(SkillInfo *info) : + mInfo(info), + mIcon(NULL), + mNameLabel(new Label(info->name)), + mLevelLabel(new Label("999")), + mIncrease(new Button(_("+"), "inc", skillDialog)), + mProgress(new ProgressBar(0.0f, 200, 20, gcn::Color(150, 150, 150))) +{ + setFrameSize(1); + setOpaque(false); + + addWidgetListener(this); + + if (!info->icon.empty()) + mIcon = new Icon(info->icon); + else + mIcon = new Icon("graphics/gui/unknown-item.png"); + + mIcon->setPosition(1, 0); + add(mIcon); + + mNameLabel->setPosition(35, 0); + add(mNameLabel); + + mLevelLabel->setPosition(165, 0); + add(mLevelLabel); + + mProgress->setPosition(35, 13); + add(mProgress); + + mIncrease->setPosition(getWidth() - mIncrease->getWidth(), 13); + add(mIncrease); + + update(); +} + +void SkillEntry::widgetResized(const gcn::Event &event) { - int skillBegin = 0; + gcn::Rectangle size = getChildrenArea(); - if (type == "Weapon") + if (mProgress->isVisible() && mIncrease->isVisible()) { - skillBegin = CHAR_SKILL_WEAPON_BEGIN - CHAR_SKILL_BEGIN; - return skillBegin; + mLevelLabel->setPosition(size.width - mLevelLabel->getWidth() + - mIncrease->getWidth() - 4, 0); + mProgress->setWidth(size.width - mIncrease->getWidth() - 39); + mIncrease->setPosition(getWidth() - mIncrease->getWidth() - 2, 6); } - else if (type == "Magic") + else if (mProgress->isVisible()) { - skillBegin = CHAR_SKILL_MAGIC_BEGIN - CHAR_SKILL_BEGIN; - return skillBegin; + mLevelLabel->setPosition(size.width - mLevelLabel->getWidth(), 0); + mProgress->setWidth(size.width - 39); } - else if (type == "Craft") + else if (mIncrease->isVisible()) { - skillBegin = CHAR_SKILL_CRAFT_BEGIN - CHAR_SKILL_BEGIN; - return skillBegin; + mLevelLabel->setPosition(size.width - mLevelLabel->getWidth() + - mIncrease->getWidth() - 4, 0); + mIncrease->setPosition(getWidth() - mIncrease->getWidth() - 2, 6); } - else return skillBegin; + else + mLevelLabel->setPosition(size.width - mLevelLabel->getWidth(), 0); } -Icon* SkillTab::getIcon(int index) +void SkillEntry::update() { - int skillBegin = getSkillBegin(); - std::string icon = LocalPlayer::getSkillInfo(index + skillBegin).icon; - return new Icon(icon); -} + int baseLevel = player_node->getAttributeBase(mInfo->id); + int effLevel = player_node->getAttributeEffective(mInfo->id); -void SkillTab::updateSkill(int index) -{ - int skillBegin = getSkillBegin(); + if (baseLevel <= 0 && !mInfo->modifiable) + { + setVisible(false); + return; + } + + setVisible(true); - int baseLevel = player_node->getAttributeBase(index + - skillBegin + - CHAR_SKILL_BEGIN); + std::string skillLevel; - int effLevel = player_node->getAttributeEffective(index + - skillBegin + - CHAR_SKILL_BEGIN); - if(baseLevel <= 0) + if (effLevel != baseLevel) { - 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); + skillLevel = strprintf(_("Lvl: %d (%+d)"), + baseLevel, baseLevel - effLevel); } 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); + skillLevel = strprintf(_("Lvl: %d"), baseLevel); + } - std::pair<int, int> exp = player_node->getExperience(index + skillBegin); - std::string sExp (toString(exp.first) + " / " + toString(exp.second)); + mLevelLabel->setCaption(skillLevel); + std::pair<int, int> exp = player_node->getExperience(mInfo->id); + 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); + mLevelLabel->adjustSize(); + + if (exp.second) + { + mProgress->setVisible(true); + mProgress->setText(sExp); // 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); + mProgress->setColor(244, color, color); + mProgress->setProgress((float) exp.first / exp.second); } -} - -void SkillTab::update() -{ - int skillNum = getSkillNum(); + else + mProgress->setVisible(false); - // Update the skill information for reach skill - for (int a = 0; a < skillNum; a++) + if (mInfo->modifiable) { - updateSkill(a); + mIncrease->setVisible(true); + mIncrease->setEnabled(player_node->getSkillPoints()); } + else + { + mIncrease->setVisible(false); + mIncrease->setEnabled(false); + } + + widgetResized(NULL); } diff --git a/src/gui/skilldialog.h b/src/gui/skilldialog.h index 56192273..ce8f091a 100644 --- a/src/gui/skilldialog.h +++ b/src/gui/skilldialog.h @@ -29,10 +29,14 @@ #include <guichan/actionlistener.hpp> #include <list> +#include <map> -class ProgressBar; -class Icon; -class SkillTab; +class Label; +class ScrollArea; +class Tab; +class TabbedArea; + +struct SkillInfo; /** * The skill dialog. @@ -52,17 +56,35 @@ class SkillDialog : public Window, public gcn::ActionListener void action(const gcn::ActionEvent &event); /** - * Update the tabs in this dialog + * Called when the widget changes size. Used for adapting the size of + * the tabbed area. */ - void update(); + void widgetResized(const gcn::Event &event); + + void logic(); /** - * Draw this window. - */ - void draw(gcn::Graphics *g); + * Update the given skill's display + */ + std::string update(int id); + + /** + * Update other parts of the display + */ + void update(); + + void loadSkills(const std::string &file); + + void setModifiable(int id, bool modifiable); private: - std::list<SkillTab*> mTabs; + void adjustTabSize(); + + typedef std::map<int, SkillInfo*> SkillMap; + SkillMap mSkills; + Tab *mCurrentTab; + TabbedArea *mTabs; + Label *mPointsLabel; }; extern SkillDialog *skillDialog; diff --git a/src/gui/speechbubble.cpp b/src/gui/speechbubble.cpp index 959e47ee..c2703327 100644 --- a/src/gui/speechbubble.cpp +++ b/src/gui/speechbubble.cpp @@ -28,8 +28,6 @@ #include "graphics.h" -#include "utils/gettext.h" - #include <guichan/font.hpp> #include <guichan/widgets/label.hpp> diff --git a/src/gui/status.cpp b/src/gui/status.cpp deleted file mode 100644 index eca01725..00000000 --- a/src/gui/status.cpp +++ /dev/null @@ -1,414 +0,0 @@ -/* - * 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 "gui/status.h" -#include "gui/palette.h" - -#include "localplayer.h" -#include "units.h" - -#include "gui/widgets/button.h" -#include "gui/widgets/label.h" -#include "gui/widgets/layout.h" -#include "gui/widgets/progressbar.h" -#include "gui/widgets/windowcontainer.h" - -#include "net/net.h" -#include "net/ea/playerhandler.h" - -#include "utils/gettext.h" -#include "utils/mathutils.h" -#include "utils/stringutils.h" - -StatusWindow::StatusWindow(LocalPlayer *player): - Window(player->getName()), - mPlayer(player), - mCurrency(0) -{ - setWindowName("Status"); - setCloseButton(true); - setSaveVisible(true); - setDefaultSize(400, 345, ImageRect::CENTER); - - // ---------------------- - // Status Part - // ---------------------- - - mLvlLabel = new Label(strprintf(_("Level: %d"), 0)); - mJobLvlLabel = new Label(strprintf(_("Job: %d"), 0)); - mGpLabel = new Label(strprintf(_("Money: %s"), - Units::formatCurrency(mCurrency).c_str())); - - mHpLabel = new Label(_("HP:")); - mHpBar = new ProgressBar(0.0f, 80, 15, gcn::Color(0, 171, 34)); - - mXpLabel = new Label(_("Exp:")); - mXpBar = new ProgressBar(0.0f, 80, 15, gcn::Color(143, 192, 211)); - - mMpLabel = new Label(_("MP:")); - mMpBar = new ProgressBar(0.0f, 80, 15, gcn::Color(26, 102, 230)); - - mJobLabel = new Label(_("Job:")); - mJobBar = new ProgressBar(0.0f, 80, 15, gcn::Color(220, 135, 203)); - - // ---------------------- - // Stats Part - // ---------------------- - - // Static Labels - gcn::Label *mStatsTitleLabel = new Label(_("Stats")); - gcn::Label *mStatsTotalLabel = new Label(_("Total")); - gcn::Label *mStatsCostLabel = new Label(_("Cost")); - mStatsTotalLabel->setAlignment(gcn::Graphics::CENTER); - - // Derived Stats - mStatsAttackLabel = new Label(_("Attack:")); - 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; - mStatsDefensePoints = new Label; - mStatsMagicAttackPoints = new Label; - mStatsMagicDefensePoints = new Label; - mStatsAccuracyPoints = new Label; - mStatsEvadePoints = new Label; - mStatsReflexPoints = new Label; - - // New labels - for (int i = 0; i < 6; i++) - { - mStatsLabel[i] = new Label("0"); - mStatsLabel[i]->setAlignment(gcn::Graphics::CENTER); - mStatsDisplayLabel[i] = new Label; - mPointsLabel[i] = new Label("0"); - mPointsLabel[i]->setAlignment(gcn::Graphics::CENTER); - } - mRemainingStatsPointsLabel = new Label; - - // Set button events Id - mStatsButton[0] = new Button("+", "STR", this); - mStatsButton[1] = new Button("+", "AGI", this); - mStatsButton[2] = new Button("+", "VIT", this); - mStatsButton[3] = new Button("+", "INT", this); - mStatsButton[4] = new Button("+", "DEX", this); - mStatsButton[5] = new Button("+", "LUK", this); - - // Assemble - ContainerPlacer place; - place = getPlacer(0, 0); - - place(0, 0, mLvlLabel, 3); - place(5, 0, mJobLvlLabel, 3); - place(8, 0, mGpLabel, 3); - place(0, 1, mHpLabel).setPadding(3); - place(1, 1, mHpBar, 4); - place(5, 1, mXpLabel).setPadding(3); - place(6, 1, mXpBar, 5); - place(0, 2, mMpLabel).setPadding(3); - place(1, 2, mMpBar, 4); - place(5, 2, mJobLabel).setPadding(3); - place(6, 2, mJobBar, 5); - place.getCell().matchColWidth(0, 1); - place = getPlacer(0, 3); - place(0, 1, mStatsTitleLabel, 5); - place(5, 1, mStatsTotalLabel, 5); - place(12, 1, mStatsCostLabel, 5); - for (int i = 0; i < 6; i++) - { - place(0, 2 + i, mStatsLabel[i], 7).setPadding(5); - place(7, 2 + i, mStatsDisplayLabel[i]).setPadding(5); - place(10, 2 + i, mStatsButton[i]); - place(12, 2 + i, mPointsLabel[i]).setPadding(5); - } - place(14, 2, mStatsAttackLabel, 7).setPadding(5); - place(14, 3, mStatsDefenseLabel, 7).setPadding(5); - place(14, 4, mStatsMagicAttackLabel, 7).setPadding(5); - place(14, 5, mStatsMagicDefenseLabel, 7).setPadding(5); - place(14, 6, mStatsAccuracyLabel, 7).setPadding(5); - place(14, 7, mStatsEvadeLabel, 7).setPadding(5); - place(14, 8, mStatsReflexLabel, 7).setPadding(5); - place(21, 2, mStatsAttackPoints, 3).setPadding(5); - place(21, 3, mStatsDefensePoints, 3).setPadding(5); - place(21, 4, mStatsMagicAttackPoints, 3).setPadding(5); - place(21, 5, mStatsMagicDefensePoints, 3).setPadding(5); - place(21, 6, mStatsAccuracyPoints, 3).setPadding(5); - place(21, 7, mStatsEvadePoints, 3).setPadding(5); - place(21, 8, mStatsReflexPoints, 3).setPadding(5); - place(0, 8, mRemainingStatsPointsLabel, 3).setPadding(5); - - Layout &layout = getLayout(); - layout.setRowHeight(0, Layout::AUTO_SET); - - loadWindowState(); -} - -void StatusWindow::update() -{ - // Status Part - // ----------- - mLvlLabel->setCaption(strprintf(_("Level: %d"), mPlayer->getLevel())); - mLvlLabel->adjustSize(); - - mJobLvlLabel->setCaption(strprintf(_("Job: %d"), mPlayer->mJobLevel)); - mJobLvlLabel->adjustSize(); - - if (mCurrency != mPlayer->getMoney()) { - mCurrency = mPlayer->getMoney(); - mGpLabel->setCaption(strprintf(_("Money: %s"), - Units::formatCurrency(mCurrency).c_str())); - mGpLabel->adjustSize(); - } - - updateHPBar(mHpBar, true); - - updateMPBar(mMpBar, true); - - updateXPBar(mXpBar, false); - - updateJobBar(mJobBar, false); - - // Stats Part - // ---------- - static const char *attrNames[6] = { - N_("Strength"), - N_("Agility"), - N_("Vitality"), - N_("Intelligence"), - N_("Dexterity"), - N_("Luck") - }; - int statusPoints = mPlayer->mStatsPointsToAttribute; - - // Update labels - for (int i = 0; i < 6; i++) - { - mStatsLabel[i]->setCaption(gettext(attrNames[i])); - mStatsDisplayLabel[i]->setCaption(toString((int) mPlayer->mAttr[i])); - mPointsLabel[i]->setCaption(toString((int) mPlayer->mAttrUp[i])); - - mStatsLabel[i]->adjustSize(); - mStatsDisplayLabel[i]->adjustSize(); - mPointsLabel[i]->adjustSize(); - - mStatsButton[i]->setEnabled(mPlayer->mAttrUp[i] <= statusPoints); - } - mRemainingStatsPointsLabel->setCaption( - strprintf(_("Remaining Status Points: %d"), statusPoints)); - mRemainingStatsPointsLabel->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(); -} - -void StatusWindow::draw(gcn::Graphics *g) -{ - update(); - - Window::draw(g); -} - -void StatusWindow::action(const gcn::ActionEvent &event) -{ - // Stats Part - // Net::getPlayerHandler()->increaseStat(?); - if (event.getId().length() == 3) - { - if (event.getId() == "STR") - Net::getPlayerHandler()->increaseStat(LocalPlayer::STR); - if (event.getId() == "AGI") - Net::getPlayerHandler()->increaseStat(LocalPlayer::AGI); - if (event.getId() == "VIT") - Net::getPlayerHandler()->increaseStat(LocalPlayer::VIT); - if (event.getId() == "INT") - Net::getPlayerHandler()->increaseStat(LocalPlayer::INT); - if (event.getId() == "DEX") - Net::getPlayerHandler()->increaseStat(LocalPlayer::DEX); - if (event.getId() == "LUK") - Net::getPlayerHandler()->increaseStat(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 - float r1 = 255; - float g1 = 255; - float b1 = 255; - - float r2 = 255; - float g2 = 255; - float b2 = 255; - - float weight = 1.0f; - - int curHP = player_node->getHp(); - int thresholdLevel = player_node->getMaxHp() / 4; - int thresholdProgress = curHP % thresholdLevel; - weight = 1-((float)thresholdProgress) / ((float)thresholdLevel); - - if (curHP < (thresholdLevel)) - { - gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_ONE_HALF); - gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_ONE_QUARTER); - r1 = color1.r; r2 = color2.r; - g1 = color1.g; g2 = color2.g; - b1 = color1.b; b2 = color2.b; - } - else if (curHP < (thresholdLevel*2)) - { - gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_THREE_QUARTERS); - gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_ONE_HALF); - r1 = color1.r; r2 = color2.r; - g1 = color1.g; g2 = color2.g; - b1 = color1.b; b2 = color2.b; - } - else if (curHP < thresholdLevel*3) - { - gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_FULL); - gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_THREE_QUARTERS); - r1 = color1.r; r2 = color2.r; - g1 = color1.g; g2 = color2.g; - b1 = color1.b; b2 = color2.b; - } - else - { - gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_FULL); - gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_FULL); - r1 = color1.r; r2 = color2.r; - g1 = color1.g; g2 = color2.g; - b1 = color1.b; b2 = color2.b; - } - - // Safety checks - if (weight > 1.0f) weight = 1.0f; - if (weight < 0.0f) weight = 0.0f; - - // Do the color blend - r1 = (int) weightedAverage(r1, r2,weight); - g1 = (int) weightedAverage(g1, g2, weight); - b1 = (int) weightedAverage(b1, b2, weight); - - // More safety checks - if (r1 > 255) r1 = 255; - if (g1 > 255) g1 = 255; - if (b1 > 255) b1 = 255; - - bar->setColor(r1, g1, b1); - - 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)); - - if (player_node->MATK <= 0) - bar->setColor(100, 100, 100); // grey, to indicate that we lack magic - else - bar->setColor(26, 102, 230); // blue, to indicate that we have magic - - bar->setProgress((float) player_node->mMp / (float) player_node->mMaxMp); -} - -static void updateProgressBar(ProgressBar *bar, int value, int max, - bool percent) -{ - if (max == 0) - { - bar->setText(_("Max level")); - bar->setProgress(1.0); - } - else - { - float progress = (float) value / max; - - if (percent) - bar->setText(strprintf("%2.2f", 100 * progress) + "%"); - else - bar->setText(toString(value) + "/" + toString(max)); - - bar->setProgress(progress); - } -} - -void StatusWindow::updateXPBar(ProgressBar *bar, bool percent) -{ - updateProgressBar(bar, - player_node->getXp(), - player_node->mXpForNextLevel, - percent); -} - -void StatusWindow::updateJobBar(ProgressBar *bar, bool percent) -{ - updateProgressBar(bar, - player_node->mJobXp, - player_node->mJobXpForNextLevel, - percent); -} diff --git a/src/gui/status.h b/src/gui/status.h deleted file mode 100644 index 403a7d59..00000000 --- a/src/gui/status.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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 "gui/widgets/window.h" - -#include <guichan/actionlistener.hpp> - -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); - 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; - - /** - * Status Part - */ - gcn::Label *mLvlLabel, *mJobLvlLabel; - gcn::Label *mGpLabel; - int mCurrency; - gcn::Label *mHpLabel, *mMpLabel, *mXpLabel, *mJobLabel; - ProgressBar *mHpBar, *mMpBar; - ProgressBar *mXpBar, *mJobBar; - - /** - * 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 *mPointsLabel[6]; - gcn::Label *mStatsDisplayLabel[6]; - gcn::Label *mRemainingStatsPointsLabel; - - /** - * Stats buttons. - */ - gcn::Button *mStatsButton[6]; -}; - -extern StatusWindow *statusWindow; - -#endif diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp index edbf387b..6f5f72fa 100644 --- a/src/gui/statuswindow.cpp +++ b/src/gui/statuswindow.cpp @@ -23,353 +23,494 @@ #include "gui/widgets/button.h" #include "gui/widgets/label.h" +#include "gui/widgets/layouthelper.h" #include "gui/widgets/progressbar.h" +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/vertcontainer.h" #include "gui/widgets/windowcontainer.h" +#include "gui/ministatus.h" +#include "gui/setup.h" + #include "localplayer.h" +#include "units.h" + +#include "net/net.h" +#include "net/playerhandler.h" + +#ifdef EATHENA_SUPPORT +#include "net/ea/protocol.h" +#endif +#include "utils/gettext.h" +#include "utils/mathutils.h" #include "utils/stringutils.h" -StatusWindow::StatusWindow(LocalPlayer *player): - Window(player->getName()), - mPlayer(player) +class AttrDisplay : public Container +{ + public: + virtual std::string update(); + + protected: + AttrDisplay(int id, const std::string &name); + + const int mId; + const std::string mName; + + LayoutHelper *mLayout; + Label *mLabel; + Label *mValue; +}; + +class DerDisplay : public AttrDisplay +{ + public: + DerDisplay(int id, const std::string &name); +}; + +class ChangeDisplay : public AttrDisplay, gcn::ActionListener +{ + public: + ChangeDisplay(int id, const std::string &name); + std::string update(); + void setPointsNeeded(int needed); + + private: + void action(const gcn::ActionEvent &event); + + int mNeeded; + + Label *mPoints; + Button *mDec; + Button *mInc; +}; + +StatusWindow::StatusWindow(): + Window(player_node->getName()) { setWindowName("Status"); + setupWindow->registerWindowForReset(this); setResizable(true); setCloseButton(true); setSaveVisible(true); setDefaultSize((windowContainer->getWidth() - 365) / 2, (windowContainer->getHeight() - 255) / 2, 365, 275); - loadWindowState(); // ---------------------- // Status Part // ---------------------- - mLvlLabel = new Label("Level:"); - mMoneyLabel = new Label("Money:"); - - mHpLabel = new Label("HP:"); - mHpBar = new ProgressBar(0.0f, 80, 15, gcn::Color(0, 171, 34)); - mHpValueLabel = new 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); + mLvlLabel = new Label(strprintf(_("Level: %d"), 0)); + mMoneyLabel = new Label(strprintf(_("Money: %s"), "")); + + mHpLabel = new Label(_("HP:")); + mHpBar = new ProgressBar((float) player_node->getHp() + / (float) player_node->getMaxHp(), + 80, 15, gcn::Color(0, 171, 34)); + + mXpLabel = new Label(_("Exp:")); + mXpBar = new ProgressBar((float) player_node->getExp() + / player_node->getExpNeeded(), + 80, 15, gcn::Color(143, 192, 211)); + + mMpLabel = new Label(_("MP:")); + mMpBar = new ProgressBar((float) player_node->getMaxMP() + / (float) player_node->getMaxMP(), + 80, 15, gcn::Color(26, 102, 230)); + + place(0, 0, mLvlLabel, 3); + // 5, 0 Job Level + place(8, 0, mMoneyLabel, 3); + place(0, 1, mHpLabel).setPadding(3); + place(1, 1, mHpBar, 4); + place(5, 1, mXpLabel).setPadding(3); + place(6, 1, mXpBar, 5); + place(0, 2, mMpLabel).setPadding(3); + // 5, 2 and 6, 2 Job Progress Bar + place(1, 2, mMpBar, 4); + +#ifdef EATHENA_SUPPORT + mJobLvlLabel = new Label(strprintf(_("Job: %d"), 0)); + mJobLabel = new Label(_("Job:")); + mJobBar = new ProgressBar(0.0f, 80, 15, gcn::Color(220, 135, 203)); + + place(5, 0, mJobLvlLabel, 3); + place(5, 2, mJobLabel).setPadding(3); + place(6, 2, mJobBar, 5); +#endif // ---------------------- // Stats Part // ---------------------- - // Static Labels - gcn::Label *mStatsTitleLabel = new Label("Stats"); - gcn::Label *mStatsTotalLabel = new Label("Total"); - - // Derived Stats -/* - mStatsAttackLabel = new Label("Attack:"); - mStatsDefenseLabel= new Label("Defense:"); - mStatsMagicAttackLabel = new Label("M.Attack:"); - mStatsMagicDefenseLabel = new Label("M.Defense:"); - mStatsAccuracyLabel = new Label("% Accuracy:"); - mStatsEvadeLabel = new Label("% Evade:"); - mStatsReflexLabel = new Label("% Reflex:"); - - mStatsAttackPoints = new Label; - mStatsDefensePoints = new Label; - mStatsMagicAttackPoints = new Label; - mStatsMagicDefensePoints = new Label; - mStatsAccuracyPoints = new Label("% Accuracy:"); - mStatsEvadePoints = new Label("% Evade:"); - mStatsReflexPoints = new Label("% Reflex:"); -*/ - // New labels - for (int i = 0; i < 6; i++) { - mStatsLabel[i] = new Label; - mStatsDisplayLabel[i] = new Label; - } - mCharacterPointsLabel = new Label; - mCorrectionPointsLabel = new 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); + mAttrCont = new VertContainer(32); + mAttrScroll = new ScrollArea(mAttrCont); + mAttrScroll->setOpaque(false); + mAttrScroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER); + mAttrScroll->setVerticalScrollPolicy(ScrollArea::SHOW_AUTO); + place(0, 3, mAttrScroll, 5, 3); - 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); + mDAttrCont = new VertContainer(32); + mDAttrScroll = new ScrollArea(mDAttrCont); + mDAttrScroll->setOpaque(false); + mDAttrScroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER); + mDAttrScroll->setVerticalScrollPolicy(ScrollArea::SHOW_AUTO); + place(6, 3, mDAttrScroll, 5, 3); + getLayout().setRowHeight(3, Layout::AUTO_SET); + mCharacterPointsLabel = new Label("C"); + mCorrectionPointsLabel = new Label("C"); + place(0, 6, mCharacterPointsLabel, 5); + place(0, 7, mCorrectionPointsLabel, 5); - // 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); - } + loadWindowState(); - 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); + update(HP); + update(MP); + update(EXP); + update(MONEY); + update(CHAR_POINTS); // This also updates all attributes (none atm) + update(LEVEL); +#ifdef EATHENA_SUPPORT + update(JOB); +#endif } -void StatusWindow::update() +std::string StatusWindow::update(int id) { - // Status Part - // ----------- - mLvlLabel->setCaption( "Level: " + - toString(mPlayer->getLevel()) + - " (" + - toString(mPlayer->getLevelProgress()) + - "%)"); - mLvlLabel->adjustSize(); - - mMoneyLabel->setCaption("Money: " + toString(mPlayer->getMoney()) + " GP"); - mMoneyLabel->adjustSize(); + if (miniStatusWindow) + miniStatusWindow->update(id); - 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++) + if (id == HP) { - 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(); + updateHPBar(mHpBar, true); - mStatsPlus[i]->setEnabled(characterPoints); - mStatsMinus[i]->setEnabled(correctionPoints); + return _("HP"); } - 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+") + else if (id == MP) { - mPlayer->raiseAttribute(LocalPlayer::STR); + updateMPBar(mMpBar, true); + + return _("MP"); } - else if (eventId == "AGI+") + else if (id == EXP) { - mPlayer->raiseAttribute(LocalPlayer::AGI); + updateXPBar(mXpBar, false); + + return _("Exp"); } - else if (eventId == "DEX+") + else if (id == MONEY) { - mPlayer->raiseAttribute(LocalPlayer::DEX); + int money = player_node->getMoney(); + mMoneyLabel->setCaption(strprintf(_("Money: %s"), + Units::formatCurrency(money).c_str())); + mMoneyLabel->adjustSize(); + + return _("Money"); } - else if (eventId == "VIT+") +#ifdef EATHENA_SUPPORT + else if (id == JOB) { - mPlayer->raiseAttribute(LocalPlayer::VIT); + mJobLvlLabel->setCaption(strprintf(_("Job: %d"), + player_node->getAttributeBase(JOB))); + mJobLvlLabel->adjustSize(); + + updateProgressBar(mJobBar, JOB, false); + + return _("Job"); } - else if (eventId == "INT+") +#endif + else if (id == CHAR_POINTS) { - mPlayer->raiseAttribute(LocalPlayer::INT); + mCharacterPointsLabel->setCaption(strprintf(_("Character points: %d"), + player_node->getCharacterPoints())); + mCharacterPointsLabel->adjustSize(); + + mCorrectionPointsLabel->setCaption(strprintf(_("Correction points: %d"), + player_node->getCorrectionPoints())); + mCorrectionPointsLabel->adjustSize(); + + for (Attrs::iterator it = mAttrs.begin(); it != mAttrs.end(); it++) + { + it->second->update(); + } } - else if (eventId == "WIL+") + else if (id == LEVEL) { - mPlayer->raiseAttribute(LocalPlayer::WIL); - } + mLvlLabel->setCaption(strprintf(_("Level: %d"), + player_node->getLevel())); + mLvlLabel->adjustSize(); - else if (eventId == "STR-") - { - mPlayer->lowerAttribute(LocalPlayer::STR); - } - else if (eventId == "AGI-") - { - mPlayer->lowerAttribute(LocalPlayer::AGI); + return _("Level"); } - else if (eventId == "DEX-") + else { - mPlayer->lowerAttribute(LocalPlayer::DEX); + Attrs::iterator it = mAttrs.find(id); + + if (it != mAttrs.end()) + { + return it->second->update(); + } } - else if (eventId == "VIT-") + + return ""; +} + +void StatusWindow::setPointsNeeded(int id, int needed) +{ + Attrs::iterator it = mAttrs.find(id); + + if (it != mAttrs.end()) { - mPlayer->lowerAttribute(LocalPlayer::VIT); + ChangeDisplay *disp = dynamic_cast<ChangeDisplay*>(it->second); + if (disp) + disp->setPointsNeeded(needed); } - else if (eventId == "INT-") +} + +void StatusWindow::addAttribute(int id, const std::string &name, + bool modifiable) +{ + AttrDisplay *disp; + + if (modifiable) { - mPlayer->lowerAttribute(LocalPlayer::INT); + disp = new ChangeDisplay(id, name); + mAttrCont->add(disp); } - else if (eventId == "WIL-") + else { - mPlayer->lowerAttribute(LocalPlayer::WIL); + disp = new DerDisplay(id, name); + mDAttrCont->add(disp); } -} -// WARNING: Duplicated method! + mAttrs[id] = disp; +} 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) + if (player_node->getMaxHp() < 4) { - bar->setColor(223, 32, 32); // Red + bar->setColor(guiPalette->getColor(Palette::HPBAR_ONE_QUARTER)); } - else if (player_node->getHp() < (player_node->getMaxHp() / 3) * 2) + else { - bar->setColor(230, 171, 34); // Orange + // HP Bar coloration + float r1 = 255; + float g1 = 255; + float b1 = 255; + + float r2 = 255; + float g2 = 255; + float b2 = 255; + + float weight = 1.0f; + + int curHP = player_node->getHp(); + int thresholdLevel = player_node->getMaxHp() / 4; + int thresholdProgress = curHP % thresholdLevel; + + if (thresholdLevel) + weight = 1 - ((float)thresholdProgress) / ((float)thresholdLevel); + else + weight = 0; + + if (curHP < (thresholdLevel)) + { + gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_ONE_HALF); + gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_ONE_QUARTER); + r1 = color1.r; r2 = color2.r; + g1 = color1.g; g2 = color2.g; + b1 = color1.b; b2 = color2.b; + } + else if (curHP < (thresholdLevel*2)) + { + gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_THREE_QUARTERS); + gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_ONE_HALF); + r1 = color1.r; r2 = color2.r; + g1 = color1.g; g2 = color2.g; + b1 = color1.b; b2 = color2.b; + } + else if (curHP < thresholdLevel*3) + { + gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_FULL); + gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_THREE_QUARTERS); + r1 = color1.r; r2 = color2.r; + g1 = color1.g; g2 = color2.g; + b1 = color1.b; b2 = color2.b; + } + else + { + gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_FULL); + gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_FULL); + r1 = color1.r; r2 = color2.r; + g1 = color1.g; g2 = color2.g; + b1 = color1.b; b2 = color2.b; + } + + // Safety checks + if (weight > 1.0f) weight = 1.0f; + if (weight < 0.0f) weight = 0.0f; + + // Do the color blend + r1 = (int) weightedAverage(r1, r2,weight); + g1 = (int) weightedAverage(g1, g2, weight); + b1 = (int) weightedAverage(b1, b2, weight); + + // More safety checks + if (r1 > 255) r1 = 255; + if (g1 > 255) g1 = 255; + if (b1 > 255) b1 = 255; + + bar->setColor(r1, g1, b1); } + + bar->setProgress((float) player_node->getHp() / (float) player_node->getMaxHp()); + +} + +void StatusWindow::updateMPBar(ProgressBar *bar, bool showMax) +{ + if (showMax) + bar->setText(toString(player_node->getMP()) + + "/" + toString(player_node->getMaxMP())); else + bar->setText(toString(player_node->getMP())); + + if (Net::getPlayerHandler()->canUseMagic()) + bar->setColor(26, 102, 230); // blue, to indicate that we have magic + else + bar->setColor(100, 100, 100); // grey, to indicate that we lack magic + + bar->setProgress((float) player_node->getMP() / + (float) player_node->getMaxMP()); +} + +void StatusWindow::updateProgressBar(ProgressBar *bar, int value, int max, + bool percent) +{ + if (max == 0) { - bar->setColor(0, 171, 34); // Green + bar->setText(_("Max")); + bar->setProgress(1.0); } + else + { + float progress = (float) value / max; - bar->setProgress((float) player_node->getHp() / (float) player_node->getMaxHp()); + if (percent) + bar->setText(strprintf("%2.2f", 100 * progress) + "%"); + else + bar->setText(toString(value) + "/" + toString(max)); + + bar->setProgress(progress); + } +} + +void StatusWindow::updateXPBar(ProgressBar *bar, bool percent) +{ + updateProgressBar(bar, player_node->getExp(), player_node->getExpNeeded(), + percent); +} + +void StatusWindow::updateProgressBar(ProgressBar *bar, int id, bool percent) +{ + std::pair<int, int> exp = player_node->getExperience(id); + updateProgressBar(bar, exp.first, exp.second, percent); +} + +AttrDisplay::AttrDisplay(int id, const std::string &name): + mId(id), + mName(name) +{ + setSize(100, 32); + mLabel = new Label(name); + mValue = new Label("1"); + + mLabel->setAlignment(Graphics::CENTER); + mValue->setAlignment(Graphics::CENTER); + + mLayout = new LayoutHelper(this); +} + +std::string AttrDisplay::update() +{ + int base = player_node->getAttributeBase(mId); + int bonus = player_node->getAttributeEffective(mId) - base; + std::string value = toString(base); + if (bonus) + value += strprintf(" (%+d)", bonus); + mValue->setCaption(value); + + return mName; +} + +DerDisplay::DerDisplay(int id, const std::string &name): + AttrDisplay(id, name) +{ + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = mLayout->getPlacer(0, 0); + + place(0, 0, mLabel, 3); + place(3, 0, mValue, 2); + + update(); +} + +ChangeDisplay::ChangeDisplay(int id, const std::string &name): + AttrDisplay(id, name), mNeeded(1) +{ + mPoints = new Label("1"); + mDec = new Button(_("-"), "dec", this); + mInc = new Button(_("+"), "inc", this); + mDec->setWidth(mInc->getWidth()); + + // Do the layout + ContainerPlacer place = mLayout->getPlacer(0, 0); + + place(0, 0, mLabel, 3); + place(3, 0, mDec); + place(4, 0, mValue, 2); + place(6, 0, mInc); + place(7, 0, mPoints); + + update(); +} + +std::string ChangeDisplay::update() +{ + mPoints->setCaption(toString(mNeeded)); + + mDec->setEnabled(player_node->getCorrectionPoints()); + mInc->setEnabled(player_node->getCharacterPoints() >= mNeeded); + + return AttrDisplay::update(); +} + +void ChangeDisplay::setPointsNeeded(int needed) +{ + mNeeded = needed; + + update(); +} + +void ChangeDisplay::action(const gcn::ActionEvent &event) +{ + if (event.getSource() == mDec) + { + Net::getPlayerHandler()->decreaseAttribute(mId); + } + else if (event.getSource() == mInc) + { + Net::getPlayerHandler()->increaseAttribute(mId); + } } diff --git a/src/gui/statuswindow.h b/src/gui/statuswindow.h index 1e2a5097..f6d4f73e 100644 --- a/src/gui/statuswindow.h +++ b/src/gui/statuswindow.h @@ -28,75 +28,71 @@ #include <guichan/actionlistener.hpp> -class LocalPlayer; +#include <map> + +class AttrDisplay; class ProgressBar; +class ScrollArea; +class VertContainer; /** * The player status dialog. * * \ingroup Interface */ -class StatusWindow : public Window, public gcn::ActionListener +class StatusWindow : public Window { public: + enum { // Some update constants + HP = -1, + MP = -2, + EXP = -3, + MONEY = -4, + CHAR_POINTS = -5, + LEVEL = -6 + }; + /** * Constructor. */ - StatusWindow(LocalPlayer *player); + StatusWindow(); - /** - * Called when receiving actions from widget. - */ - void action(const gcn::ActionEvent &event); + std::string update(int id); - /** - * Draw this window - */ - void draw(gcn::Graphics *graphics); + void setPointsNeeded(int id, int needed); - /** - * Updates this dialog with values from PLAYER_INFO *char_info - */ - void update(); + void addAttribute(int id, const std::string &name, bool modifiable); 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 updateProgressBar(ProgressBar *bar, int value, int max, + bool percent); + void updateProgressBar(ProgressBar *bar, int id, + bool percent = true); private: - LocalPlayer *mPlayer; - /** * Status Part */ - gcn::Label *mLvlLabel, *mMoneyLabel, *mHpLabel, *mHpValueLabel; - ProgressBar *mHpBar; + gcn::Label *mLvlLabel, *mMoneyLabel; + gcn::Label *mHpLabel, *mMpLabel, *mXpLabel; + ProgressBar *mHpBar, *mMpBar, *mXpBar; - /** - * 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; +#ifdef EATHENA_SUPPORT + gcn::Label *mJobLvlLabel, *mJobLabel; + ProgressBar *mJobBar; +#endif - /** - * Stats buttons. - */ - gcn::Button *mStatsPlus[6]; - gcn::Button *mStatsMinus[6]; + VertContainer *mAttrCont; + ScrollArea *mAttrScroll; + VertContainer *mDAttrCont; + ScrollArea *mDAttrScroll; + + gcn::Label *mCharacterPointsLabel, *mCorrectionPointsLabel; + + typedef std::map<int, AttrDisplay*> Attrs; + Attrs mAttrs; }; extern StatusWindow *statusWindow; diff --git a/src/gui/storagewindow.cpp b/src/gui/storagewindow.cpp index 91224359..f0d00ee7 100644 --- a/src/gui/storagewindow.cpp +++ b/src/gui/storagewindow.cpp @@ -24,6 +24,7 @@ #include "gui/inventorywindow.h" #include "gui/itemamount.h" #include "gui/itemcontainer.h" +#include "gui/setup.h" #include "gui/viewport.h" #include "gui/widgets/button.h" @@ -58,6 +59,7 @@ StorageWindow::StorageWindow(int invSize): setWindowName("Storage"); setResizable(true); setCloseButton(true); + setupWindow->registerWindowForReset(this); // If you adjust these defaults, don't forget to adjust the trade window's. setDefaultSize(375, 300, ImageRect::CENTER); diff --git a/src/gui/trade.cpp b/src/gui/trade.cpp index 3abb985e..22eefc14 100644 --- a/src/gui/trade.cpp +++ b/src/gui/trade.cpp @@ -29,6 +29,7 @@ #include "gui/inventorywindow.h" #include "gui/itemamount.h" #include "gui/itemcontainer.h" +#include "gui/setup.h" #include "gui/widgets/button.h" #include "gui/widgets/chattab.h" @@ -65,6 +66,7 @@ TradeWindow::TradeWindow(): setDefaultSize(386, 180, ImageRect::CENTER); setMinWidth(386); setMinHeight(180); + setupWindow->registerWindowForReset(this); std::string longestName = getFont()->getWidth(_("OK")) > getFont()->getWidth(_("Trade")) ? @@ -92,7 +94,7 @@ TradeWindow::TradeWindow(): ScrollArea *partnerScroll = new ScrollArea(mPartnerItemContainer); partnerScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - mMoneyLabel = new Label(strprintf(_("You get %s."), "")); + mMoneyLabel = new Label(strprintf(_("You get %s"), "")); gcn::Label *mMoneyLabel2 = new Label(_("You give:")); mMoneyField = new TextField; @@ -128,7 +130,7 @@ TradeWindow::~TradeWindow() void TradeWindow::setMoney(int amount) { - mMoneyLabel->setCaption(strprintf(_("You get %s."), + mMoneyLabel->setCaption(strprintf(_("You get %s"), Units::formatCurrency(amount).c_str())); mMoneyLabel->adjustSize(); } @@ -255,7 +257,10 @@ void TradeWindow::action(const gcn::ActionEvent &event) return; if (!inventoryWindow->isVisible()) + { + inventoryWindow->setVisible(true); return; + } if (!item) return; diff --git a/src/gui/unregisterdialog.cpp b/src/gui/unregisterdialog.cpp index 048239c5..be54453d 100644 --- a/src/gui/unregisterdialog.cpp +++ b/src/gui/unregisterdialog.cpp @@ -42,7 +42,7 @@ #include <sstream> UnRegisterDialog::UnRegisterDialog(Window *parent, LoginData *loginData): - Window("Unregister", true, parent), + Window(_("Unregister"), true, parent), mWrongDataNoticeListener(new WrongDataNoticeListener), mLoginData(loginData) { @@ -102,24 +102,23 @@ UnRegisterDialog::action(const gcn::ActionEvent &event) logger->log("UnregisterDialog::unregistered, Username is %s", username.c_str()); - std::stringstream errorMsg; + std::stringstream errorMessage; 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."; + errorMessage << strprintf(_("The password needs to be at least %d " + "characters long."), LEN_MIN_PASSWORD); error = true; } - else if (password.length() > LEN_MAX_PASSWORD - 1 ) + else if (password.length() > LEN_MAX_PASSWORD - 1) { // Pass too long - errorMsg << "The password needs to be less than " - << LEN_MAX_PASSWORD - << " characters long."; + errorMessage << strprintf(_("The password needs to be less than " + "%d characters long."), + LEN_MAX_PASSWORD); error = true; } @@ -127,7 +126,7 @@ UnRegisterDialog::action(const gcn::ActionEvent &event) { mWrongDataNoticeListener->setTarget(this->mPasswordField); - OkDialog *dlg = new OkDialog("Error", errorMsg.str()); + OkDialog *dlg = new OkDialog(_("Error"), errorMessage.str()); dlg->addActionListener(mWrongDataNoticeListener); } else diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp index 21362630..bb2128b4 100644 --- a/src/gui/updatewindow.cpp +++ b/src/gui/updatewindow.cpp @@ -322,9 +322,8 @@ int UpdaterWindow::downloadThread(void *ptr) { case CURLE_COULDNT_CONNECT: default: - std::cerr << _("curl error ") << res << ": " - << uw->mCurlError << _(" host: ") << url.c_str() - << std::endl; + logger->log("curl error %d: %s host: %s", + res, uw->mCurlError, url.c_str()); break; } @@ -445,10 +444,13 @@ void UpdaterWindow::logic() } mThread = NULL; } + // TODO: Only send complete sentences to gettext mBrowserBox->addRow(""); mBrowserBox->addRow(_("##1 The update process is incomplete.")); + // TRANSLATORS: Continues "you try again later.". mBrowserBox->addRow(_("##1 It is strongly recommended that")); - mBrowserBox->addRow(_("##1 you try again later")); + // TRANSLATORS: Begins "It is strongly recommended that". + mBrowserBox->addRow(_("##1 you try again later.")); mBrowserBox->addRow(mCurlError); mScrollArea->setVerticalScrollAmount( mScrollArea->getVerticalMaxScroll()); diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp index 68b5fed3..9a631581 100644 --- a/src/gui/viewport.cpp +++ b/src/gui/viewport.cpp @@ -116,22 +116,12 @@ 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; - - int player_x = (player_node->mX - midTileX) * 32 + - player_node->getXOffset(); - int player_y = (player_node->mY - midTileY) * 32 + - player_node->getYOffset(); -#endif if (mScrollLaziness < 1) mScrollLaziness = 1; // Avoids division by zero diff --git a/src/gui/widgets/button.cpp b/src/gui/widgets/button.cpp index 71579bd4..2357b263 100644 --- a/src/gui/widgets/button.cpp +++ b/src/gui/widgets/button.cpp @@ -152,7 +152,10 @@ void Button::draw(gcn::Graphics *graphics) static_cast<Graphics*>(graphics)-> drawImageRect(0, 0, getWidth(), getHeight(), button[mode]); - graphics->setColor(guiPalette->getColor(Palette::TEXT)); + if (mode == BUTTON_DISABLED) + graphics->setColor(guiPalette->getColor(Palette::BUTTON_DISABLED)); + else + graphics->setColor(guiPalette->getColor(Palette::BUTTON)); int textX; int textY = getHeight() / 2 - getFont()->getHeight() / 2; diff --git a/src/gui/widgets/channeltab.cpp b/src/gui/widgets/channeltab.cpp index e3edbba0..8b055a22 100644 --- a/src/gui/widgets/channeltab.cpp +++ b/src/gui/widgets/channeltab.cpp @@ -72,23 +72,24 @@ bool ChannelTab::handleCommand(const std::string &type, { chatLog(_("Command: /quit")); chatLog(_("This command leaves the current channel.")); - chatLog(_("If you're the last person in the channel, it will be deleted.")); + chatLog(_("If you're the last person in the channel, " + "it will be deleted.")); } else if (args == "op") { chatLog(_("Command: /op <nick>")); chatLog(_("This command makes <nick> a channel operator.")); chatLog(_("If the <nick> has spaces in it, enclose it in " - "double quotes (\").")); + "double quotes (\").")); chatLog(_("Channel operators can kick and op other users " - "from the channel.")); + "from the channel.")); } else if (args == "kick") { chatLog(_("Command: /kick <nick>")); chatLog(_("This command makes <nick> leave the channel.")); chatLog(_("If the <nick> has spaces in it, enclose it in " - "double quotes (\").")); + "double quotes (\").")); } else return false; diff --git a/src/gui/widgets/chattab.cpp b/src/gui/widgets/chattab.cpp index d2fa33b8..e3ba4874 100644 --- a/src/gui/widgets/chattab.cpp +++ b/src/gui/widgets/chattab.cpp @@ -143,7 +143,7 @@ void ChatTab::chatLog(std::string line, int own, bool ignoreRecord) lineColor = "##2"; // Equiv. to BrowserBox::GREEN break; case ACT_WHISPER: - tmp.nick = strprintf(_("%s whispers: "), tmp.nick.c_str()); + tmp.nick = strprintf(_("%s whispers: %s"), tmp.nick.c_str(), ""); lineColor = "##W"; break; case ACT_IS: diff --git a/src/gui/widgets/checkbox.cpp b/src/gui/widgets/checkbox.cpp index 2e9a234b..dd57f674 100644 --- a/src/gui/widgets/checkbox.cpp +++ b/src/gui/widgets/checkbox.cpp @@ -35,9 +35,12 @@ Image *CheckBox::checkBoxNormal; Image *CheckBox::checkBoxChecked; Image *CheckBox::checkBoxDisabled; Image *CheckBox::checkBoxDisabledChecked; +Image *CheckBox::checkBoxNormalHi; +Image *CheckBox::checkBoxCheckedHi; CheckBox::CheckBox(const std::string &caption, bool selected): - gcn::CheckBox(caption, selected) + gcn::CheckBox(caption, selected), + mHasMouse(false) { if (instances == 0) { @@ -47,10 +50,14 @@ CheckBox::CheckBox(const std::string &caption, bool selected): checkBoxChecked = checkBox->getSubImage(9, 0, 9, 10); checkBoxDisabled = checkBox->getSubImage(18, 0, 9, 10); checkBoxDisabledChecked = checkBox->getSubImage(27, 0, 9, 10); + checkBoxNormalHi = checkBox->getSubImage(36, 0, 9, 10); + checkBoxCheckedHi = checkBox->getSubImage(45, 0, 9, 10); checkBoxNormal->setAlpha(mAlpha); checkBoxChecked->setAlpha(mAlpha); checkBoxDisabled->setAlpha(mAlpha); checkBoxDisabledChecked->setAlpha(mAlpha); + checkBoxNormalHi->setAlpha(mAlpha); + checkBoxCheckedHi->setAlpha(mAlpha); checkBox->decRef(); } @@ -67,6 +74,8 @@ CheckBox::~CheckBox() delete checkBoxChecked; delete checkBoxDisabled; delete checkBoxDisabledChecked; + delete checkBoxNormalHi; + delete checkBoxCheckedHi; } } @@ -86,17 +95,22 @@ void CheckBox::drawBox(gcn::Graphics* graphics) { Image *box; - if (isSelected()) - { - if (isEnabled()) - box = checkBoxChecked; + if (isEnabled()) + if (isSelected()) + if (mHasMouse) + box = checkBoxCheckedHi; + else + box = checkBoxChecked; else - box = checkBoxDisabledChecked; - } - else if (isEnabled()) - box = checkBoxNormal; + if (mHasMouse) + box = checkBoxNormalHi; + else + box = checkBoxNormal; else - box = checkBoxDisabled; + if (isSelected()) + box = checkBoxDisabledChecked; + else + box = checkBoxDisabled; if (config.getValue("guialpha", 0.8) != mAlpha) { @@ -105,7 +119,19 @@ void CheckBox::drawBox(gcn::Graphics* graphics) checkBoxChecked->setAlpha(mAlpha); checkBoxDisabled->setAlpha(mAlpha); checkBoxDisabledChecked->setAlpha(mAlpha); + checkBoxNormal->setAlpha(mAlpha); + checkBoxCheckedHi->setAlpha(mAlpha); } static_cast<Graphics*>(graphics)->drawImage(box, 2, 2); } + +void CheckBox::mouseEntered(gcn::MouseEvent& event) +{ + mHasMouse = true; +} + +void CheckBox::mouseExited(gcn::MouseEvent& event) +{ + mHasMouse = false; +} diff --git a/src/gui/widgets/checkbox.h b/src/gui/widgets/checkbox.h index 303782b0..7a7c8674 100644 --- a/src/gui/widgets/checkbox.h +++ b/src/gui/widgets/checkbox.h @@ -24,6 +24,7 @@ #include <guichan/widgets/checkbox.hpp> + class Image; /** @@ -54,13 +55,26 @@ class CheckBox : public gcn::CheckBox */ void drawBox(gcn::Graphics* graphics); + /** + * Called when the mouse enteres the widget area. + */ + void mouseEntered(gcn::MouseEvent& event); + + /** + * Called when the mouse leaves the widget area. + */ + void mouseExited(gcn::MouseEvent& event); + private: static int instances; static float mAlpha; + bool mHasMouse; static Image *checkBoxNormal; static Image *checkBoxChecked; static Image *checkBoxDisabled; static Image *checkBoxDisabledChecked; + static Image *checkBoxNormalHi; + static Image *checkBoxCheckedHi; }; #endif diff --git a/src/gui/widgets/desktop.cpp b/src/gui/widgets/desktop.cpp index a4164bcc..13ac866a 100644 --- a/src/gui/widgets/desktop.cpp +++ b/src/gui/widgets/desktop.cpp @@ -39,8 +39,9 @@ Desktop::Desktop() Wallpaper::loadWallpapers(); - gcn::Label *versionLabel = new Label(FULL_VERSION); - add(versionLabel, 25, 2); + mVersionLabel = new Label(FULL_VERSION); + mVersionLabel->setBackgroundColor(gcn::Color(255, 255, 255, 128)); + add(mVersionLabel, 25, 2); } Desktop::~Desktop() @@ -74,11 +75,20 @@ void Desktop::draw(gcn::Graphics *graphics) if (mWallpaper) { - g->drawImage(mWallpaper, + if (!mWallpaper->isAnOpenGLOne()) + g->drawImage(mWallpaper, (getWidth() - mWallpaper->getWidth()) / 2, (getHeight() - mWallpaper->getHeight()) / 2); + else + g->drawRescaledImage(mWallpaper, 0, 0, 0, 0, + mWallpaper->getWidth(), mWallpaper->getHeight(), + getWidth(), getHeight(), false); } + // Draw a thin border under the application version... + g->setColor(gcn::Color(255, 255, 255, 128)); + g->fillRectangle(gcn::Rectangle(mVersionLabel->getDimension())); + Container::draw(graphics); } @@ -87,13 +97,27 @@ void Desktop::setBestFittingWallpaper() const std::string wallpaperName = Wallpaper::getWallpaper(getWidth(), getHeight()); - Image *temp = ResourceManager::getInstance()->getImage(wallpaperName); + Image *nWallPaper = ResourceManager::getInstance()->getImage(wallpaperName); - if (temp) + if (nWallPaper) { if (mWallpaper) mWallpaper->decRef(); - mWallpaper = temp; + + if (!nWallPaper->isAnOpenGLOne() && (nWallPaper->getWidth() != getWidth() + || nWallPaper->getHeight() != getHeight())) + { + // We rescale to obtain a fullscreen wallpaper... + Image *newRsclWlPpr = nWallPaper->SDLgetScaledImage(getWidth(), getHeight()); + std::string idPath = nWallPaper->getIdPath(); + + // We replace the resource in the resource manager + nWallPaper->decRef(); + ResourceManager::getInstance()->addResource(idPath, newRsclWlPpr); + mWallpaper = newRsclWlPpr; + } + else + mWallpaper = nWallPaper; } else { diff --git a/src/gui/widgets/desktop.h b/src/gui/widgets/desktop.h index ad04ee96..da623bbd 100644 --- a/src/gui/widgets/desktop.h +++ b/src/gui/widgets/desktop.h @@ -24,6 +24,8 @@ #include "gui/widgets/container.h" +#include "guichanfwd.h" + #include <guichan/widgetlistener.hpp> class Image; @@ -60,6 +62,7 @@ class Desktop : public Container, gcn::WidgetListener void setBestFittingWallpaper(); Image *mWallpaper; + gcn::Label *mVersionLabel; }; #endif // DESKTOP_H diff --git a/src/gui/widgets/progressbar.cpp b/src/gui/widgets/progressbar.cpp index 134d071f..7cc020ef 100644 --- a/src/gui/widgets/progressbar.cpp +++ b/src/gui/widgets/progressbar.cpp @@ -43,14 +43,17 @@ ProgressBar::ProgressBar(float progress, int width, int height, const gcn::Color &color): gcn::Widget(), - mProgress(0.0f), - mProgressToGo(0.0f), mSmoothProgress(true), mColor(color), mColorToGo(color), mSmoothColorChange(true) { - setProgress(progress); + // The progress value is directly set at load time: + if (progress > 1.0f || progress < 0.0f) + progress = 1.0f; + + mProgress = mProgressToGo = progress; + setSize(width, height); if (mInstances == 0) diff --git a/src/gui/widgets/radiobutton.cpp b/src/gui/widgets/radiobutton.cpp index 6f0ccdbd..9cf49672 100644 --- a/src/gui/widgets/radiobutton.cpp +++ b/src/gui/widgets/radiobutton.cpp @@ -33,10 +33,13 @@ Image *RadioButton::radioNormal; Image *RadioButton::radioChecked; Image *RadioButton::radioDisabled; Image *RadioButton::radioDisabledChecked; +Image *RadioButton::radioNormalHi; +Image *RadioButton::radioCheckedHi; RadioButton::RadioButton(const std::string &caption, const std::string &group, bool marked): - gcn::RadioButton(caption, group, marked) + gcn::RadioButton(caption, group, marked), + mHasMouse(false) { if (instances == 0) { @@ -45,10 +48,14 @@ RadioButton::RadioButton(const std::string &caption, const std::string &group, radioChecked = resman->getImage("graphics/gui/radioin.png"); radioDisabled = resman->getImage("graphics/gui/radioout.png"); radioDisabledChecked = resman->getImage("graphics/gui/radioin.png"); + radioNormalHi = resman->getImage("graphics/gui/radioout_highlight.png"); + radioCheckedHi = resman->getImage("graphics/gui/radioin_highlight.png"); radioNormal->setAlpha(mAlpha); radioChecked->setAlpha(mAlpha); radioDisabled->setAlpha(mAlpha); radioDisabledChecked->setAlpha(mAlpha); + radioNormalHi->setAlpha(mAlpha); + radioCheckedHi->setAlpha(mAlpha); } instances++; @@ -64,6 +71,8 @@ RadioButton::~RadioButton() radioChecked->decRef(); radioDisabled->decRef(); radioDisabledChecked->decRef(); + radioNormalHi->decRef(); + radioCheckedHi->decRef(); } } @@ -76,21 +85,28 @@ void RadioButton::drawBox(gcn::Graphics* graphics) radioChecked->setAlpha(mAlpha); radioDisabled->setAlpha(mAlpha); radioDisabledChecked->setAlpha(mAlpha); + radioNormalHi->setAlpha(mAlpha); + radioCheckedHi->setAlpha(mAlpha); } Image *box = NULL; - if (isSelected()) - { - if (isEnabled()) - box = radioChecked; + if (isEnabled()) + if (isSelected()) + if (mHasMouse) + box = radioCheckedHi; + else + box = radioChecked; else - box = radioDisabledChecked; - } - else if (isEnabled()) - box = radioNormal; + if (mHasMouse) + box = radioNormalHi; + else + box = radioNormal; else - box = radioDisabled; + if (isSelected()) + box = radioDisabledChecked; + else + box = radioDisabled; if (box) static_cast<Graphics*>(graphics)->drawImage(box, 2, 2); @@ -111,3 +127,14 @@ void RadioButton::draw(gcn::Graphics* graphics) int h = getHeight() + getHeight() / 2; graphics->drawText(getCaption(), h - 2, 0); } + +void RadioButton::mouseEntered(gcn::MouseEvent& event) +{ + mHasMouse = true; +} + +void RadioButton::mouseExited(gcn::MouseEvent& event) +{ + mHasMouse = false; +} + diff --git a/src/gui/widgets/radiobutton.h b/src/gui/widgets/radiobutton.h index 9aec3add..57eb3623 100644 --- a/src/gui/widgets/radiobutton.h +++ b/src/gui/widgets/radiobutton.h @@ -26,13 +26,13 @@ class Image; -/* +/** * Guichan based RadioButton with custom look */ class RadioButton : public gcn::RadioButton { public: - /* + /** * Constructor. */ RadioButton(const std::string &caption,const std::string &group, @@ -54,13 +54,26 @@ class RadioButton : public gcn::RadioButton */ void draw(gcn::Graphics* graphics); + /** + * Called when the mouse enteres the widget area. + */ + void mouseEntered(gcn::MouseEvent& event); + + /** + * Called when the mouse leaves the widget area. + */ + void mouseExited(gcn::MouseEvent& event); + private: static int instances; static float mAlpha; + bool mHasMouse; static Image *radioNormal; static Image *radioChecked; static Image *radioDisabled; static Image *radioDisabledChecked; + static Image *radioNormalHi; + static Image *radioCheckedHi; }; #endif /* RADIOBUTTON_H */ diff --git a/src/gui/widgets/scrollarea.cpp b/src/gui/widgets/scrollarea.cpp index ff3a23d1..52322b05 100644 --- a/src/gui/widgets/scrollarea.cpp +++ b/src/gui/widgets/scrollarea.cpp @@ -33,10 +33,13 @@ int ScrollArea::instances = 0; float ScrollArea::mAlpha = 1.0; ImageRect ScrollArea::background; ImageRect ScrollArea::vMarker; +ImageRect ScrollArea::vMarkerHi; Image *ScrollArea::buttons[4][2]; ScrollArea::ScrollArea(): gcn::ScrollArea(), + mX(0), + mY(0), mOpaque(true) { init(); @@ -44,6 +47,7 @@ ScrollArea::ScrollArea(): ScrollArea::ScrollArea(gcn::Widget *widget): gcn::ScrollArea(widget), + mHasMouse(false), mOpaque(true) { init(); @@ -60,6 +64,7 @@ ScrollArea::~ScrollArea() { for_each(background.grid, background.grid + 9, dtor<Image*>()); for_each(vMarker.grid, vMarker.grid + 9, dtor<Image*>()); + for_each(vMarkerHi.grid, vMarkerHi.grid + 9, dtor<Image*>()); buttons[UP][0]->decRef(); buttons[UP][1]->decRef(); @@ -103,6 +108,8 @@ void ScrollArea::init() // Load vertical scrollbar skin Image *vscroll = resman->getImage("graphics/gui/vscroll_grey.png"); + Image *vscrollHi = resman->getImage("graphics/gui/vscroll_highlight.png"); + int vsgridx[4] = {0, 4, 7, 11}; int vsgridy[4] = {0, 4, 15, 19}; a = 0; @@ -115,12 +122,18 @@ void ScrollArea::init() vsgridx[x], vsgridy[y], vsgridx[x + 1] - vsgridx[x], vsgridy[y + 1] - vsgridy[y]); + vMarkerHi.grid[a] = vscrollHi->getSubImage( + vsgridx[x], vsgridy[y], + vsgridx[x + 1] - vsgridx[x], + vsgridy[y + 1] - vsgridy[y]); vMarker.grid[a]->setAlpha(config.getValue("guialpha", 0.8)); + vMarkerHi.grid[a]->setAlpha(config.getValue("guialpha", 0.8)); a++; } } vscroll->decRef(); + vscrollHi->decRef(); buttons[UP][0] = resman->getImage("graphics/gui/vscroll_up_default.png"); @@ -202,6 +215,7 @@ void ScrollArea::draw(gcn::Graphics *graphics) { background.grid[a]->setAlpha(mAlpha); vMarker.grid[a]->setAlpha(mAlpha); + vMarkerHi.grid[a]->setAlpha(mAlpha); } } @@ -296,14 +310,39 @@ void ScrollArea::drawVMarker(gcn::Graphics *graphics) { gcn::Rectangle dim = getVerticalMarkerDimension(); - static_cast<Graphics*>(graphics)-> - drawImageRect(dim.x, dim.y, dim.width, dim.height, vMarker); + if ((mHasMouse) && (mX > (getWidth() - getScrollbarWidth()))) + static_cast<Graphics*>(graphics)-> + drawImageRect(dim.x, dim.y, dim.width, dim.height, vMarkerHi); + else + static_cast<Graphics*>(graphics)-> + drawImageRect(dim.x, dim.y, dim.width, dim.height,vMarker); } void ScrollArea::drawHMarker(gcn::Graphics *graphics) { gcn::Rectangle dim = getHorizontalMarkerDimension(); - static_cast<Graphics*>(graphics)-> - drawImageRect(dim.x, dim.y, dim.width, dim.height, vMarker); + if ((mHasMouse) && (mY > (getHeight() - getScrollbarWidth()))) + static_cast<Graphics*>(graphics)-> + drawImageRect(dim.x, dim.y, dim.width, dim.height, vMarkerHi); + else + static_cast<Graphics*>(graphics)-> + drawImageRect(dim.x, dim.y, dim.width, dim.height, vMarker); } + +void ScrollArea::mouseMoved(gcn::MouseEvent& event) +{ +mX = event.getX(); +mY = event.getY(); +} + +void ScrollArea::mouseEntered(gcn::MouseEvent& event) +{ + mHasMouse = true; +} + +void ScrollArea::mouseExited(gcn::MouseEvent& event) +{ + mHasMouse = false; +} + diff --git a/src/gui/widgets/scrollarea.h b/src/gui/widgets/scrollarea.h index 700de32b..8fd92b5f 100644 --- a/src/gui/widgets/scrollarea.h +++ b/src/gui/widgets/scrollarea.h @@ -83,6 +83,21 @@ class ScrollArea : public gcn::ScrollArea */ bool isOpaque() const { return mOpaque; } + /** + * Called when the mouse moves in the widget area. + */ + void mouseMoved(gcn::MouseEvent& event); + + /** + * Called when the mouse enteres the widget area. + */ + void mouseEntered(gcn::MouseEvent& event); + + /** + * Called when the mouse leaves the widget area. + */ + void mouseExited(gcn::MouseEvent& event); + protected: enum BUTTON_DIR { UP, @@ -110,8 +125,11 @@ class ScrollArea : public gcn::ScrollArea static float mAlpha; static ImageRect background; static ImageRect vMarker; + static ImageRect vMarkerHi; static Image *buttons[4][2]; + int mX,mY; + bool mHasMouse; bool mOpaque; }; diff --git a/src/gui/widgets/slider.cpp b/src/gui/widgets/slider.cpp index 7cd0e54a..6ce5f849 100644 --- a/src/gui/widgets/slider.cpp +++ b/src/gui/widgets/slider.cpp @@ -29,17 +29,21 @@ Image *Slider::hStart, *Slider::hMid, *Slider::hEnd, *Slider::hGrip; Image *Slider::vStart, *Slider::vMid, *Slider::vEnd, *Slider::vGrip; +Image *Slider::hStartHi, *Slider::hMidHi, *Slider::hEndHi, *Slider::hGripHi; +Image *Slider::vStartHi, *Slider::vMidHi, *Slider::vEndHi, *Slider::vGripHi; float Slider::mAlpha = 1.0; int Slider::mInstances = 0; Slider::Slider(double scaleEnd): - gcn::Slider(scaleEnd) + gcn::Slider(scaleEnd), + mHasMouse(false) { init(); } Slider::Slider(double scaleStart, double scaleEnd): - gcn::Slider(scaleStart, scaleEnd) + gcn::Slider(scaleStart, scaleEnd), + mHasMouse(false) { init(); } @@ -58,6 +62,14 @@ Slider::~Slider() delete vMid; delete vEnd; delete vGrip; + delete hStartHi; + delete hMidHi; + delete hEndHi; + delete hGripHi; + delete vStartHi; + delete vMidHi; + delete vEndHi; + delete vGripHi; } } @@ -71,6 +83,7 @@ void Slider::init() { ResourceManager *resman = ResourceManager::getInstance(); Image *slider = resman->getImage("graphics/gui/slider.png"); + Image *sliderHi = resman->getImage("graphics/gui/slider_hilight.png"); x = 0; y = 0; w = 15; h = 6; @@ -78,10 +91,14 @@ void Slider::init() hStart = slider->getSubImage(x, y, o1 - x, h); hMid = slider->getSubImage(o1, y, o2 - o1, h); hEnd = slider->getSubImage(o2, y, w - o2 + x, h); + hStartHi = sliderHi->getSubImage(x, y, o1 - x, h); + hMidHi = sliderHi->getSubImage(o1, y, o2 - o1, h); + hEndHi = sliderHi->getSubImage(o2, y, w - o2 + x, h); x = 6; y = 8; w = 9; h = 10; hGrip = slider->getSubImage(x, y, w, h); + hGripHi = sliderHi->getSubImage(x, y, w, h); x = 0; y = 6; w = 6; h = 21; @@ -89,22 +106,35 @@ void Slider::init() vStart = slider->getSubImage(x, y, w, o1 - y); vMid = slider->getSubImage(x, o1, w, o2 - o1); vEnd = slider->getSubImage(x, o2, w, h - o2 + y); + vStartHi = sliderHi->getSubImage(x, y, w, o1 - y); + vMidHi = sliderHi->getSubImage(x, o1, w, o2 - o1); + vEndHi = sliderHi->getSubImage(x, o2, w, h - o2 + y); x = 6; y = 8; w = 9; h = 10; vGrip = slider->getSubImage(x, y, w, h); + vGripHi = sliderHi->getSubImage(x, y, w, h); slider->decRef(); + sliderHi->decRef(); hStart->setAlpha(mAlpha); hMid->setAlpha(mAlpha); hEnd->setAlpha(mAlpha); hGrip->setAlpha(mAlpha); + hStartHi->setAlpha(mAlpha); + hMidHi->setAlpha(mAlpha); + hEndHi->setAlpha(mAlpha); + hGripHi->setAlpha(mAlpha); vStart->setAlpha(mAlpha); vMid->setAlpha(mAlpha); vEnd->setAlpha(mAlpha); vGrip->setAlpha(mAlpha); + vStartHi->setAlpha(mAlpha); + vMidHi->setAlpha(mAlpha); + vEndHi->setAlpha(mAlpha); + vGripHi->setAlpha(mAlpha); } mInstances++; @@ -117,7 +147,7 @@ void Slider::draw(gcn::Graphics *graphics) int w = getWidth(); int h = getHeight(); int x = 0; - int y = (h - hStart->getHeight()) / 2; + int y = mHasMouse?(h - hStartHi->getHeight()) / 2:(h - hStart->getHeight()) / 2; if (config.getValue("guialpha", 0.8) != mAlpha) { @@ -126,23 +156,45 @@ void Slider::draw(gcn::Graphics *graphics) hMid->setAlpha(mAlpha); hEnd->setAlpha(mAlpha); hGrip->setAlpha(mAlpha); + hStartHi->setAlpha(mAlpha); + hMidHi->setAlpha(mAlpha); + hEndHi->setAlpha(mAlpha); + hGripHi->setAlpha(mAlpha); vStart->setAlpha(mAlpha); vMid->setAlpha(mAlpha); vEnd->setAlpha(mAlpha); vGrip->setAlpha(mAlpha); + vStartHi->setAlpha(mAlpha); + vMidHi->setAlpha(mAlpha); + vEndHi->setAlpha(mAlpha); + vGripHi->setAlpha(mAlpha); } + if (!mHasMouse) + { + static_cast<Graphics*>(graphics)->drawImage(hStart, x, y); - static_cast<Graphics*>(graphics)->drawImage(hStart, x, y); + w -= hStart->getWidth() + hEnd->getWidth(); + x += hStart->getWidth(); - w -= hStart->getWidth() + hEnd->getWidth(); - x += hStart->getWidth(); + static_cast<Graphics*>(graphics)-> + drawImagePattern(hMid, x, y, w, hMid->getHeight()); - static_cast<Graphics*>(graphics)-> - drawImagePattern(hMid, x, y, w, hMid->getHeight()); + x += w; + static_cast<Graphics*>(graphics)->drawImage(hEnd, x, y); + } else + { + static_cast<Graphics*>(graphics)->drawImage(hStartHi, x, y); - x += w; - static_cast<Graphics*>(graphics)->drawImage(hEnd, x, y); + w -= hStartHi->getWidth() + hEndHi->getWidth(); + x += hStartHi->getWidth(); + + static_cast<Graphics*>(graphics)-> + drawImagePattern(hMidHi, x, y, w, hMidHi->getHeight()); + + x += w; + static_cast<Graphics*>(graphics)->drawImage(hEndHi, x, y); + } drawMarker(graphics); } @@ -150,5 +202,16 @@ void Slider::draw(gcn::Graphics *graphics) void Slider::drawMarker(gcn::Graphics *graphics) { static_cast<Graphics*>(graphics)-> - drawImage(hGrip, getMarkerPosition(), (getHeight() - hGrip->getHeight()) / 2); + drawImage(mHasMouse?hGripHi:hGrip, getMarkerPosition(), + (getHeight() - (mHasMouse?hGripHi:hGrip)->getHeight()) / 2); } + +void Slider::mouseEntered(gcn::MouseEvent& event) +{ + mHasMouse = true; +} + +void Slider::mouseExited(gcn::MouseEvent& event) +{ + mHasMouse = false; +}
\ No newline at end of file diff --git a/src/gui/widgets/slider.h b/src/gui/widgets/slider.h index 56ea334a..85fb2633 100644 --- a/src/gui/widgets/slider.h +++ b/src/gui/widgets/slider.h @@ -58,6 +58,16 @@ class Slider : public gcn::Slider { */ void drawMarker(gcn::Graphics *graphics); + /** + * Called when the mouse enteres the widget area. + */ + void mouseEntered(gcn::MouseEvent& event); + + /** + * Called when the mouse leaves the widget area. + */ + void mouseExited(gcn::MouseEvent& event); + private: /** * Used to initialize instances. @@ -66,6 +76,9 @@ class Slider : public gcn::Slider { static Image *hStart, *hMid, *hEnd, *hGrip; static Image *vStart, *vMid, *vEnd, *vGrip; + static Image *hStartHi, *hMidHi, *hEndHi, *hGripHi; + static Image *vStartHi, *vMidHi, *vEndHi, *vGripHi; + bool mHasMouse; static float mAlpha; static int mInstances; }; diff --git a/src/gui/widgets/tab.cpp b/src/gui/widgets/tab.cpp index f2231fca..3e49263e 100644 --- a/src/gui/widgets/tab.cpp +++ b/src/gui/widgets/tab.cpp @@ -55,7 +55,7 @@ struct TabData static TabData const data[TAB_COUNT] = { { "graphics/gui/tab.png", 0, 0 }, - { "graphics/gui/tab.png", 9, 4 }, + { "graphics/gui/tab_hilight.png", 9, 4 }, { "graphics/gui/tabselected.png", 16, 19 }, { "graphics/gui/tab.png", 25, 23 } }; @@ -63,7 +63,7 @@ static TabData const data[TAB_COUNT] = { ImageRect Tab::tabImg[TAB_COUNT]; Tab::Tab() : gcn::Tab(), - mTabColor(&guiPalette->getColor(Palette::TEXT)) + mTabColor(&guiPalette->getColor(Palette::TAB)) { init(); } @@ -123,21 +123,19 @@ void Tab::draw(gcn::Graphics *graphics) // check which type of tab to draw if (mTabbedArea) { + mLabel->setForegroundColor(*mTabColor); if (mTabbedArea->isTabSelected(this)) { mode = TAB_SELECTED; // if tab is selected, it doesnt need to highlight activity - mLabel->setForegroundColor(*mTabColor); mHighlighted = false; - } - else if (mHighlighted) + } else if (mHasMouse) { mode = TAB_HIGHLIGHTED; - mLabel->setForegroundColor(guiPalette->getColor(Palette::TAB_HIGHLIGHT)); } - else + if (mHighlighted) { - mLabel->setForegroundColor(*mTabColor); + mLabel->setForegroundColor(guiPalette->getColor(Palette::TAB_HIGHLIGHT)); } } diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp index 07f46a94..bb5ae9a4 100644 --- a/src/gui/widgets/tabbedarea.cpp +++ b/src/gui/widgets/tabbedarea.cpp @@ -69,6 +69,16 @@ gcn::Widget *TabbedArea::getWidget(const std::string &name) const return NULL; } +gcn::Widget *TabbedArea::getCurrentWidget() +{ + gcn::Tab *tab = getSelectedTab(); + + if (tab) + return getWidget(tab->getCaption()); + else + return NULL; +} + void TabbedArea::addTab(const std::string &caption, gcn::Widget *widget) { Tab *tab = new Tab; diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h index 6aaafe16..29ba2f76 100644 --- a/src/gui/widgets/tabbedarea.h +++ b/src/gui/widgets/tabbedarea.h @@ -63,6 +63,11 @@ class TabbedArea : public gcn::TabbedArea */ gcn::Widget *getWidget(const std::string &name) const; + /** + * Returns the widget for the current tab + */ + gcn::Widget *getCurrentWidget(); + using gcn::TabbedArea::addTab; /** diff --git a/src/gui/widgets/vertcontainer.cpp b/src/gui/widgets/vertcontainer.cpp new file mode 100644 index 00000000..9dd02cdc --- /dev/null +++ b/src/gui/widgets/vertcontainer.cpp @@ -0,0 +1,53 @@ +/* + * 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 + */ + +#include "gui/widgets/vertcontainer.h" + +VertContainer::VertContainer(int spacing): + mSpacing(spacing), + mCount(0) +{ + addWidgetListener(this); +} + +void VertContainer::add(gcn::Widget *widget) +{ + Container::add(widget); + widget->setPosition(0, mCount * mSpacing); + widget->setSize(getWidth(), mSpacing); + mCount++; + setHeight(mCount * mSpacing); +} + +void VertContainer::clear() +{ + Container::clear(); + + mCount = 0; +} + +void VertContainer::widgetResized(const gcn::Event &event) +{ + for (WidgetListIterator it = mWidgets.begin(); it != mWidgets.end(); it++) + { + (*it)->setWidth(getWidth()); + } +} diff --git a/src/gui/widgets/vertcontainer.h b/src/gui/widgets/vertcontainer.h new file mode 100644 index 00000000..9e15e66a --- /dev/null +++ b/src/gui/widgets/vertcontainer.h @@ -0,0 +1,47 @@ +/* + * 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 GUI_VERTCONTAINER_H +#define GUI_VERTCONTAINER_H + +#include "gui/widgets/container.h" + +#include <guichan/widgetlistener.hpp> + +/** + * A widget container. + * + * This container places it's contents veritcally. + */ +class VertContainer : public Container, public gcn::WidgetListener +{ + public: + VertContainer(int spacing); + virtual void add(gcn::Widget *widget); + virtual void clear(); + void widgetResized(const gcn::Event &event); + + private: + int mSpacing; + int mCount; +}; + +#endif diff --git a/src/gui/widgets/whispertab.cpp b/src/gui/widgets/whispertab.cpp index 43c63cc0..5509a589 100644 --- a/src/gui/widgets/whispertab.cpp +++ b/src/gui/widgets/whispertab.cpp @@ -84,14 +84,14 @@ bool WhisperTab::handleCommand(const std::string &type, else if (args == "ignore") { chatLog(_("Command: /ignore")); - chatLog(_("This command ignores the other player reguardless of " + chatLog(_("This command ignores the other player regardless of " "current relations.")); } else if (args == "unignore") { chatLog(_("Command: /unignore <player>")); chatLog(_("This command stops ignoring the other player if they " - "are being ignored")); + "are being ignored.")); } else return false; diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp index 19d80671..1ee84a6f 100644 --- a/src/gui/widgets/window.cpp +++ b/src/gui/widgets/window.cpp @@ -306,6 +306,10 @@ void Window::setVisible(bool visible) void Window::setVisible(bool visible, bool forceSticky) { + // Check if the window is off screen... + if (visible) + checkIfIsOffScreen(); + gcn::Window::setVisible((!forceSticky && isSticky()) || visible); } @@ -526,6 +530,9 @@ void Window::loadWindowState() { setSize(mDefaultWidth, mDefaultHeight); } + + // Check if the window is off screen... + checkIfIsOffScreen(); } void Window::saveWindowState() @@ -739,3 +746,63 @@ void Window::center() { setLocationRelativeTo(getParent()); } + +void Window::checkIfIsOffScreen(bool partially, bool entirely) +{ + // Move the window onto screen if it has become off screen + // For instance, because of resolution change... + + // First of all, don't deal when a window hasn't got + // any size initialized yet... + if (getWidth() == 0 && getHeight() == 0) + return; + + // Made partially the default behaviour + if (!partially && !entirely) + partially = true; + + // Keep guichan window inside screen (supports resizing any side) + + gcn::Rectangle winDimension = getDimension(); + + if (winDimension.x < 0) + { + winDimension.width += winDimension.x; + winDimension.x = 0; + } + if (winDimension.y < 0) + { + winDimension.height += winDimension.y; + winDimension.y = 0; + } + + // Look if the window is partially off-screen limits... + if (partially) + { + if (winDimension.x + winDimension.width > graphics->getWidth()) + { + winDimension.x = graphics->getWidth() - winDimension.width; + } + + if (winDimension.y + winDimension.height > graphics->getHeight()) + { + winDimension.y = graphics->getHeight() - winDimension.height; + } + setDimension(winDimension); + return; + } + + if (entirely) + { + if (winDimension.x > graphics->getWidth()) + { + winDimension.x = graphics->getWidth() - winDimension.width; + } + + if (winDimension.y > graphics->getHeight()) + { + winDimension.y = graphics->getHeight() - winDimension.height; + } + } + setDimension(winDimension); +} diff --git a/src/gui/widgets/window.h b/src/gui/widgets/window.h index 153602ba..b3ef3fdc 100644 --- a/src/gui/widgets/window.h +++ b/src/gui/widgets/window.h @@ -269,7 +269,7 @@ class Window : public gcn::Window, gcn::WidgetListener int defaultWidth, int defaultHeight); /** - * Set the default win pos and size tot he current ones. + * Set the default win pos and size to the current ones. */ void setDefaultSize(); @@ -347,6 +347,13 @@ class Window : public gcn::Window, gcn::WidgetListener }; /** + * Check if the window is off-screen and then move it to be visible + * again. This is internally used by loadWindowState + * and setVisible(true) members. + */ + void checkIfIsOffScreen(bool partially = true, bool entirely = true); + + /** * Determines if the mouse is in a resize area and returns appropriate * resize handles. Also initializes drag offset in case the resize * grip is used. diff --git a/src/gui/windowmenu.cpp b/src/gui/windowmenu.cpp index 8964f072..96776617 100644 --- a/src/gui/windowmenu.cpp +++ b/src/gui/windowmenu.cpp @@ -62,7 +62,7 @@ WindowMenu::WindowMenu(): #ifdef TMWSERV_SUPPORT N_("Magic"), N_("Guilds"), - N_("Buddys"), + N_("Buddies"), #endif N_("Shortcut"), N_("Setup"), @@ -138,7 +138,7 @@ void WindowMenu::action(const gcn::ActionEvent &event) { window = guildWindow; } - else if (event.getId() == "Buddys") + else if (event.getId() == "Buddies") { window = buddyWindow; } diff --git a/src/inventory.cpp b/src/inventory.cpp index 532d9ab6..202c3e52 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -29,11 +29,7 @@ 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 + return item && item->getId() >= 0 && item->getQuantity() > 0; } }; @@ -54,11 +50,7 @@ Inventory::~Inventory() 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]; @@ -91,6 +83,7 @@ void Inventory::setItem(int index, int id, int quantity, bool equipment) Item *item = new Item(id, quantity, equipment); item->setInvIndex(index); mItems[index] = item; + mItems[index]->setEquipment(equipment); } else if (id > 0) { diff --git a/src/item.cpp b/src/item.cpp index 2fadc035..312a7f63 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -43,10 +43,8 @@ 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) diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 241cfe99..1cc0ae34 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -40,25 +40,25 @@ #include "gui/gui.h" #include "gui/ministatus.h" #include "gui/palette.h" -#ifdef EATHENA_SUPPORT +#include "gui/skilldialog.h" +#include "gui/statuswindow.h" #include "gui/storagewindow.h" -#endif + +#include "gui/widgets/chattab.h" #include "net/inventoryhandler.h" #include "net/net.h" #include "net/partyhandler.h" #include "net/playerhandler.h" +#include "net/specialhandler.h" #include "net/tradehandler.h" -#ifdef TMWSERV_SUPPORT #include "effectmanager.h" +#ifdef TMWSERV_SUPPORT #include "guild.h" -#include "net/tmwserv/gameserver/player.h" +//#include "net/tmwserv/gameserver/player.h" #include "net/tmwserv/chatserver/guild.h" -#else -#include "net/ea/partyhandler.h" -#include "net/ea/skillhandler.h" #endif #include "resources/animation.h" @@ -80,44 +80,26 @@ const short walkingKeyboardDelay = 40; LocalPlayer *player_node = NULL; -#ifdef TMWSERV_SUPPORT -LocalPlayer::LocalPlayer(): - Player(65535, 0, NULL), - mEquipment(new Equipment), -#else LocalPlayer::LocalPlayer(int id, int job, Map *map): Player(id, job, map), - mCharId(0), - mJobXp(0), - mJobLevel(0), - mXpForNextLevel(0), mJobXpForNextLevel(0), - mMp(0), mMaxMp(0), +#ifdef EATHENA_SUPPORT mAttackRange(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), #endif + mEquipment(new Equipment), mInStorage(false), #ifdef EATHENA_SUPPORT - mXp(0), mTargetTime(-1), #endif mLastTarget(-1), -#ifdef TMWSERV_SUPPORT - 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), -#endif + mCharacterPoints(0), + mCorrectionPoints(0), mLevel(1), + mExp(0), mExpNeeded(0), + mMp(0), mMaxMp(0), mMoney(0), mTotalWeight(1), mMaxWeight(1), mHp(1), mMaxHp(1), + mSkillPoints(0), mTarget(NULL), mPickUpTarget(NULL), mTrading(false), mGoingToTarget(false), mKeepAttacking(false), mLastAction(-1), @@ -127,10 +109,8 @@ LocalPlayer::LocalPlayer(int id, int job, Map *map): #ifdef TMWSERV_SUPPORT mLocalWalkTime(-1), #endif - mStorage(new Inventory(STORAGE_SIZE)) -#ifdef TMWSERV_SUPPORT - , mExpMessageTime(0) -#endif + mStorage(new Inventory(STORAGE_SIZE)), + mMessageTime(0) { // 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 @@ -164,25 +144,28 @@ void LocalPlayer::logic() if (get_elapsed_time(mLastAction) >= 1000) mLastAction = -1; -#ifdef TMWSERV_SUPPORT // Show XP messages - if (!mExpMessages.empty()) + if (!mMessages.empty()) { - if (mExpMessageTime == 0) + if (mMessageTime == 0) { - const Vector &pos = getPosition(); + //const Vector &pos = getPosition(); + + MessagePair info = mMessages.front(); particleEngine->addTextRiseFadeOutEffect( - mExpMessages.front(), - (int) pos.x + 16, - (int) pos.y - 16, - &guiPalette->getColor(Palette::EXP_INFO), + info.first, + /*(int) pos.x, + (int) pos.y - 48,*/ + getPixelX(), + getPixelY() - 48, + &guiPalette->getColor(info.second), gui->getInfoParticleFont(), true); - mExpMessages.pop_front(); - mExpMessageTime = 30; + mMessages.pop_front(); + mMessageTime = 30; } - mExpMessageTime--; + mMessageTime--; } if ((mSpecialRechargeUpdateNeeded%11) == 0) @@ -201,7 +184,7 @@ void LocalPlayer::logic() } mSpecialRechargeUpdateNeeded++; -#else +#ifdef EATHENA_SUPPORT // Targeting allowed 4 times a second if (get_elapsed_time(mLastTarget) >= 250) mLastTarget = -1; @@ -213,7 +196,6 @@ void LocalPlayer::logic() setTarget(NULL); mLastTarget = -1; } - #endif if (mTarget) @@ -232,8 +214,8 @@ void LocalPlayer::logic() const int rangeY = abs(mTarget->getPosition().y - getPosition().y); #else // Find whether target is in range - const int rangeX = abs(mTarget->mX - mX); - const int rangeY = abs(mTarget->mY - mY); + const int rangeX = abs(mTarget->getTileX() - getTileX()); + const int rangeY = abs(mTarget->getTileY() - getTileY()); #endif const int attackRange = getAttackRange(); const int inRange = rangeX > attackRange || rangeY > attackRange @@ -366,13 +348,8 @@ void LocalPlayer::setInvItem(int index, int id, int amount) 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) { @@ -409,22 +386,12 @@ void LocalPlayer::walk(unsigned char dir) #ifdef TMWSERV_SUPPORT Being::setDestination(pos.x, pos.y); #else - Being::setDestination(mX, mY); + Being::setDestination(getTileX(), getTileY()); #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) @@ -433,7 +400,6 @@ void LocalPlayer::walk(unsigned char dir) dx--; if (dir & RIGHT) dx++; -#endif // Prevent skipping corners over colliding tiles #ifdef TMWSERV_SUPPORT @@ -444,9 +410,9 @@ void LocalPlayer::walk(unsigned char dir) ((int) pos.y + dy) / 32, getWalkMask())) dy = 16 - (int) pos.y % 32; #else - if (dx && !mMap->getWalk(mX + dx, mY, getWalkMask())) + if (dx && !mMap->getWalk(getTileX() + dx, getTileY(), getWalkMask())) dx = 0; - if (dy && !mMap->getWalk(mX, mY + dy, getWalkMask())) + if (dy && !mMap->getWalk(getTileX(), getTileY() + dy, getWalkMask())) dy = 0; #endif @@ -460,7 +426,7 @@ void LocalPlayer::walk(unsigned char dir) // Checks our path up to 1 tiles, if a blocking tile is found // We go to the last good tile, and break out of the loop - for (dScaler = 1; dScaler <= 1; dScaler++) + for (dScaler = 1; dScaler <= 32; dScaler++) { if ( (dx || dy) && !mMap->getWalk( ((int) pos.x + (dx * dScaler)) / 32, @@ -473,16 +439,17 @@ void LocalPlayer::walk(unsigned char dir) if (dScaler >= 0) { - setDestination((int) pos.x + (dx * dScaler), (int) pos.y + (dy * dScaler)); + effectManager->trigger(15, (int) pos.x + (dx * dScaler), (int) pos.y + (dy * dScaler)); + setDestination((int) pos.x + (dx * dScaler), (int) pos.y + (dy * dScaler)); } #else - if (dx && dy && !mMap->getWalk(mX + dx, mY + dy, getWalkMask())) + if (dx && dy && !mMap->getWalk(getTileX() + dx, getTileY() + dy, getWalkMask())) dx = 0; // Walk to where the player can actually go - if ((dx || dy) && mMap->getWalk(mX + dx, mY + dy, getWalkMask())) + if ((dx || dy) && mMap->getWalk(getTileX() + dx, getTileY() + dy, getWalkMask())) { - setDestination(mX + dx, mY + dy); + setDestination(getTileX() + dx, getTileY() + dy); } #endif else if (dir) @@ -588,21 +555,22 @@ void LocalPlayer::setWalkingDir(int dir) } } -#ifdef TMWSERV_SUPPORT void LocalPlayer::stopWalking(bool sendToServer) { if (mAction == WALK && mWalkingDir) { mWalkingDir = 0; +#ifdef TMWSERV_SUPPORT mLocalWalkTime = 0; +#endif Being::setDestination(getPosition().x,getPosition().y); if (sendToServer) - Net::GameServer::Player::walk(getPosition().x, getPosition().y); + Net::getPlayerHandler()->setDestination(getPosition().x, + getPosition().y); setAction(STAND); } clearPath(); } -#endif void LocalPlayer::toggleSit() { @@ -682,9 +650,10 @@ void LocalPlayer::attack() Net::GameServer::Player::attack(getSpriteDirection()); } */ + void LocalPlayer::useSpecial(int special) { - Net::GameServer::Player::useSpecial(special); + Net::getSpecialHandler()->use(special); } void LocalPlayer::setSpecialStatus(int id, int current, int max, int recharge) @@ -724,8 +693,8 @@ void LocalPlayer::attack(Being *target, bool keep) int dist_x = plaPos.x - tarPos.x; int dist_y = plaPos.y - tarPos.y; #else - int dist_x = target->mX - mX; - int dist_y = target->mY - mY; + int dist_x = target->getTileX() - getTileX(); + int dist_y = target->getTileY() - getTileY(); // Must be standing to attack if (mAction != STAND) @@ -802,14 +771,14 @@ void LocalPlayer::stopAttack() mLastTarget = -1; } -#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); + IntMap::iterator it = mAttributeBase.find(attr); + if (it != mAttributeBase.end()) + (*it).second++; + Net::getPlayerHandler()->increaseAttribute(attr); } void LocalPlayer::lowerAttribute(size_t attr) @@ -817,90 +786,179 @@ 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); + IntMap::iterator it = mAttributeBase.find(attr); + if (it != mAttributeBase.end()) + (*it).second--; + Net::getPlayerHandler()->decreaseAttribute(attr); } -const struct LocalPlayer::SkillInfo& LocalPlayer::getSkillInfo(int skill) +void LocalPlayer::setAttributeBase(int num, int value) { - 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 + int old = mAttributeBase[num]; + + mAttributeBase[num] = value; + if (skillDialog) { - return skills[skill]; + if (skillDialog->update(num).empty() || !(value > old)) + return; + + effectManager->trigger(1, this); } + + if (statusWindow) + statusWindow->update(num); +} + +void LocalPlayer::setAttributeEffective(int num, int value) +{ + mAttributeEffective[num] = value; + if (skillDialog) + skillDialog->update(num); + + if (statusWindow) + statusWindow->update(num); +} + +void LocalPlayer::setCharacterPoints(int n) +{ + mCharacterPoints = n; + + if (statusWindow) + statusWindow->update(StatusWindow::CHAR_POINTS); +} + +void LocalPlayer::setCorrectionPoints(int n) +{ + mCorrectionPoints = n; + + if (statusWindow) + statusWindow->update(StatusWindow::CHAR_POINTS); +} + +void LocalPlayer::setSkillPoints(int points) +{ + mSkillPoints = points; + if (skillDialog) + skillDialog->update(); } void LocalPlayer::setExperience(int skill, int current, int next) { - int diff = current - mExpCurrent.at(skill); - if (mMap && mExpCurrent.at(skill) != -1 && diff > 0) + std::pair<int, int> cur = getExperience(skill); + int diff = current - cur.first; + + cur = std::pair<int, int>(current, next); + + mSkillExp[skill] = cur; + std::string name; + if (skillDialog) + name = skillDialog->update(skill); + + if (mMap && cur.first != -1 && diff > 0 && !name.empty()) { - const std::string text = toString(diff) + " " + getSkillInfo(skill).name + " xp"; - mExpMessages.push_back(text); + addMessageToQueue(strprintf("%d %s xp", diff, name.c_str())); } - - 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)); + return mSkillExp[skill]; } -#else +void LocalPlayer::setHp(int value) +{ + mHp = value; -void LocalPlayer::setXp(int xp) + if (statusWindow) + statusWindow->update(StatusWindow::HP); +} + +void LocalPlayer::setMaxHp(int value) { - if (mMap && xp > mXp) + mMaxHp = value; + + if (statusWindow) + statusWindow->update(StatusWindow::HP); +} + +void LocalPlayer::setLevel(int value) +{ + mLevel = value; + + if (statusWindow) + statusWindow->update(StatusWindow::LEVEL); +} + +void LocalPlayer::setExp(int value) +{ + if (mMap && value > mExp) { - const std::string text = toString(xp - mXp) + " xp"; - - // Show XP number - particleEngine->addTextRiseFadeOutEffect( - text, - getPixelX(), - getPixelY() - 48, - &guiPalette->getColor(Palette::EXP_INFO), - gui->getInfoParticleFont(), true); + addMessageToQueue(toString(value - mExp) + " xp"); } - mXp = xp; + mExp = value; + + if (statusWindow) + statusWindow->update(StatusWindow::EXP); } -#endif +void LocalPlayer::setExpNeeded(int value) +{ + mExpNeeded = value; -void LocalPlayer::pickedUp(const std::string &item) + if (statusWindow) + statusWindow->update(StatusWindow::EXP); +} + +void LocalPlayer::setMP(int value) +{ + mMp = value; + + if (statusWindow) + statusWindow->update(StatusWindow::MP); +} + +void LocalPlayer::setMaxMP(int value) +{ + mMaxMp = value; + + if (statusWindow) + statusWindow->update(StatusWindow::MP); +} + +void LocalPlayer::setMoney(int value) +{ + mMoney = value; + + if (statusWindow) + statusWindow->update(StatusWindow::MONEY); +} + +void LocalPlayer::pickedUp(const ItemInfo &itemInfo, int amount) { - if (mMap) + if (!amount) { - // Show pickup notification - particleEngine->addTextRiseFadeOutEffect( - item, - getPixelX(), - getPixelY() - 48, - &guiPalette->getColor(Palette::PICKUP_INFO), - gui->getInfoParticleFont(), true); + if (config.getValue("showpickupchat", 1)) + { + localChatTab->chatLog(_("Unable to pick up item."), BY_SERVER); + } + } + else + { + if (config.getValue("showpickupchat", 1)) + { + // TRANSLATORS: This sentence may be translated differently + // for different grammatical numbers (singular, plural, ...) + localChatTab->chatLog(strprintf(ngettext("You picked up %d " + "[@@%d|%s@@].", "You picked up %d [@@%d|%s@@].", amount), + amount, itemInfo.getId(), itemInfo.getName().c_str()), + BY_SERVER); + } + + if (mMap && config.getValue("showpickupparticle", 0)) + { + // Show pickup notification + addMessageToQueue(itemInfo.getName(), Palette::PICKUP_INFO); + } } } @@ -930,8 +988,8 @@ bool LocalPlayer::withinAttackRange(Being *target) return !(dx > range || dy > range); #else - int dist_x = abs(target->mX - mX); - int dist_y = abs(target->mY - mY); + int dist_x = abs(target->getTileX() - getTileY()); + int dist_y = abs(target->getTileY() - getTileX()); if (dist_x > getAttackRange() || dist_y > getAttackRange()) { @@ -953,7 +1011,7 @@ void LocalPlayer::setGotoTarget(Being *target) #else setTarget(target); mGoingToTarget = true; - setDestination(target->mX, target->mY); + setDestination(target->getTileX(), target->getTileY()); #endif } @@ -1049,3 +1107,9 @@ void LocalPlayer::setInStorage(bool inStorage) storageWindow->setVisible(inStorage); } #endif + +void LocalPlayer::addMessageToQueue(const std::string &message, + Palette::ColorType color) +{ + mMessages.push_back(MessagePair(message, color)); +} diff --git a/src/localplayer.h b/src/localplayer.h index 0a3f742b..0b41ca82 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -26,6 +26,7 @@ #include <vector> #include "player.h" +#include "gui/palette.h" class Equipment; class FloorItem; @@ -34,7 +35,6 @@ class Inventory; class Item; class Map; -#ifdef TMWSERV_SUPPORT struct Special { @@ -43,6 +43,7 @@ struct Special int recharge; }; + /** * Attributes used during combat. Available to all the beings. */ @@ -91,66 +92,26 @@ enum 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 + NB_CHARACTER_ATTRIBUTES = CHAR_ATTR_END }; -#endif - /** * The local player character. */ class LocalPlayer : public Player { public: +#ifdef TMWSERV_SUPPORT enum Attribute { -#ifdef TMWSERV_SUPPORT STR = 0, AGI, DEX, VIT, INT, WIL, CHR -#else - STR = 0, AGI, VIT, INT, DEX, LUK -#endif }; +#endif /** * Constructor. */ -#ifdef TMWSERV_SUPPORT - LocalPlayer(); -#else - LocalPlayer(int id, int job, Map *map); -#endif + LocalPlayer(int id= 65535, int job = 0, Map *map = NULL); /** * Destructor. @@ -220,14 +181,13 @@ class LocalPlayer : public Player */ void setTrading(bool trading) { mTrading = trading; } -#ifdef TMWSERV_SUPPORT void useSpecial(int id); void setSpecialStatus(int id, int current, int max, int recharge); const std::map<int, Special> &getSpecialStatus() const { return mSpecials; } -#endif + void attack(Being *target = NULL, bool keep = false); /** @@ -292,7 +252,6 @@ class LocalPlayer : public Player */ bool withinAttackRange(Being *target); -#ifdef TMWSERV_SUPPORT /** * Stops the player dead in his tracks */ @@ -307,15 +266,14 @@ class LocalPlayer : public Player * Uses a correction point to lower an attribute */ void lowerAttribute(size_t attr); -#endif void toggleSit(); void emote(Uint8 emotion); /** - * Shows item pickup effect if the player is on a map. + * Shows item pickup notifications. */ - void pickedUp(const std::string &item); + void pickedUp(const ItemInfo &itemInfo, int amount); /** * Accessors for mInStorage @@ -324,34 +282,7 @@ class LocalPlayer : public Player void setInStorage(bool inStorage); #ifdef EATHENA_SUPPORT - /** - * Sets the amount of XP. Shows XP gaining effect if the player is on - * a map. - */ - void setXp(int xp); - - /** - * Returns the amount of experience points. - */ - int getXp() const { return mXp; } - - Uint32 mCharId; /**< Used only during character selection. */ - - Uint32 mJobXp; - Uint32 mJobLevel; - Uint32 mXpForNextLevel, mJobXpForNextLevel; - Uint16 mMp, mMaxMp; - Uint16 mAttackRange; - - Uint8 mAttr[6]; - Uint8 mAttrUp[6]; - - int ATK, MATK, DEF, MDEF, HIT, FLEE; - int ATK_BONUS, MATK_BONUS, DEF_BONUS, MDEF_BONUS, FLEE_BONUS; - - Uint16 mStatPoint, mSkillPoint; - Uint16 mStatsPointsToAttribute; #endif int getHp() const @@ -360,31 +291,39 @@ class LocalPlayer : public Player int getMaxHp() const { return mMaxHp; } - void setHp(int value) - { mHp = value; } + void setHp(int value); - void setMaxHp(int value) - { mMaxHp = value; } + void setMaxHp(int value); int getLevel() const { return mLevel; } - void setLevel(int value) - { mLevel = value; } + void setLevel(int value); -#ifdef TMWSERV_SUPPORT - void setLevelProgress(int percent) - { mLevelProgress = percent; } + void setExp(int value); - int getLevelProgress() const - { return mLevelProgress; } -#endif + int getExp() const + { return mExp; } + + void setExpNeeded(int value); + + int getExpNeeded() const + { return mExpNeeded; } + + void setMP(int value); + + int getMP() const + { return mMp; } + + void setMaxMP(int value); + + int getMaxMP() const + { return mMaxMp; } int getMoney() const { return mMoney; } - void setMoney(int value) - { mMoney = value; } + void setMoney(int value); int getTotalWeight() const { return mTotalWeight; } @@ -398,42 +337,34 @@ class LocalPlayer : public Player void setMaxWeight(int value) { mMaxWeight = value; } -#ifdef TMWSERV_SUPPORT - int getAttributeBase(int num) const + int getAttributeBase(int num) { return mAttributeBase[num]; } - void setAttributeBase(int num, int value) - { mAttributeBase[num] = value; } + void setAttributeBase(int num, int value); - int getAttributeEffective(int num) const + int getAttributeEffective(int num) { return mAttributeEffective[num]; } - void setAttributeEffective(int num, int value) - { mAttributeEffective[num] = value; } + void setAttributeEffective(int num, int value); int getCharacterPoints() const { return mCharacterPoints; } - void setCharacterPoints(int n) - { mCharacterPoints = n; } + void setCharacterPoints(int n); int getCorrectionPoints() const { return mCorrectionPoints; } - void setCorrectionPoints(int n) - { mCorrectionPoints = n; } + void setCorrectionPoints(int n); - void setExperience(int skill, int current, int next); + int getSkillPoints() const + { return mSkillPoints; } - struct SkillInfo { - std::string name; - std::string icon; - }; + void setSkillPoints(int points); - static const SkillInfo& getSkillInfo(int skill); + void setExperience(int skill, int current, int next); std::pair<int, int> getExperience(int skill); -#endif bool mUpdateName; /** Whether or not the name settings have changed */ @@ -441,6 +372,9 @@ class LocalPlayer : public Player const std::auto_ptr<Equipment> mEquipment; + void addMessageToQueue(const std::string &message, + Palette::ColorType color = Palette::EXP_INFO); + protected: virtual void handleStatusEffect(StatusEffect *effect, int effectId); @@ -448,29 +382,29 @@ class LocalPlayer : public Player bool mInStorage; /**< Whether storage is currently accessible */ #ifdef EATHENA_SUPPORT - int mXp; /**< Experience points. */ int mTargetTime; /** How long the being has been targeted **/ #endif int mLastTarget; /** Time stamp of last targeting action, -1 if none. */ -#ifdef TMWSERV_SUPPORT // Character status: - std::vector<int> mAttributeBase; - std::vector<int> mAttributeEffective; - std::vector<int> mExpCurrent; - std::vector<int> mExpNext; + typedef std::map<int, int> IntMap; + IntMap mAttributeBase; + IntMap mAttributeEffective; + std::map<int, std::pair<int, int> > mSkillExp; int mCharacterPoints; int mCorrectionPoints; int mLevelProgress; std::map<int, Special> mSpecials; char mSpecialRechargeUpdateNeeded; -#endif int mLevel; + int mExp, mExpNeeded; + int mMp, mMaxMp; int mMoney; int mTotalWeight; int mMaxWeight; int mHp; int mMaxHp; + int mSkillPoints; int mGMLevel; @@ -512,10 +446,10 @@ 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 + typedef std::pair<std::string, Palette::ColorType> MessagePair; + /** Queued exp messages*/ + std::list<MessagePair> mMessages; + int mMessageTime; }; extern LocalPlayer *player_node; diff --git a/src/main.cpp b/src/main.cpp index 3ea8aa2d..10145dfc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -143,9 +143,6 @@ namespace } listener; } -static const int defaultScreenWidth = 800; -static const int defaultScreenHeight = 600; - static const int defaultSfxVolume = 100; static const int defaultMusicVolume = 60; @@ -260,7 +257,7 @@ static void setUpdatesDir() else { logger->log("Error: Invalid update host: %s", updateHost.c_str()); - errorMessage = _("Invalid update host: ") + updateHost; + errorMessage = strprintf(_("Invalid update host: %s"), updateHost.c_str()); state = STATE_ERROR; } } @@ -335,10 +332,8 @@ static void initHomeDir(const Options &options) (errno != EEXIST)) #endif { - std::cout << homeDir - << _(" can't be created, but it doesn't exist! Exiting.") - << std::endl; - exit(1); + logger->error(strprintf(_("%s doesn't exist and can't be created! " + "Exiting."), homeDir.c_str())); } } @@ -389,8 +384,7 @@ static void initConfiguration(const Options &options) configFile = fopen(configPath.c_str(), "wt"); } if (configFile == NULL) { - std::cout << "Can't create " << configPath << ". " - << "Using Defaults." << std::endl; + logger->log("Can't create %s. Using defaults.", configPath.c_str()); } else { fclose(configFile); config.init(configPath); @@ -405,9 +399,8 @@ 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: " << - SDL_GetError() << std::endl; - exit(1); + logger->error(strprintf("Could not initialize SDL: %s", + SDL_GetError())); } atexit(SDL_Quit); @@ -420,10 +413,8 @@ static void initEngine(const Options &options) ResourceManager *resman = ResourceManager::getInstance(); if (!resman->setWriteDir(homeDir)) { - std::cout << homeDir - << " couldn't be set as home directory! Exiting." - << std::endl; - exit(1); + logger->error(strprintf("%s couldn't be set as home directory! " + "Exiting.", homeDir.c_str())); } // Add the user's homedir to PhysicsFS search path @@ -489,10 +480,8 @@ static void initEngine(const Options &options) // Try to set the desired video mode if (!graphics->setVideoMode(width, height, bpp, fullscreen, hwaccel)) { - std::cerr << _("Couldn't set ") - << width << "x" << height << "x" << bpp << _(" video mode: ") - << SDL_GetError() << std::endl; - exit(1); + logger->error(strprintf("Couldn't set %dx%dx%d video mode: %s", + width, height, bpp, SDL_GetError())); } // Initialize for drawing @@ -1160,7 +1149,7 @@ int main(int argc, char *argv[]) case STATE_LOGIN_ERROR: logger->log("State: LOGIN ERROR"); - currentDialog = new OkDialog("Error ", errorMessage); + currentDialog = new OkDialog(_("Error"), errorMessage); currentDialog->addActionListener(&loginListener); currentDialog = NULL; // OkDialog deletes itself break; @@ -1214,8 +1203,8 @@ int main(int argc, char *argv[]) case STATE_CHANGEEMAIL: logger->log("State: CHANGE EMAIL"); - currentDialog = new OkDialog("Email Address change", - "Email Address changed successfully!"); + currentDialog = new OkDialog(_("Email Address Change"), + _("Email address changed successfully!")); currentDialog->addActionListener(&accountListener); currentDialog = NULL; // OkDialog deletes itself loginData.email = loginData.newEmail; @@ -1231,8 +1220,8 @@ int main(int argc, char *argv[]) case STATE_CHANGEPASSWORD: logger->log("State: CHANGE PASSWORD"); - currentDialog = new OkDialog("Password change", - "Password changed successfully!"); + currentDialog = new OkDialog(_("Password Change"), + _("Password changed successfully!")); currentDialog->addActionListener(&accountListener); currentDialog = NULL; // OkDialog deletes itself loginData.password = loginData.newPassword; @@ -1248,8 +1237,8 @@ int main(int argc, char *argv[]) case STATE_UNREGISTER: logger->log("State: UNREGISTER"); accountServerConnection->disconnect(); - currentDialog = new OkDialog("Unregister successful", - "Farewell, come back any time ...."); + currentDialog = new OkDialog(_("Unregister Successful"), + _("Farewell, come back any time...")); loginData.clear(); //The errorlistener sets the state to STATE_CHOOSE_SERVER currentDialog->addActionListener(&errorListener); @@ -1258,7 +1247,7 @@ int main(int argc, char *argv[]) case STATE_ACCOUNTCHANGE_ERROR: logger->log("State: ACCOUNT CHANGE ERROR"); - currentDialog = new OkDialog("Error ", errorMessage); + currentDialog = new OkDialog(_("Error"), errorMessage); currentDialog->addActionListener(&accountListener); currentDialog = NULL; // OkDialog deletes itself break; @@ -1266,7 +1255,7 @@ int main(int argc, char *argv[]) case STATE_ERROR: logger->log("State: ERROR"); - currentDialog = new OkDialog("Error", errorMessage); + currentDialog = new OkDialog(_("Error"), errorMessage); currentDialog->addActionListener(&errorListener); currentDialog = NULL; // OkDialog deletes itself gameServerConnection->disconnect(); @@ -1555,8 +1544,8 @@ int main(int argc, char *argv[]) case STATE_CHANGEPASSWORD: logger->log("State: CHANGE PASSWORD"); - currentDialog = new OkDialog("Password change", - "Password changed successfully!"); + currentDialog = new OkDialog(_("Password Change"), + _("Password changed successfully!")); currentDialog->addActionListener(&accountListener); currentDialog = NULL; // OkDialog deletes itself loginData.password = loginData.newPassword; @@ -1565,7 +1554,7 @@ int main(int argc, char *argv[]) case STATE_ACCOUNTCHANGE_ERROR: logger->log("State: ACCOUNT CHANGE ERROR"); - currentDialog = new OkDialog("Error ", errorMessage); + currentDialog = new OkDialog(_("Error"), errorMessage); currentDialog->addActionListener(&accountListener); currentDialog = NULL; // OkDialog deletes itself break; diff --git a/src/map.cpp b/src/map.cpp index 61fcdfe8..dbecda3d 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -218,11 +218,12 @@ void Map::initializeOverlays() const float speedX = getFloatProperty(name + "scrollX"); const float speedY = getFloatProperty(name + "scrollY"); const float parallax = getFloatProperty(name + "parallax"); + const bool keepRatio = getBoolProperty(name + "keepratio"); if (img) { mOverlays.push_back( - new AmbientOverlay(img, parallax, speedX, speedY)); + new AmbientOverlay(img, parallax, speedX, speedY, keepRatio)); // The AmbientOverlay takes control over the image. img->decRef(); @@ -448,7 +449,7 @@ bool Map::occupied(int x, int y) const const Being *being = *i; // job 45 is a portal, they don't collide - if (being->mX == x && being->mY == y && being->mJob != 45) + if (being->getTileX() == x && being->getTileY() == y && being->mJob != 45) return true; } @@ -490,50 +491,6 @@ const std::string &Map::getName() const return getProperty("mapname"); } -Path Map::findSimplePath(int startX, int startY, - int destX, int destY, - unsigned char walkmask) -{ - // Path to be built up (empty by default) - Path path; - int positionX = startX, positionY = startY; - int directionX, directionY; - // Checks our path up to 1 tiles, if a blocking tile is found - // We go to the last good tile, and break out of the loop - while(true) - { - directionX = destX - positionX; - directionY = destY - positionY; - - if (directionX > 0) - directionX = 1; - else if(directionX < 0) - directionX = -1; - - if (directionY > 0) - directionY = 1; - else if(directionY < 0) - directionY = -1; - - positionX += directionX; - positionY += directionY; - - if (getWalk(positionX, positionY, walkmask)) - { - path.push_back(Position(positionX, positionY)); - - if ((positionX == destX) && (positionY == destY)) - { - return path; - } - } - else - { - return path; - } - } -} - static int const basicCost = 100; Path Map::findPath(int startX, int startY, int destX, int destY, @@ -258,13 +258,6 @@ class Map : public Properties const std::string &getName() const; /** - * Find a simple path from one location to the next. - */ - Path findSimplePath(int startX, int startY, - int destX, int destY, - unsigned char walkmask); - - /** * Find a path from one location to the next. */ Path findPath(int startX, int startY, int destX, int destY, diff --git a/src/net/ea/beinghandler.cpp b/src/net/ea/beinghandler.cpp index f149f15f..1d780a60 100644 --- a/src/net/ea/beinghandler.cpp +++ b/src/net/ea/beinghandler.cpp @@ -194,14 +194,15 @@ void BeingHandler::handleMessage(MessageIn &msg) Uint16 srcX, srcY, dstX, dstY; msg.readCoordinatePair(srcX, srcY, dstX, dstY); dstBeing->setAction(Being::STAND); - dstBeing->mX = srcX; - dstBeing->mY = srcY; + dstBeing->setTileCoords(srcX, srcY); dstBeing->setDestination(dstX, dstY); } else { Uint8 dir; - msg.readCoordinates(dstBeing->mX, dstBeing->mY, dir); + Uint16 x, y; + msg.readCoordinates(x, y, dir); + dstBeing->setTileCoords(x, y); dstBeing->setDirection(dir); } @@ -234,8 +235,7 @@ void BeingHandler::handleMessage(MessageIn &msg) if (dstBeing) { dstBeing->setAction(Being::STAND); - dstBeing->mX = srcX; - dstBeing->mY = srcY; + dstBeing->setTileCoords(srcX, srcY); dstBeing->setDestination(dstX, dstY); } @@ -515,14 +515,15 @@ void BeingHandler::handleMessage(MessageIn &msg) { Uint16 srcX, srcY, dstX, dstY; msg.readCoordinatePair(srcX, srcY, dstX, dstY); - dstBeing->mX = srcX; - dstBeing->mY = srcY; + dstBeing->setTileCoords(srcX, srcY); dstBeing->setDestination(dstX, dstY); } else { Uint8 dir; - msg.readCoordinates(dstBeing->mX, dstBeing->mY, dir); + Uint16 x, y; + msg.readCoordinates(x, y, dir); + dstBeing->setTileCoords(x, y); dstBeing->setDirection(dir); } @@ -577,8 +578,10 @@ void BeingHandler::handleMessage(MessageIn &msg) if (mSync || id != player_node->getId()) { dstBeing = beingManager->findBeing(id); if (dstBeing) { - dstBeing->mX = msg.readInt16(); - dstBeing->mY = msg.readInt16(); + Uint16 x, y; + x = msg.readInt16(); + y = msg.readInt16(); + dstBeing->setTileCoords(x, y); if (dstBeing->mAction == Being::WALK) { dstBeing->mFrame = 0; dstBeing->setAction(Being::STAND); diff --git a/src/net/ea/charserverhandler.cpp b/src/net/ea/charserverhandler.cpp index 77bfaa50..6fae1864 100644 --- a/src/net/ea/charserverhandler.cpp +++ b/src/net/ea/charserverhandler.cpp @@ -61,18 +61,16 @@ CharServerHandler::CharServerHandler(): void CharServerHandler::handleMessage(MessageIn &msg) { - int slot, flags; + int slot; LocalPlayer *tempPlayer; logger->log("CharServerHandler: Packet ID: %x, Length: %d", msg.getId(), msg.getLength()); switch (msg.getId()) { - case 0x006b: + case SMSG_CHAR_LOGIN: msg.skip(2); // Length word - flags = msg.readInt32(); // Aethyra extensions flags - logger->log("Server flags are: %x", flags); - msg.skip(16); // Unused + msg.skip(20); // Unused // Derive number of characters from message length n_character = (msg.getLength() - 24) / 106; @@ -92,13 +90,13 @@ void CharServerHandler::handleMessage(MessageIn &msg) case SMSG_CHAR_LOGIN_ERROR: switch (msg.readInt8()) { case 0: - errorMessage = _("Access denied"); + errorMessage = _("Access denied."); break; case 1: - errorMessage = _("Cannot use this ID"); + errorMessage = _("Cannot use this ID."); break; default: - errorMessage = _("Unknown failure to select character"); + errorMessage = _("Unknown failure to select character."); break; } mCharInfo->unlock(); @@ -169,14 +167,15 @@ void CharServerHandler::handleMessage(MessageIn &msg) LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot) { - LocalPlayer *tempPlayer = new LocalPlayer(mLoginData->account_ID, 0, NULL); + LocalPlayer *tempPlayer = new LocalPlayer(msg.readInt32(), 0, NULL); tempPlayer->setGender(mLoginData->sex); - tempPlayer->mCharId = msg.readInt32(); - tempPlayer->setXp(msg.readInt32()); + tempPlayer->setExp(msg.readInt32()); tempPlayer->setMoney(msg.readInt32()); - tempPlayer->mJobXp = msg.readInt32(); - tempPlayer->mJobLevel = msg.readInt32(); + tempPlayer->setExperience(JOB, msg.readInt32(), 1); + int temp = msg.readInt32(); + tempPlayer->setAttributeBase(JOB, temp); + tempPlayer->setAttributeEffective(JOB, temp); tempPlayer->setSprite(Being::SHOE_SPRITE, msg.readInt16()); tempPlayer->setSprite(Being::GLOVES_SPRITE, msg.readInt16()); tempPlayer->setSprite(Being::CAPE_SPRITE, msg.readInt16()); @@ -187,8 +186,8 @@ LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot) msg.skip(2); // unknown tempPlayer->setHp(msg.readInt16()); tempPlayer->setMaxHp(msg.readInt16()); - tempPlayer->mMp = msg.readInt16(); - tempPlayer->mMaxMp = msg.readInt16(); + tempPlayer->setMP(msg.readInt16()); + tempPlayer->setMaxMP(msg.readInt16()); msg.readInt16(); // speed msg.readInt16(); // class int hairStyle = msg.readInt16(); @@ -205,7 +204,7 @@ LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot) tempPlayer->setSprite(Being::MISC2_SPRITE, msg.readInt16()); tempPlayer->setName(msg.readString(24)); for (int i = 0; i < 6; i++) { - tempPlayer->mAttr[i] = msg.readInt8(); + tempPlayer->setAttributeBase(i + STR, msg.readInt8()); } slot = msg.readInt8(); // character slot msg.readInt8(); // unknown @@ -272,7 +271,7 @@ void CharServerHandler::newCharacter(const std::string &name, int slot, void CharServerHandler::deleteCharacter(int slot, LocalPlayer* character) { MessageOut outMsg(CMSG_CHAR_DELETE); - outMsg.writeInt32(character->mCharId); + outMsg.writeInt32(character->getId()); outMsg.writeString("a@a.com", 40); } diff --git a/src/net/ea/chathandler.cpp b/src/net/ea/chathandler.cpp index 49f83e67..65f1db3c 100644 --- a/src/net/ea/chathandler.cpp +++ b/src/net/ea/chathandler.cpp @@ -166,7 +166,7 @@ void ChatHandler::handleMessage(MessageIn &msg) case SMSG_MVP: // Display MVP player msg.readInt32(); // id - localChatTab->chatLog("MVP player", BY_SERVER); + localChatTab->chatLog(_("MVP player."), BY_SERVER); break; } } diff --git a/src/net/ea/equipmenthandler.cpp b/src/net/ea/equipmenthandler.cpp index 0153b5da..3520bca5 100644 --- a/src/net/ea/equipmenthandler.cpp +++ b/src/net/ea/equipmenthandler.cpp @@ -35,10 +35,112 @@ #include "utils/gettext.h" +const Equipment::EquipmentSlots EQUIP_POINTS[Equipment::EQUIP_VECTOREND] = { + Equipment::EQUIP_LEGS_SLOT, + Equipment::EQUIP_FIGHT1_SLOT, + Equipment::EQUIP_GLOVES_SLOT, + Equipment::EQUIP_RING2_SLOT, + Equipment::EQUIP_RING1_SLOT, + Equipment::EQUIP_FIGHT2_SLOT, + Equipment::EQUIP_FEET_SLOT, + Equipment::EQUIP_NECK_SLOT, + Equipment::EQUIP_HEAD_SLOT, + Equipment::EQUIP_TORSO_SLOT, + Equipment::EQUIP_PROJECTILE_SLOT}; + +Item *equips[Equipment::EQUIP_VECTOREND]; + namespace EAthena { enum { debugEquipment = 1 }; +void setEquipment(int eAthenaSlot, int index, bool equiped) +{ + if (!eAthenaSlot) + return; + + Item *item = player_node->getInventory()->getItem(index); + + if (!item) + return; + + int position = 0; + + if (eAthenaSlot & 0x8000) { // Arrows + position = Equipment::EQUIP_PROJECTILE_SLOT; + } + else + { + /* + * An item may occupy more than 1 slot. If so, it's + * only shown as equipped on the *first* slot. + */ + int mask = 1; + while (!(eAthenaSlot & mask)) + { + mask <<= 1; + position++; + } + + position = EQUIP_POINTS[position]; + } + + if (equips[position]) + equips[position]->setEquipped(false); + + if (equiped && item) + { + equips[position] = item; + item->setEquipped(true); + player_node->mEquipment->setEquipment(position, item->getId(), item->getQuantity()); + + if (debugEquipment) + { + logger->log("Equipping: %i %i at position %i", + index, eAthenaSlot, position); + } + } + else + { + equips[position] = NULL; + player_node->mEquipment->setEquipment(position, -1); + + if (debugEquipment) + { + logger->log("Unequipping: %i %i at position %i", + index, eAthenaSlot, position); + } + } +} + +void clearEquipment() +{ + for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++) + { + if (equips[i]) + { + equips[i]->setEquipped(false); + player_node->mEquipment->setEquipment(i, -1); + } + + equips[i] = NULL; + } +} + +Item *getRealEquipedItem(const Item *equipped) +{ + if (!equipped) + return NULL; + + for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++) + { + if (equips[i] && equipped->getId() == equips[i]->getId()) + return equips[i]; + } + + return NULL; +} + EquipmentHandler::EquipmentHandler() { static const Uint16 _messages[] = { @@ -50,6 +152,7 @@ EquipmentHandler::EquipmentHandler() 0 }; handledMessages = _messages; + memset(equips, 0, sizeof(equips)); } void EquipmentHandler::handleMessage(MessageIn &msg) @@ -57,8 +160,6 @@ void EquipmentHandler::handleMessage(MessageIn &msg) int itemCount; int index, equipPoint, itemId; int type; - int mask, position; - Item *item; Inventory *inventory = player_node->getInventory(); switch (msg.getId()) @@ -79,25 +180,9 @@ void EquipmentHandler::handleMessage(MessageIn &msg) msg.readInt8(); // refine msg.skip(8); // card - if (debugEquipment) - { - logger->log("Index: %d, ID: %d", index, itemId); - } - inventory->setItem(index, itemId, 1, true); - if (equipPoint) - { - mask = 1; - position = 0; - while (!(equipPoint & mask)) - { - mask <<= 1; - position++; - } - item = inventory->getItem(index); - player_node->mEquipment->setEquipment(position, index); - } + setEquipment(equipPoint, index, true); } break; @@ -112,35 +197,7 @@ void EquipmentHandler::handleMessage(MessageIn &msg) break; } - // No point in searching when no point given - if (!equipPoint) - break; - - /* - * An item may occupy more than 1 slot. If so, it's - * only shown as equipped on the *first* slot. - */ - mask = 1; - position = 0; - while (!(equipPoint & mask)) { - mask <<= 1; - position++; - } - - if (debugEquipment) - { - logger->log("Equipping: %i %i %i at position %i", - index, equipPoint, type, position); - } - - item = inventory->getItem(player_node->mEquipment->getEquipment(position)); - - // Unequip any existing equipped item in this position - if (item) - item->setEquipped(false); - - item = inventory->getItem(index); - player_node->mEquipment->setEquipment(position, index); + setEquipment(equipPoint, index, true); break; case SMSG_PLAYER_UNEQUIP: @@ -153,36 +210,7 @@ void EquipmentHandler::handleMessage(MessageIn &msg) break; } - if (!equipPoint) { - // No point given, no point in searching - break; - } - - mask = 1; - position = 0; - while (!(equipPoint & mask)) { - mask <<= 1; - position++; - } - - item = inventory->getItem(index); - if (!item) - break; - - item->setEquipped(false); - - if (equipPoint & 0x8000) { // Arrows - player_node->mEquipment->setArrows(-1); - } - else { - player_node->mEquipment->removeEquipment(position); - } - - if (debugEquipment) - { - logger->log("Unequipping: %i %i(%i) %i", - index, equipPoint, type, position); - } + setEquipment(equipPoint, index, false); break; case SMSG_PLAYER_ATTACK_RANGE: @@ -197,13 +225,8 @@ void EquipmentHandler::handleMessage(MessageIn &msg) index -= INVENTORY_OFFSET; - item = inventory->getItem(index); - - if (item) { - item->setEquipped(true); - player_node->mEquipment->setArrows(index); - logger->log("Arrows equipped: %i", index); - } + logger->log("Arrows equipped: %i", index); + setEquipment(0x8000, index, true); break; } } diff --git a/src/net/ea/equipmenthandler.h b/src/net/ea/equipmenthandler.h index 852be3c9..47c2f803 100644 --- a/src/net/ea/equipmenthandler.h +++ b/src/net/ea/equipmenthandler.h @@ -24,8 +24,14 @@ #include "net/messagehandler.h" +class Item; + namespace EAthena { +void setEquipment(int eAthenaSlot, int index, bool equiped); +void clearEquipment(); +Item *getRealEquipedItem(const Item *equipped); + class EquipmentHandler : public MessageHandler { public: diff --git a/src/net/ea/generalhandler.cpp b/src/net/ea/generalhandler.cpp index 404bff69..1d500d62 100644 --- a/src/net/ea/generalhandler.cpp +++ b/src/net/ea/generalhandler.cpp @@ -19,10 +19,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "gui/inventorywindow.h" - #include "net/ea/generalhandler.h" +#include "gui/inventorywindow.h" +#include "gui/skilldialog.h" +#include "gui/statuswindow.h" + #include "net/ea/network.h" #include "net/ea/protocol.h" @@ -41,7 +43,7 @@ #include "net/ea/playerhandler.h" #include "net/ea/partyhandler.h" #include "net/ea/tradehandler.h" -#include "net/ea/skillhandler.h" +#include "net/ea/specialhandler.h" #include "net/ea/gui/partytab.h" @@ -77,7 +79,7 @@ GeneralHandler::GeneralHandler(): mNpcHandler(new NpcHandler), mPartyHandler(new PartyHandler), mPlayerHandler(new PlayerHandler), - mSkillHandler(new SkillHandler), + mSpecialHandler(new SpecialHandler), mTradeHandler(new TradeHandler) { static const Uint16 _messages[] = { @@ -115,26 +117,26 @@ void GeneralHandler::handleMessage(MessageIn &msg) switch (code) { case 0: - errorMessage = _("Authentication failed"); + errorMessage = _("Authentication failed."); break; case 1: - errorMessage = _("No servers available"); + errorMessage = _("No servers available."); break; case 2: if (state == STATE_GAME) errorMessage = _("Someone else is trying to use this " - "account"); + "account."); else - errorMessage = _("This account is already logged in"); + errorMessage = _("This account is already logged in."); break; case 3: - errorMessage = _("Speed hack detected"); + errorMessage = _("Speed hack detected."); break; case 8: - errorMessage = _("Duplicated login"); + errorMessage = _("Duplicated login."); break; default: - errorMessage = _("Unknown connection error"); + errorMessage = _("Unknown connection error."); break; } state = STATE_ERROR; @@ -157,7 +159,7 @@ void GeneralHandler::load() mNetwork->registerHandler(mMapHandler.get()); mNetwork->registerHandler(mNpcHandler.get()); mNetwork->registerHandler(mPlayerHandler.get()); - mNetwork->registerHandler(mSkillHandler.get()); + mNetwork->registerHandler(mSpecialHandler.get()); mNetwork->registerHandler(mTradeHandler.get()); mNetwork->registerHandler(mPartyHandler.get()); } @@ -201,6 +203,22 @@ void GeneralHandler::guiWindowsLoaded() { partyTab = new PartyTab; inventoryWindow->setSplitAllowed(false); + skillDialog->loadSkills("ea-skills.xml"); + + statusWindow->addAttribute(STR, _("Strength"), true); + statusWindow->addAttribute(AGI, _("Agility"), true); + statusWindow->addAttribute(VIT, _("Vitality"), true); + statusWindow->addAttribute(INT, _("Intelligence"), true); + statusWindow->addAttribute(DEX, _("Dexterity"), true); + statusWindow->addAttribute(LUK, _("Luck"), true); + + statusWindow->addAttribute(ATK, _("Attack"), false); + statusWindow->addAttribute(DEF, _("Defense"), false); + statusWindow->addAttribute(MATK, _("M.Attack"), false); + statusWindow->addAttribute(MDEF, _("M.Defense"), false); + statusWindow->addAttribute(HIT, _("% Accuracy"), false); + statusWindow->addAttribute(FLEE, _("% Evade"), false); + statusWindow->addAttribute(CRIT, _("% Critical"), false); } void GeneralHandler::guiWindowsUnloaded() diff --git a/src/net/ea/generalhandler.h b/src/net/ea/generalhandler.h index ebbc84ca..98364e5d 100644 --- a/src/net/ea/generalhandler.h +++ b/src/net/ea/generalhandler.h @@ -66,7 +66,7 @@ class GeneralHandler : public MessageHandler, public Net::GeneralHandler MessageHandlerPtr mNpcHandler; MessageHandlerPtr mPartyHandler; MessageHandlerPtr mPlayerHandler; - MessageHandlerPtr mSkillHandler; + MessageHandlerPtr mSpecialHandler; MessageHandlerPtr mTradeHandler; }; diff --git a/src/net/ea/inventoryhandler.cpp b/src/net/ea/inventoryhandler.cpp index c1f04661..b6e91609 100644 --- a/src/net/ea/inventoryhandler.cpp +++ b/src/net/ea/inventoryhandler.cpp @@ -21,6 +21,7 @@ #include "net/ea/inventoryhandler.h" +#include "net/ea/equipmenthandler.h" #include "net/ea/protocol.h" #include "net/messagein.h" @@ -86,6 +87,7 @@ void InventoryHandler::handleMessage(MessageIn &msg) if (msg.getId() == SMSG_PLAYER_INVENTORY) { // Clear inventory - this will be a complete refresh + clearEquipment(); inventory->clear(); } else @@ -178,42 +180,25 @@ void InventoryHandler::handleMessage(MessageIn &msg) equipType = msg.readInt16(); itemType = msg.readInt8(); - if (msg.readInt8() > 0) - { - if (config.getValue("showpickupchat", 1)) - { - localChatTab->chatLog(_("Unable to pick up item."), - BY_SERVER); - } - } - else { const ItemInfo &itemInfo = ItemDB::get(itemId); - const std::string amountStr = - // TRANSLATORS: Used as in "You picked up a ...", when - // picking up only one item. - (amount > 1) ? toString(amount) : _("a"); - if (config.getValue("showpickupchat", 1)) + if (msg.readInt8() > 0) { - localChatTab->chatLog(strprintf(_("You picked up %s [@@%d|%s@@]."), - amountStr.c_str(), itemInfo.getId(), itemInfo.getName().c_str()), - BY_SERVER); + player_node->pickedUp(itemInfo, 0); } - - if (config.getValue("showpickupparticle", 0)) + else { - player_node->pickedUp(itemInfo.getName()); - } + player_node->pickedUp(itemInfo, amount); + + Item *item = inventory->getItem(index); + + if (item && item->getId() == itemId) + amount += inventory->getItem(index)->getQuantity(); - if (Item *item = inventory->getItem(index)) { - item->setId(itemId); - item->increaseQuantity(amount); - } else { inventory->setItem(index, itemId, amount, equipType != 0); } - } - break; + } break; case SMSG_PLAYER_INVENTORY_REMOVE: index = msg.readInt16() - INVENTORY_OFFSET; @@ -319,11 +304,13 @@ void InventoryHandler::equipItem(const Item *item) void InventoryHandler::unequipItem(const Item *item) { - if (!item) + const Item *real_item = item->isEquipped() ? item : getRealEquipedItem(item); + + if (!real_item) return; MessageOut outMsg(CMSG_PLAYER_UNEQUIP); - outMsg.writeInt16(item->getInvIndex() + INVENTORY_OFFSET); + outMsg.writeInt16(real_item->getInvIndex() + INVENTORY_OFFSET); } void InventoryHandler::useItem(const Item *item) diff --git a/src/net/ea/loginhandler.cpp b/src/net/ea/loginhandler.cpp index 54e31cf3..8e7187c0 100644 --- a/src/net/ea/loginhandler.cpp +++ b/src/net/ea/loginhandler.cpp @@ -76,13 +76,13 @@ void LoginHandler::handleMessage(MessageIn &msg) errorMessage = _("Account was not found. Please re-login."); break; case 2: - errorMessage = _("Old password incorrect"); + errorMessage = _("Old password incorrect."); break; case 3: - errorMessage = _("New password too short"); + errorMessage = _("New password too short."); break; default: - errorMessage = _("Unknown error"); + errorMessage = _("Unknown error."); break; } state = STATE_ACCOUNTCHANGE_ERROR; @@ -96,7 +96,7 @@ void LoginHandler::handleMessage(MessageIn &msg) len = msg.readInt16() - 4; mUpdateHost = msg.readString(len); - logger->log("Received update host \"%s\" from login server", + logger->log("Received update host \"%s\" from login server.", mUpdateHost.c_str()); break; @@ -139,21 +139,21 @@ void LoginHandler::handleMessage(MessageIn &msg) switch (code) { case 0: - errorMessage = _("Unregistered ID"); + errorMessage = _("Unregistered ID."); break; case 1: - errorMessage = _("Wrong password"); + errorMessage = _("Wrong password."); break; case 2: - errorMessage = _("Account expired"); + errorMessage = _("Account expired."); break; case 3: - errorMessage = _("Rejected from server"); + errorMessage = _("Rejected from server."); break; case 4: errorMessage = _("You have been permanently banned from " - "the game. Please contact the GM Team."); + "the game. Please contact the GM team."); break; case 6: errorMessage = strprintf(_("You have been temporarily " @@ -163,10 +163,10 @@ void LoginHandler::handleMessage(MessageIn &msg) msg.readString(20).c_str()); break; case 9: - errorMessage = _("This user name is already taken"); + errorMessage = _("This user name is already taken."); break; default: - errorMessage = _("Unknown error"); + errorMessage = _("Unknown error."); break; } state = STATE_ERROR; diff --git a/src/net/ea/maphandler.cpp b/src/net/ea/maphandler.cpp index 6f8a9827..c3c9437c 100644 --- a/src/net/ea/maphandler.cpp +++ b/src/net/ea/maphandler.cpp @@ -61,14 +61,17 @@ void MapHandler::handleMessage(MessageIn &msg) switch (msg.getId()) { case SMSG_MAP_LOGIN_SUCCESS: + { + Uint16 x, y; msg.readInt32(); // server tick - msg.readCoordinates(player_node->mX, player_node->mY, direction); + msg.readCoordinates(x, y, direction); msg.skip(2); // unknown logger->log("Protocol: Player start position: (%d, %d), Direction: %d", - player_node->mX, player_node->mY, direction); + x, y, direction); state = STATE_GAME; + player_node->setTileCoords(x, y); game = new Game; - break; + } break; case SMSG_SERVER_PING: // We ignore this for now @@ -76,22 +79,27 @@ void MapHandler::handleMessage(MessageIn &msg) break; case SMSG_WHO_ANSWER: - localChatTab->chatLog("Online users: " + toString(msg.readInt32()), - BY_SERVER); + localChatTab->chatLog(strprintf(_("Online users: %d"), + msg.readInt32()), BY_SERVER); break; } } +#include <fstream> + void MapHandler::connect(LoginData *loginData) { // Send login infos MessageOut outMsg(CMSG_MAP_SERVER_CONNECT); outMsg.writeInt32(loginData->account_ID); - outMsg.writeInt32(player_node->mCharId); + outMsg.writeInt32(player_node->getId()); outMsg.writeInt32(loginData->session_ID1); outMsg.writeInt32(loginData->session_ID2); outMsg.writeInt8((loginData->sex == GENDER_MALE) ? 1 : 0); + // Change the player's ID to the account ID to match what eAthena uses + player_node->setId(loginData->account_ID); + // We get 4 useless bytes before the real answer comes in (what are these?) mNetwork->skip(4); } diff --git a/src/net/ea/network.cpp b/src/net/ea/network.cpp index 956d7877..c6bc712c 100644 --- a/src/net/ea/network.cpp +++ b/src/net/ea/network.cpp @@ -318,9 +318,9 @@ bool Network::realConnect() if (SDLNet_ResolveHost(&ipAddress, mAddress.c_str(), mPort) == -1) { - std::string error = "Unable to resolve host \"" + mAddress + "\""; - setError(error); - logger->log("SDLNet_ResolveHost: %s", error.c_str()); + std::string errorMessage = "Unable to resolve host \"" + mAddress + "\""; + setError(errorMessage); + logger->log("SDLNet_ResolveHost: %s", errorMessage.c_str()); return false; } diff --git a/src/net/ea/partyhandler.cpp b/src/net/ea/partyhandler.cpp index 5e7f43c4..a4a84b07 100644 --- a/src/net/ea/partyhandler.cpp +++ b/src/net/ea/partyhandler.cpp @@ -230,6 +230,7 @@ void PartyHandler::handleMessage(MessageIn &msg) if (id == player_node->getId()) { partyWindow->clearMembers(); + partyWindow->clearPartyName(); partyWindow->setVisible(false); partyTab->chatLog(_("You have left the party."), BY_SERVER); } diff --git a/src/net/ea/playerhandler.cpp b/src/net/ea/playerhandler.cpp index 58167339..3e379d82 100644 --- a/src/net/ea/playerhandler.cpp +++ b/src/net/ea/playerhandler.cpp @@ -37,7 +37,7 @@ #include "gui/gui.h" #include "gui/okdialog.h" #include "gui/sell.h" -#include "gui/skill.h" +#include "gui/statuswindow.h" #include "gui/storagewindow.h" #include "gui/viewport.h" @@ -54,6 +54,9 @@ OkDialog *deathNotice = NULL; // everything beyond will reset the port hard. static const int MAP_TELEPORT_SCROLL_DISTANCE = 8; +#define ATTR_BONUS(atr) \ +(player_node->getAttributeEffective(atr) - player_node->getAttributeBase(atr)) + // TODO Move somewhere else namespace { @@ -197,17 +200,16 @@ void PlayerHandler::handleMessage(MessageIn &msg) /* Scroll if neccessary */ if (!nearby - || (abs(x - player_node->mX) > MAP_TELEPORT_SCROLL_DISTANCE) - || (abs(y - player_node->mY) > MAP_TELEPORT_SCROLL_DISTANCE)) + || (abs(x - player_node->getTileX()) > MAP_TELEPORT_SCROLL_DISTANCE) + || (abs(y - player_node->getTileY()) > MAP_TELEPORT_SCROLL_DISTANCE)) { - scrollOffsetX = (x - player_node->mX) * 32; - scrollOffsetY = (y - player_node->mY) * 32; + scrollOffsetX = (x - player_node->getTileX()) * 32; + scrollOffsetY = (y - player_node->getTileY()) * 32; } player_node->setAction(Being::STAND); player_node->mFrame = 0; - player_node->mX = x; - player_node->mY = y; + player_node->setTileCoords(x, y); logger->log("Adjust scrolling by %d:%d", (int) scrollOffsetX, (int) scrollOffsetY); @@ -224,18 +226,14 @@ void PlayerHandler::handleMessage(MessageIn &msg) switch (type) { case 0x0000: player_node->setWalkSpeed(value); break; + case 0x0004: break; // manner 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 0x0007: player_node->setMP(value); break; + case 0x0008: player_node->setMaxMP(value); break; + case 0x0009: player_node->setCharacterPoints(value); break; case 0x000b: player_node->setLevel(value); break; - case 0x000c: - player_node->mSkillPoint = value; - skillDialog->update(); - break; + case 0x000c: player_node->setSkillPoints(value); break; case 0x0018: if (value >= player_node->getMaxWeight() / 2 && player_node->getTotalWeight() < @@ -251,15 +249,48 @@ void PlayerHandler::handleMessage(MessageIn &msg) player_node->setTotalWeight(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; - case 0x002e: player_node->DEF_BONUS = value; break; - case 0x002f: player_node->MDEF = value; break; - case 0x0031: player_node->HIT = value; break; - case 0x0032: player_node->FLEE = value; break; + + case 0x0029: player_node->setAttributeEffective(ATK, value + + ATTR_BONUS(ATK)); + player_node->setAttributeBase(ATK, value); + break; + case 0x002a: value += player_node->getAttributeBase(ATK); + player_node->setAttributeEffective(ATK, value); break; + + case 0x002b: player_node->setAttributeEffective(MATK, value + + ATTR_BONUS(MATK)); + player_node->setAttributeBase(MATK, value); + statusWindow->update(StatusWindow::MP); break; + case 0x002c: value += player_node->getAttributeBase(MATK); + player_node->setAttributeEffective(MATK, value); + statusWindow->update(StatusWindow::MP); break; + case 0x002d: player_node->setAttributeEffective(DEF, value + + ATTR_BONUS(DEF)); + player_node->setAttributeBase(DEF, value); break; + case 0x002e: value += player_node->getAttributeBase(DEF); + player_node->setAttributeEffective(DEF, value); break; + + case 0x002f: player_node->setAttributeEffective(MDEF, value + + ATTR_BONUS(MDEF)); + player_node->setAttributeBase(MDEF, value); break; + case 0x0030: value += player_node->getAttributeBase(MDEF); + player_node->setAttributeEffective(MDEF, value); break; + + case 0x0031: player_node->setAttributeBase(HIT, value); + player_node->setAttributeEffective(HIT, value); break; + + case 0x0032: player_node->setAttributeEffective(FLEE, value + + ATTR_BONUS(FLEE)); + player_node->setAttributeBase(FLEE, value); break; + case 0x0033: value += player_node->getAttributeBase(FLEE); + player_node->setAttributeEffective(FLEE, value); break; + + case 0x0034: player_node->setAttributeBase(CRIT, value); + player_node->setAttributeEffective(CRIT, value); break; + case 0x0035: player_node->mAttackSpeed = value; break; - case 0x0037: player_node->mJobLevel = value; break; + case 0x0037: player_node->setAttributeBase(JOB, value); + player_node->setAttributeEffective(JOB, value); break; case 500: player_node->setGMLevel(value); break; } @@ -276,54 +307,45 @@ void PlayerHandler::handleMessage(MessageIn &msg) case SMSG_PLAYER_STAT_UPDATE_2: switch (msg.readInt16()) { case 0x0001: - player_node->setXp(msg.readInt32()); + player_node->setExp(msg.readInt32()); break; case 0x0002: - player_node->mJobXp = msg.readInt32(); + player_node->setExperience(JOB, msg.readInt32(), + player_node->getExperience(JOB).second); break; case 0x0014: { int curGp = player_node->getMoney(); player_node->setMoney(msg.readInt32()); if (player_node->getMoney() > curGp) - localChatTab->chatLog(_("You picked up ") + + localChatTab->chatLog(strprintf(_("You picked up " + "%s."), Units::formatCurrency(player_node->getMoney() - - curGp), BY_SERVER); + - curGp).c_str()), BY_SERVER); } break; case 0x0016: - player_node->mXpForNextLevel = msg.readInt32(); + player_node->setExpNeeded(msg.readInt32()); break; case 0x0017: - player_node->mJobXpForNextLevel = msg.readInt32(); + player_node->setExperience(JOB, + player_node->getExperience(JOB).first, + msg.readInt32()); break; } break; - case SMSG_PLAYER_STAT_UPDATE_3: + case SMSG_PLAYER_STAT_UPDATE_3: // Update a base attribute { int type = msg.readInt32(); int base = msg.readInt32(); int bonus = msg.readInt32(); - int total = base + bonus; - switch (type) { - case 0x000d: player_node->mAttr[LocalPlayer::STR] = total; - break; - case 0x000e: player_node->mAttr[LocalPlayer::AGI] = total; - break; - case 0x000f: player_node->mAttr[LocalPlayer::VIT] = total; - break; - case 0x0010: player_node->mAttr[LocalPlayer::INT] = total; - break; - case 0x0011: player_node->mAttr[LocalPlayer::DEX] = total; - break; - case 0x0012: player_node->mAttr[LocalPlayer::LUK] = total; - break; - } + player_node->setAttributeBase(type, base); + player_node->setAttributeEffective(type, base + bonus); } break; - case SMSG_PLAYER_STAT_UPDATE_4: + case SMSG_PLAYER_STAT_UPDATE_4: // Attribute increase ack { int type = msg.readInt16(); int fail = msg.readInt8(); @@ -332,72 +354,105 @@ void PlayerHandler::handleMessage(MessageIn &msg) if (fail != 1) break; - switch (type) { - case 0x000d: player_node->mAttr[LocalPlayer::STR] = value; - break; - case 0x000e: player_node->mAttr[LocalPlayer::AGI] = value; - break; - case 0x000f: player_node->mAttr[LocalPlayer::VIT] = value; - break; - case 0x0010: player_node->mAttr[LocalPlayer::INT] = value; - break; - case 0x0011: player_node->mAttr[LocalPlayer::DEX] = value; - break; - case 0x0012: player_node->mAttr[LocalPlayer::LUK] = value; - break; - } + int bonus = ATTR_BONUS(type); + + player_node->setAttributeBase(type, value); + player_node->setAttributeEffective(type, value + bonus); } break; // 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->setCharacterPoints(msg.readInt16()); + + { + int val = msg.readInt8(); + player_node->setAttributeEffective(STR, val + ATTR_BONUS(STR)); + player_node->setAttributeBase(STR, val); + statusWindow->setPointsNeeded(STR, msg.readInt8()); + + val = msg.readInt8(); + player_node->setAttributeEffective(AGI, val + ATTR_BONUS(AGI)); + player_node->setAttributeBase(AGI, val); + statusWindow->setPointsNeeded(AGI, msg.readInt8()); + + val = msg.readInt8(); + player_node->setAttributeEffective(VIT, val + ATTR_BONUS(VIT)); + player_node->setAttributeBase(VIT, val); + statusWindow->setPointsNeeded(VIT, msg.readInt8()); + + val = msg.readInt8(); + player_node->setAttributeEffective(INT, val + ATTR_BONUS(INT)); + player_node->setAttributeBase(INT, val); + statusWindow->setPointsNeeded(INT, msg.readInt8()); + + val = msg.readInt8(); + player_node->setAttributeEffective(DEX, val + ATTR_BONUS(DEX)); + player_node->setAttributeBase(DEX, val); + statusWindow->setPointsNeeded(DEX, msg.readInt8()); + + val = msg.readInt8(); + player_node->setAttributeEffective(LUK, val + ATTR_BONUS(LUK)); + player_node->setAttributeBase(LUK, val); + statusWindow->setPointsNeeded(LUK, msg.readInt8()); + + val = msg.readInt16(); // ATK + player_node->setAttributeBase(ATK, val); + val += msg.readInt16(); // ATK bonus + player_node->setAttributeEffective(ATK, val); + + val = msg.readInt16(); // MATK + player_node->setAttributeBase(MATK, val); + val += msg.readInt16(); // MATK bonus + player_node->setAttributeEffective(MATK, val); + statusWindow->update(StatusWindow::MP); + + val = msg.readInt16(); // DEF + player_node->setAttributeBase(DEF, val); + val += msg.readInt16(); // DEF bonus + player_node->setAttributeEffective(DEF, val); + + val = msg.readInt16(); // MDEF + player_node->setAttributeBase(MDEF, val); + val += msg.readInt16(); // MDEF bonus + player_node->setAttributeEffective(MDEF, val); + + val = msg.readInt16(); // HIT + player_node->setAttributeBase(ATK, val); + player_node->setAttributeEffective(ATK, val); + + val = msg.readInt16(); // FLEE + player_node->setAttributeBase(FLEE, val); + val += msg.readInt16(); // FLEE bonus + player_node->setAttributeEffective(FLEE, val); + + val = msg.readInt16(); + player_node->setAttributeBase(CRIT, val); + player_node->setAttributeEffective(CRIT, val); + } + + msg.readInt16(); // manner break; case SMSG_PLAYER_STAT_UPDATE_6: switch (msg.readInt16()) { case 0x0020: - player_node->mAttrUp[LocalPlayer::STR] = msg.readInt8(); + statusWindow->setPointsNeeded(STR, msg.readInt8()); break; case 0x0021: - player_node->mAttrUp[LocalPlayer::AGI] = msg.readInt8(); + statusWindow->setPointsNeeded(AGI, msg.readInt8()); break; case 0x0022: - player_node->mAttrUp[LocalPlayer::VIT] = msg.readInt8(); + statusWindow->setPointsNeeded(VIT, msg.readInt8()); break; case 0x0023: - player_node->mAttrUp[LocalPlayer::INT] = msg.readInt8(); + statusWindow->setPointsNeeded(INT, msg.readInt8()); break; case 0x0024: - player_node->mAttrUp[LocalPlayer::DEX] = msg.readInt8(); + statusWindow->setPointsNeeded(DEX, msg.readInt8()); break; case 0x0025: - player_node->mAttrUp[LocalPlayer::LUK] = msg.readInt8(); + statusWindow->setPointsNeeded(LUK, msg.readInt8()); break; } break; @@ -433,44 +488,30 @@ void PlayerHandler::emote(int emoteId) outMsg.writeInt8(emoteId); } -void PlayerHandler::increaseStat(LocalPlayer::Attribute attr) +void PlayerHandler::increaseAttribute(size_t attr) { - MessageOut outMsg(CMSG_STAT_UPDATE_REQUEST); - - switch (attr) + if (attr >= STR && attr <= LUK) { - case LocalPlayer::STR: - outMsg.writeInt16(0x000d); - break; - - case LocalPlayer::AGI: - outMsg.writeInt16(0x000e); - break; - - case LocalPlayer::VIT: - outMsg.writeInt16(0x000f); - break; - - case LocalPlayer::INT: - outMsg.writeInt16(0x0010); - break; - - case LocalPlayer::DEX: - outMsg.writeInt16(0x0011); - break; - - case LocalPlayer::LUK: - outMsg.writeInt16(0x0012); - break; + MessageOut outMsg(CMSG_STAT_UPDATE_REQUEST); + outMsg.writeInt16(attr); + outMsg.writeInt8(1); } - outMsg.writeInt8(1); } -void PlayerHandler::decreaseStat(LocalPlayer::Attribute attr) +void PlayerHandler::decreaseAttribute(size_t attr) { // Supported by eA? } +void PlayerHandler::increaseSkill(int skillId) +{ + if (player_node->getSkillPoints() <= 0) + return; + + MessageOut outMsg(CMSG_SKILL_LEVELUP_REQUEST); + outMsg.writeInt16(skillId); +} + void PlayerHandler::pickUp(FloorItem *floorItem) { MessageOut outMsg(CMSG_ITEM_PICKUP); @@ -521,4 +562,9 @@ void PlayerHandler::ignoreAll(bool ignore) // TODO } +bool PlayerHandler::canUseMagic() +{ + return player_node->getAttributeEffective(MATK) > 0; +} + } // namespace EAthena diff --git a/src/net/ea/playerhandler.h b/src/net/ea/playerhandler.h index 5dbc171b..78e64a88 100644 --- a/src/net/ea/playerhandler.h +++ b/src/net/ea/playerhandler.h @@ -39,9 +39,11 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler void emote(int emoteId); - void increaseStat(LocalPlayer::Attribute attr); + void increaseAttribute(size_t attr); - void decreaseStat(LocalPlayer::Attribute attr); + void decreaseAttribute(size_t attr); + + void increaseSkill(int skillId); void pickUp(FloorItem *floorItem); @@ -56,6 +58,8 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler void ignorePlayer(const std::string &player, bool ignore); void ignoreAll(bool ignore); + + bool canUseMagic(); }; } // namespace EAthena diff --git a/src/net/ea/protocol.h b/src/net/ea/protocol.h index b3759946..279e4c2f 100644 --- a/src/net/ea/protocol.h +++ b/src/net/ea/protocol.h @@ -22,6 +22,25 @@ #ifndef EA_PROTOCOL_H #define EA_PROTOCOL_H +enum { + JOB = 0xa, + + STR = 0xd, + AGI, + VIT, + INT, + DEX, + LUK, + + ATK, + DEF, + MATK, + MDEF, + HIT, + FLEE, + CRIT +}; + static const int INVENTORY_OFFSET = 2; static const int STORAGE_OFFSET = 1; @@ -69,6 +88,7 @@ static const int STORAGE_OFFSET = 1; #define SMSG_PLAYER_ARROW_EQUIP 0x013c #define SMSG_PLAYER_ARROW_MESSAGE 0x013b #define SMSG_PLAYER_SKILLS 0x010f +#define SMSG_PLAYER_SKILL_UP 0x010e #define SMSG_SKILL_FAILED 0x0110 #define SMSG_ITEM_USE_RESPONSE 0x00a8 #define SMSG_ITEM_VISIBLE 0x009d /**< An item is on the floor */ @@ -160,6 +180,11 @@ static const int STORAGE_OFFSET = 1; #define CMSG_SKILL_LEVELUP_REQUEST 0x0112 #define CMSG_STAT_UPDATE_REQUEST 0x00bb +#define CMSG_SKILL_USE_BEING 0x0113 +#define CMSG_SKILL_USE_POSITION 0x0116 +// Variant of 0x116 with 80 char string at end (unsure of use) +#define CMSG_SKILL_USE_POSITION_MORE 0x0190 +#define CMSG_SKILL_USE_MAP 0x011b #define CMSG_PLAYER_INVENTORY_USE 0x00a7 #define CMSG_PLAYER_INVENTORY_DROP 0x00a2 diff --git a/src/net/ea/skillhandler.cpp b/src/net/ea/specialhandler.cpp index 69b0fd65..528f531e 100644 --- a/src/net/ea/skillhandler.cpp +++ b/src/net/ea/specialhandler.cpp @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "net/ea/skillhandler.h" +#include "net/ea/specialhandler.h" #include "net/ea/protocol.h" @@ -29,7 +29,7 @@ #include "localplayer.h" #include "log.h" -#include "gui/skill.h" +#include "gui/skilldialog.h" #include "gui/widgets/chattab.h" @@ -67,60 +67,68 @@ /** should always be zero if failed */ #define SKILL_FAILED 0x00 -Net::SkillHandler *skillHandler; +Net::SpecialHandler *specialHandler; namespace EAthena { -SkillHandler::SkillHandler() +SpecialHandler::SpecialHandler() { static const Uint16 _messages[] = { SMSG_PLAYER_SKILLS, SMSG_SKILL_FAILED, + SMSG_PLAYER_SKILL_UP, 0 }; handledMessages = _messages; - skillHandler = this; + specialHandler = this; } -void SkillHandler::handleMessage(MessageIn &msg) +void SpecialHandler::handleMessage(MessageIn &msg) { int skillCount; + int skillId; 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(); + skillId = msg.readInt16(); msg.readInt16(); // target type - msg.readInt16(); // unknown + msg.skip(2); // unused int level = msg.readInt16(); - int sp = msg.readInt16(); - msg.readInt16(); // range - std::string skillName = msg.readString(24); + msg.readInt16(); // sp + msg.readInt16(); // range + msg.skip(24); // unused int up = msg.readInt8(); - if (level != 0 || up != 0) - { - if (skillDialog->hasSkill(skillId)) { - skillDialog->setSkill(skillId, level, sp); - } - else { - skillDialog->addSkill(skillId, level, sp); - } - } + player_node->setAttributeBase(skillId, level); + player_node->setAttributeEffective(skillId, level); + skillDialog->setModifiable(skillId, up); + } + break; + + case SMSG_PLAYER_SKILL_UP: + { + skillId = msg.readInt16(); + int level = msg.readInt16(); + msg.readInt16(); // sp + msg.readInt16(); // range + int up = msg.readInt8(); + + player_node->setAttributeBase(skillId, level); + player_node->setAttributeEffective(skillId, level); + skillDialog->setModifiable(skillId, up); } - skillDialog->update(); break; case SMSG_SKILL_FAILED: // Action failed (ex. sit because you have not reached the // right level) - short skill = msg.readInt16(); + skillId = msg.readInt16(); short bskill = msg.readInt16(); msg.readInt16(); // unknown char success = msg.readInt8(); @@ -131,7 +139,7 @@ void SkillHandler::handleMessage(MessageIn &msg) } std::string msg; - if (success == SKILL_FAILED && skill == SKILL_BASIC) + if (success == SKILL_FAILED && skillId == SKILL_BASIC) { switch (bskill) { @@ -196,7 +204,7 @@ void SkillHandler::handleMessage(MessageIn &msg) } else { - switch (skill) + switch (skillId) { case SKILL_WARP : msg = _("Warp failed..."); @@ -215,28 +223,33 @@ void SkillHandler::handleMessage(MessageIn &msg) } } -void SkillHandler::up(int skillId) +void SpecialHandler::use(int id) { - if (player_node->mSkillPoint <= 0) - return; - - MessageOut outMsg(CMSG_SKILL_LEVELUP_REQUEST); - outMsg.writeInt16(skillId); + // TODO } -void SkillHandler::use(int skillId, int level, int beingId) +void SpecialHandler::use(int id, int level, int beingId) { - // TODO + MessageOut outMsg(CMSG_SKILL_USE_BEING); + outMsg.writeInt16(level); + outMsg.writeInt16(id); + outMsg.writeInt16(beingId); } -void SkillHandler::use(int skillId, int level, int x, int y) +void SpecialHandler::use(int id, int level, int x, int y) { - // TODO + MessageOut outMsg(CMSG_SKILL_USE_POSITION); + outMsg.writeInt16(level); + outMsg.writeInt16(id); + outMsg.writeInt16(x); + outMsg.writeInt16(y); } -void SkillHandler::use(int skillId, const std::string &map) +void SpecialHandler::use(int id, const std::string &map) { - // TODO + MessageOut outMsg(CMSG_SKILL_USE_MAP); + outMsg.writeInt16(id); + outMsg.writeString(map, 16); } } // namespace EAthena diff --git a/src/net/ea/skillhandler.h b/src/net/ea/specialhandler.h index c1965213..eac53569 100644 --- a/src/net/ea/skillhandler.h +++ b/src/net/ea/specialhandler.h @@ -24,24 +24,24 @@ #include "net/messagehandler.h" #include "net/net.h" -#include "net/skillhandler.h" +#include "net/specialhandler.h" namespace EAthena { -class SkillHandler : public MessageHandler, public Net::SkillHandler +class SpecialHandler : public MessageHandler, public Net::SpecialHandler { public: - SkillHandler(); + SpecialHandler(); void handleMessage(MessageIn &msg); - void up(int skillId); + void use(int id); - void use(int skillId, int level, int beingId); + void use(int id, int level, int beingId); - void use(int skillId, int level, int x, int y); + void use(int id, int level, int x, int y); - void use(int skillId, const std::string &map); + void use(int id, const std::string &map); }; } // namespace EAthena diff --git a/src/net/net.cpp b/src/net/net.cpp index a329af1a..7df336c6 100644 --- a/src/net/net.cpp +++ b/src/net/net.cpp @@ -33,7 +33,7 @@ #include "net/npchandler.h" #include "net/partyhandler.h" #include "net/playerhandler.h" -#include "net/skillhandler.h" +#include "net/specialhandler.h" #include "net/tradehandler.h" extern Net::AdminHandler *adminHandler; @@ -47,7 +47,7 @@ extern Net::MapHandler *mapHandler; extern Net::NpcHandler *npcHandler; extern Net::PartyHandler *partyHandler; extern Net::PlayerHandler *playerHandler; -extern Net::SkillHandler *skillHandler; +extern Net::SpecialHandler *specialHandler; extern Net::TradeHandler *tradeHandler; Net::AdminHandler *Net::getAdminHandler() @@ -111,9 +111,9 @@ Net::PlayerHandler *Net::getPlayerHandler() return playerHandler; } -Net::SkillHandler *Net::getSkillHandler() +Net::SpecialHandler *Net::getSpecialHandler() { - return skillHandler; + return specialHandler; } Net::TradeHandler *Net::getTradeHandler() diff --git a/src/net/net.h b/src/net/net.h index 9154c1ef..1d91faa7 100644 --- a/src/net/net.h +++ b/src/net/net.h @@ -36,7 +36,7 @@ class MapHandler; class NpcHandler; class PartyHandler; class PlayerHandler; -class SkillHandler; +class SpecialHandler; class TradeHandler; AdminHandler *getAdminHandler(); @@ -51,7 +51,7 @@ MapHandler *getMapHandler(); NpcHandler *getNpcHandler(); PartyHandler *getPartyHandler(); PlayerHandler *getPlayerHandler(); -SkillHandler *getSkillHandler(); +SpecialHandler *getSpecialHandler(); TradeHandler *getTradeHandler(); } // namespace Net diff --git a/src/net/playerhandler.h b/src/net/playerhandler.h index 163b48f3..a0fd8bac 100644 --- a/src/net/playerhandler.h +++ b/src/net/playerhandler.h @@ -35,9 +35,11 @@ class PlayerHandler virtual void emote(int emoteId) = 0; - virtual void increaseStat(LocalPlayer::Attribute attr) = 0; + virtual void increaseAttribute(size_t attr) = 0; - virtual void decreaseStat(LocalPlayer::Attribute attr) = 0; + virtual void decreaseAttribute(size_t attr) = 0; + + virtual void increaseSkill(int skillId) = 0; virtual void pickUp(FloorItem *floorItem) = 0; @@ -52,6 +54,8 @@ class PlayerHandler virtual void ignorePlayer(const std::string &player, bool ignore) = 0; virtual void ignoreAll(bool ignore) = 0; + + virtual bool canUseMagic() = 0; }; } // namespace Net diff --git a/src/net/skillhandler.h b/src/net/specialhandler.h index 9db6ac5b..602003aa 100644 --- a/src/net/skillhandler.h +++ b/src/net/specialhandler.h @@ -19,23 +19,23 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef SKILLHANDLER_H -#define SKILLHANDLER_H +#ifndef SPECIALHANDLER_H +#define SPECIALHANDLER_H #include <iosfwd> namespace Net { -class SkillHandler +class SpecialHandler { public: - virtual void up(int skillId) = 0; + virtual void use(int id) = 0; - virtual void use(int skillId, int level, int beingId) = 0; + virtual void use(int id, int level, int beingId) = 0; - virtual void use(int skillId, int level, int x, int y) = 0; + virtual void use(int id, int level, int x, int y) = 0; - virtual void use(int skillId, const std::string &map) = 0; + virtual void use(int id, const std::string &map) = 0; }; } -#endif // SKILLHANDLER_H +#endif // SPECIALHANDLER_H diff --git a/src/net/tmwserv/beinghandler.cpp b/src/net/tmwserv/beinghandler.cpp index 7076ff8e..acd6b62c 100644 --- a/src/net/tmwserv/beinghandler.cpp +++ b/src/net/tmwserv/beinghandler.cpp @@ -187,28 +187,14 @@ void BeingHandler::handleBeingsMoveMessage(MessageIn &msg) Being *being = beingManager->findBeing(id); int sx = 0; int sy = 0; - int dx = 0; - int dy = 0; int speed = 0; if (flags & MOVING_POSITION) { - Uint16 sx2, sy2; - msg.readCoordinates(sx2, sy2); - sx = sx2 * 32 + 16; - sy = sy2 * 32 + 16; + sx = msg.readInt16(); + sy = msg.readInt16(); 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; @@ -228,33 +214,9 @@ void BeingHandler::handleBeingsMoveMessage(MessageIn &msg) 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) < 16 && - (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 + if (flags & MOVING_POSITION) { - being->setDestination(sx, sy, dx, dy); + being->setDestination(sx, sy); } } } @@ -306,23 +268,27 @@ void BeingHandler::handleBeingActionChangeMessage(MessageIn &msg) static char const *const deadMsg[] = { _("You are dead."), - _("We regret to inform you that your character was killed in battle."), + _("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."), + _("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 + _("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); + message.append(std::string(" ") + _("Press OK to respawn.")); + OkDialog *dlg = new OkDialog(_("You Died"), message); dlg->addActionListener(&(Net::GameServer::Player::respawnListener)); } } diff --git a/src/net/tmwserv/charserverhandler.cpp b/src/net/tmwserv/charserverhandler.cpp index 7b74904f..0146babb 100644 --- a/src/net/tmwserv/charserverhandler.cpp +++ b/src/net/tmwserv/charserverhandler.cpp @@ -81,25 +81,25 @@ void CharServerHandler::handleMessage(MessageIn &msg) delete mCharInfo->getEntry(); mCharInfo->setEntry(0); mCharInfo->unlock(); - new OkDialog("Info", "Player deleted"); + new OkDialog(_("Info"), _("Player deleted.")); } // Character deletion failed else { - std::string message = ""; + std::string errorMessage = ""; switch (errMsg) { case ERRMSG_NO_LOGIN: - message = "Not logged in"; + errorMessage = _("Not logged in."); break; case ERRMSG_INVALID_ARGUMENT: - message = "Selection out of range"; + errorMessage = _("Selection out of range."); break; default: - message = "Unknown error"; + errorMessage = _("Unknown error."); } mCharInfo->unlock(); - new OkDialog("Error", message); + new OkDialog(_("Error"), errorMessage); } } break; @@ -131,44 +131,44 @@ void CharServerHandler::handleCharCreateResponse(MessageIn &msg) // Character creation failed if (errMsg != ERRMSG_OK) { - std::string message = ""; + std::string errorMessage = ""; switch (errMsg) { case ERRMSG_NO_LOGIN: - message = "Not logged in"; + errorMessage = _("Not logged in."); break; case CREATE_TOO_MUCH_CHARACTERS: - message = "No empty slot"; + errorMessage = _("No empty slot."); break; case ERRMSG_INVALID_ARGUMENT: - message = "Invalid name"; + errorMessage = _("Invalid name."); break; case CREATE_EXISTS_NAME: - message = "Character's name already exists"; + errorMessage = _("Character's name already exists."); break; case CREATE_INVALID_HAIRSTYLE: - message = "Invalid hairstyle"; + errorMessage = _("Invalid hairstyle."); break; case CREATE_INVALID_HAIRCOLOR: - message = "Invalid hair color"; + errorMessage = _("Invalid hair color."); break; case CREATE_INVALID_GENDER: - message = "Invalid gender"; + errorMessage = _("Invalid gender."); break; case CREATE_RAW_STATS_TOO_HIGH: - message = "Character's stats are too high"; + errorMessage = _("Character's stats are too high."); break; case CREATE_RAW_STATS_TOO_LOW: - message = "Character's stats are too low"; + errorMessage = _("Character's stats are too low."); break; case CREATE_RAW_STATS_EQUAL_TO_ZERO: - message = "One stat is zero"; + errorMessage = _("One stat is zero."); break; default: - message = "Unknown error"; + errorMessage = _("Unknown error."); break; } - new OkDialog("Error", message); + new OkDialog(_("Error"), errorMessage); } if (mCharCreateDialog) diff --git a/src/net/tmwserv/chathandler.cpp b/src/net/tmwserv/chathandler.cpp index e2d09534..ad3ae49b 100644 --- a/src/net/tmwserv/chathandler.cpp +++ b/src/net/tmwserv/chathandler.cpp @@ -159,7 +159,7 @@ void ChatHandler::handleEnterChannelResponse(MessageIn &msg) std::string user; std::string userModes; - tab->chatLog("Players in this channel:", BY_CHANNEL); + tab->chatLog(_("Players in this channel:"), BY_CHANNEL); while(msg.getUnreadLength()) { user = msg.readString(); @@ -176,13 +176,13 @@ void ChatHandler::handleEnterChannelResponse(MessageIn &msg) } else { - localChatTab->chatLog("Error joining channel.", BY_SERVER); + localChatTab->chatLog(_("Error joining channel."), BY_SERVER); } } void ChatHandler::handleListChannelsResponse(MessageIn &msg) { - localChatTab->chatLog("Listing channels", BY_SERVER); + localChatTab->chatLog(_("Listing channels."), BY_SERVER); while(msg.getUnreadLength()) { std::string channelName = msg.readString(); @@ -194,7 +194,7 @@ void ChatHandler::handleListChannelsResponse(MessageIn &msg) channelName += numUsers.str(); localChatTab->chatLog(channelName, BY_SERVER); } - localChatTab->chatLog("End of channel list.", BY_SERVER); + localChatTab->chatLog(_("End of channel list."), BY_SERVER); } void ChatHandler::handlePrivateMessage(MessageIn &msg) @@ -237,7 +237,7 @@ void ChatHandler::handleListChannelUsersResponse(MessageIn &msg) std::string userNick; std::string userModes; Channel *channel = channelManager->findByName(channelName); - channel->getTab()->chatLog("Players in this channel:", BY_CHANNEL); + channel->getTab()->chatLog(_("Players in this channel:"), BY_CHANNEL); while(msg.getUnreadLength()) { userNick = msg.readString(); @@ -266,15 +266,18 @@ void ChatHandler::handleChannelEvent(MessageIn &msg) switch(eventId) { case CHAT_EVENT_NEW_PLAYER: - line += " entered the channel."; + channel->getTab()->chatLog(strprintf(_("%s entered the " + "channel."), line.c_str()), BY_CHANNEL); break; case CHAT_EVENT_LEAVING_PLAYER: - line += " left the channel."; + channel->getTab()->chatLog(strprintf(_("%s left the channel."), + line.c_str()), BY_CHANNEL); break; case CHAT_EVENT_TOPIC_CHANGE: - line = "Topic: " + line; + channel->getTab()->chatLog(strprintf(_("Topic: %s"), + line.c_str()), BY_CHANNEL); break; case CHAT_EVENT_MODE_CHANGE: @@ -284,7 +287,9 @@ void ChatHandler::handleChannelEvent(MessageIn &msg) 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; + channel->getTab()->chatLog(strprintf(_("%s has set mode %s " + "on user %s."), user1.c_str(), mode.c_str(), + user2.c_str()), BY_CHANNEL); } break; case CHAT_EVENT_KICKED_PLAYER: @@ -292,14 +297,14 @@ void ChatHandler::handleChannelEvent(MessageIn &msg) 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; + channel->getTab()->chatLog(strprintf(_("%s has kicked %s."), + user1, user2), BY_CHANNEL); } break; default: - line = "Unknown channel event."; + channel->getTab()->chatLog(_("Unknown channel event."), + BY_CHANNEL); } - - channel->getTab()->chatLog(line, BY_CHANNEL); } } diff --git a/src/net/tmwserv/gameserver/player.cpp b/src/net/tmwserv/gameserver/player.cpp index 93853681..4e63930b 100644 --- a/src/net/tmwserv/gameserver/player.cpp +++ b/src/net/tmwserv/gameserver/player.cpp @@ -41,14 +41,6 @@ void Net::GameServer::Player::walk(int x, int 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); @@ -58,47 +50,6 @@ void Net::GameServer::Player::moveItem(int oldSlot, int newSlot, int amount) 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::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_REQUEST : PGMSG_TRADE_CANCEL); - 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::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); diff --git a/src/net/tmwserv/gameserver/player.h b/src/net/tmwserv/gameserver/player.h index 24b25dc7..9a202c6e 100644 --- a/src/net/tmwserv/gameserver/player.h +++ b/src/net/tmwserv/gameserver/player.h @@ -41,14 +41,7 @@ namespace Net namespace Player { void walk(int x, int y); - void pickUp(int x, int y); void moveItem(int oldSlot, int newSlot, int amount); - void useSpecial(int special); - void requestTrade(int id); - void acceptTrade(bool accept); - void tradeMoney(int amount); - void raiseAttribute(int attribute); - void lowerAttribute(int attribute); void respawn(); static RespawnRequestListener respawnListener; } diff --git a/src/net/tmwserv/generalhandler.cpp b/src/net/tmwserv/generalhandler.cpp index 5886aafb..d643586b 100644 --- a/src/net/tmwserv/generalhandler.cpp +++ b/src/net/tmwserv/generalhandler.cpp @@ -21,6 +21,8 @@ #include "gui/inventorywindow.h" #include "gui/partywindow.h" +#include "gui/skilldialog.h" +#include "gui/statuswindow.h" #include "net/tmwserv/generalhandler.h" @@ -146,6 +148,16 @@ void GeneralHandler::guiWindowsLoaded() { inventoryWindow->setSplitAllowed(true); partyWindow->clearPartyName(); + skillDialog->loadSkills("tmw-skills.xml"); + + player_node->setExpNeeded(100); + + statusWindow->addAttribute(16, _("Strength"), true); + statusWindow->addAttribute(17, _("Agility"), true); + statusWindow->addAttribute(18, _("Dexterity"), true); + statusWindow->addAttribute(19, _("Vitality"), true); + statusWindow->addAttribute(20, _("Intelligence"), true); + statusWindow->addAttribute(21, _("Willpower"), true); } void GeneralHandler::guiWindowsUnloaded() diff --git a/src/net/tmwserv/loginhandler.cpp b/src/net/tmwserv/loginhandler.cpp index 35739669..f728d831 100644 --- a/src/net/tmwserv/loginhandler.cpp +++ b/src/net/tmwserv/loginhandler.cpp @@ -77,16 +77,16 @@ void LoginHandler::handleMessage(MessageIn &msg) { switch (errMsg) { case ERRMSG_INVALID_ARGUMENT: - errorMessage = _("Wrong magic_token"); + errorMessage = _("Wrong magic_token."); break; case ERRMSG_FAILURE: - errorMessage = _("Already logged in"); + errorMessage = _("Already logged in."); break; case LOGIN_SERVER_FULL: - errorMessage = _("Server is full"); + errorMessage = _("Server is full."); break; default: - errorMessage = _("Unknown error"); + errorMessage = _("Unknown error."); break; } state = STATE_ERROR; @@ -107,16 +107,16 @@ void LoginHandler::handleMessage(MessageIn &msg) { switch (errMsg) { case ERRMSG_INVALID_ARGUMENT: - errorMessage = _("New password incorrect"); + errorMessage = _("New password incorrect."); break; case ERRMSG_FAILURE: - errorMessage = _("Old password incorrect"); + errorMessage = _("Old password incorrect."); break; case ERRMSG_NO_LOGIN: errorMessage = _("Account not connected. Please login first."); break; default: - errorMessage = _("Unknown error"); + errorMessage = _("Unknown error."); break; } state = STATE_ACCOUNTCHANGE_ERROR; @@ -137,19 +137,19 @@ void LoginHandler::handleMessage(MessageIn &msg) { switch (errMsg) { case ERRMSG_INVALID_ARGUMENT: - errorMessage = _("New email address incorrect"); + errorMessage = _("New email address incorrect."); break; case ERRMSG_FAILURE: - errorMessage = _("Old email address incorrect"); + 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."); + errorMessage = _("The new email address already exists."); break; default: - errorMessage = _("Unknown error"); + errorMessage = _("Unknown error."); break; } state = STATE_ACCOUNTCHANGE_ERROR; @@ -173,19 +173,19 @@ void LoginHandler::handleLoginResponse(MessageIn &msg) { switch (errMsg) { case LOGIN_INVALID_VERSION: - errorMessage = _("Client version is too old"); + errorMessage = _("Client version is too old."); break; case ERRMSG_INVALID_ARGUMENT: - errorMessage = _("Wrong username or password"); + errorMessage = _("Wrong username or password."); break; case ERRMSG_FAILURE: - errorMessage = _("Already logged in"); + errorMessage = _("Already logged in."); break; case LOGIN_SERVER_FULL: - errorMessage = _("Server is full"); + errorMessage = _("Server is full."); break; default: - errorMessage = _("Unknown error"); + errorMessage = _("Unknown error."); break; } state = STATE_LOGIN_ERROR; @@ -205,19 +205,19 @@ void LoginHandler::handleRegisterResponse(MessageIn &msg) { switch (errMsg) { case REGISTER_INVALID_VERSION: - errorMessage = _("Client version is too old"); + errorMessage = _("Client version is too old."); break; case ERRMSG_INVALID_ARGUMENT: - errorMessage = _("Wrong username, password or email address"); + errorMessage = _("Wrong username, password or email address."); break; case REGISTER_EXISTS_USERNAME: - errorMessage = _("Username already exists"); + errorMessage = _("Username already exists."); break; case REGISTER_EXISTS_EMAIL: - errorMessage = _("Email address already exists"); + errorMessage = _("Email address already exists."); break; default: - errorMessage = _("Unknown error"); + errorMessage = _("Unknown error."); break; } state = STATE_LOGIN_ERROR; diff --git a/src/net/tmwserv/partyhandler.cpp b/src/net/tmwserv/partyhandler.cpp index 557a3a43..2af0e4cb 100644 --- a/src/net/tmwserv/partyhandler.cpp +++ b/src/net/tmwserv/partyhandler.cpp @@ -100,8 +100,8 @@ void PartyHandler::handleMessage(MessageIn &msg) int id = msg.readInt16(); // being id std::string name = msg.readString(); - localChatTab->chatLog(strprintf(_("%s joined the " - "party."), name.c_str())); + localChatTab->chatLog(strprintf(_("%s joined the party.", + name.c_str())); if (!player_node->isInParty()) player_node->setInParty(true); @@ -117,7 +117,8 @@ void PartyHandler::handleMessage(MessageIn &msg) case CPMSG_PARTY_REJECTED: { std::string name = msg.readString(); - localChatTab->chatLog(name + "rejected your invite."); + localChatTab->chatLog(strprintf(_("%s rejected your invite."), + name.c_str())); } break; } } diff --git a/src/net/tmwserv/playerhandler.cpp b/src/net/tmwserv/playerhandler.cpp index bbc73b7c..ce1990ed 100644 --- a/src/net/tmwserv/playerhandler.cpp +++ b/src/net/tmwserv/playerhandler.cpp @@ -43,7 +43,6 @@ #include "gui/gui.h" #include "gui/okdialog.h" #include "gui/sell.h" -#include "gui/skill.h" #include "gui/viewport.h" // TODO Move somewhere else @@ -134,7 +133,7 @@ void PlayerHandler::handleMessage(MessageIn &msg) logger->log("ATTRIBUTE UPDATE:"); while (msg.getUnreadLength()) { - int stat = msg.readInt8(); + int stat = msg.readInt16(); int base = msg.readInt16(); int value = msg.readInt16(); logger->log("%d set to %d %d", stat, base, value); @@ -144,24 +143,11 @@ void PlayerHandler::handleMessage(MessageIn &msg) player_node->setMaxHp(base); player_node->setHp(value); } - else if (stat < NB_CHARACTER_ATTRIBUTES) + else { - 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; @@ -174,15 +160,7 @@ void PlayerHandler::handleMessage(MessageIn &msg) 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); - } + player_node->setExperience(skill, current, next); } } break; @@ -199,7 +177,7 @@ void PlayerHandler::handleMessage(MessageIn &msg) case GPMSG_LEVEL_PROGRESS: { logger->log("Level Progress Update"); - player_node->setLevelProgress(msg.readInt8()); + player_node->setExp(msg.readInt8()); } break; @@ -358,20 +336,32 @@ void PlayerHandler::emote(int emoteId) // TODO } -void PlayerHandler::increaseStat(LocalPlayer::Attribute attr) +void PlayerHandler::increaseAttribute(size_t attr) { - // TODO + MessageOut msg(PGMSG_RAISE_ATTRIBUTE); + msg.writeInt8(attr); + Net::GameServer::connection->send(msg); } -void PlayerHandler::decreaseStat(LocalPlayer::Attribute attr) +void PlayerHandler::decreaseAttribute(size_t attr) { - // TODO + MessageOut msg(PGMSG_LOWER_ATTRIBUTE); + msg.writeInt8(attr); + Net::GameServer::connection->send(msg); +} + +void PlayerHandler::increaseSkill(int skillId) +{ + // Not used atm } void PlayerHandler::pickUp(FloorItem *floorItem) { int id = floorItem->getId(); - Net::GameServer::Player::pickUp(id >> 16, id & 0xFFFF); + MessageOut msg(PGMSG_PICKUP); + msg.writeInt16(id >> 16); + msg.writeInt16(id & 0xFFFF); + Net::GameServer::connection->send(msg); } void PlayerHandler::setDirection(char direction) @@ -414,4 +404,9 @@ void PlayerHandler::ignoreAll(bool ignore) // TODO } +bool PlayerHandler::canUseMagic() +{ + return true; +} + } // namespace TmwServ diff --git a/src/net/tmwserv/playerhandler.h b/src/net/tmwserv/playerhandler.h index 164d30ae..287baa3d 100644 --- a/src/net/tmwserv/playerhandler.h +++ b/src/net/tmwserv/playerhandler.h @@ -38,9 +38,11 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler void emote(int emoteId); - void increaseStat(LocalPlayer::Attribute attr); + void increaseAttribute(size_t attr); - void decreaseStat(LocalPlayer::Attribute attr); + void decreaseAttribute(size_t attr); + + void increaseSkill(int skillId); void pickUp(FloorItem *floorItem); @@ -56,6 +58,8 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler void ignoreAll(bool ignore); + bool canUseMagic(); + private: void handleMapChangeMessage(MessageIn &msg); }; diff --git a/src/net/tmwserv/protocol.h b/src/net/tmwserv/protocol.h index 2f1ea885..60a50d89 100644 --- a/src/net/tmwserv/protocol.h +++ b/src/net/tmwserv/protocol.h @@ -83,7 +83,7 @@ enum { 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_ATTRIBUTE_CHANGE = 0x0130, // { W attribute, W base value, W modified value }* GPMSG_PLAYER_EXP_CHANGE = 0x0140, // { W skill, D exp got, D exp needed }* GPMSG_LEVELUP = 0x0150, // W new level GPMSG_LEVEL_PROGRESS = 0x0151, // B percent completed to next levelup @@ -104,7 +104,7 @@ enum { 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_BEINGS_MOVE = 0x0280, // { W being id, B flags [, W*2 position, B speed] }* GPMSG_ITEMS = 0x0281, // { W item id, W*2 position }* PGMSG_ATTACK = 0x0290, // W being id GPMSG_BEING_ATTACK = 0x0291, // W being id diff --git a/src/net/tmwserv/skillhandler.cpp b/src/net/tmwserv/specialhandler.cpp index e35b896a..f259e77a 100644 --- a/src/net/tmwserv/skillhandler.cpp +++ b/src/net/tmwserv/specialhandler.cpp @@ -19,33 +19,42 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "net/tmwserv/skillhandler.h" +#include "net/tmwserv/specialhandler.h" -Net::SkillHandler *skillHandler; +#include "net/tmwserv/gameserver/internal.h" + +#include "net/tmwserv/connection.h" +#include "net/tmwserv/protocol.h" + +#include "net/messageout.h" + +Net::SpecialHandler *specialHandler; namespace TmwServ { -SkillHandler::SkillHandler() +SpecialHandler::SpecialHandler() { - skillHandler = this; + specialHandler = this; } -void SkillHandler::up(int skillId) +void SpecialHandler::use(int id) { - // TODO + MessageOut msg(PGMSG_USE_SPECIAL); + msg.writeInt8(id); + Net::GameServer::connection->send(msg); } -void SkillHandler::use(int skillId, int level, int beingId) +void SpecialHandler::use(int id, int level, int beingId) { // TODO } -void SkillHandler::use(int skillId, int level, int x, int y) +void SpecialHandler::use(int id, int level, int x, int y) { // TODO } -void SkillHandler::use(int skillId, const std::string &map) +void SpecialHandler::use(int id, const std::string &map) { // TODO } diff --git a/src/net/tmwserv/skillhandler.h b/src/net/tmwserv/specialhandler.h index 8c459c4f..c7ebd6a2 100644 --- a/src/net/tmwserv/skillhandler.h +++ b/src/net/tmwserv/specialhandler.h @@ -22,22 +22,22 @@ #ifndef NET_TMWSERV_SKILLHANDLER_H #define NET_TMWSERV_SKILLHANDLER_H -#include "net/skillhandler.h" +#include "net/specialhandler.h" namespace TmwServ { -class SkillHandler : public Net::SkillHandler +class SpecialHandler : public Net::SpecialHandler { public: - SkillHandler(); + SpecialHandler(); - void up(int skillId); + void use(int id); - void use(int skillId, int level, int beingId); + void use(int id, int level, int beingId); - void use(int skillId, int level, int x, int y); + void use(int id, int level, int x, int y); - void use(int skillId, const std::string &map); + void use(int id, const std::string &map); }; } // namespace TmwServ diff --git a/src/net/tmwserv/tradehandler.cpp b/src/net/tmwserv/tradehandler.cpp index aabd8b2a..55a00d4c 100644 --- a/src/net/tmwserv/tradehandler.cpp +++ b/src/net/tmwserv/tradehandler.cpp @@ -55,7 +55,11 @@ namespace { void action(const gcn::ActionEvent &event) { if (event.getId() == "yes") - Net::GameServer::Player::requestTrade(tradePartnerID); + { + MessageOut msg(PGMSG_TRADE_REQUEST); + msg.writeInt16(tradePartnerID); + Net::GameServer::connection->send(msg); + } else Net::getTradeHandler()->cancel(); } @@ -105,7 +109,7 @@ void TradeHandler::handleMessage(MessageIn &msg) Being *being = beingManager->findBeing(msg.readInt16()); if (!being || !mAcceptTradeRequests) { - Net::GameServer::Player::acceptTrade(false); + respond(false); break; } player_node->setTrading(true); @@ -171,7 +175,9 @@ void TradeHandler::request(Being *being) void TradeHandler::respond(bool accept) { - // TODO + MessageOut msg(accept ? PGMSG_TRADE_REQUEST : PGMSG_TRADE_CANCEL); + Net::GameServer::connection->send(msg); + if (!accept) player_node->setTrading(false); } diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp index b9d837ad..4d66a919 100644 --- a/src/openglgraphics.cpp +++ b/src/openglgraphics.cpp @@ -140,6 +140,42 @@ static inline void drawQuad(Image *image, } } +static inline void drawRescaledQuad(Image *image, + int srcX, int srcY, int dstX, int dstY, + int width, int height, + int desiredWidth, int desiredHeight) +{ + if (image->getTextureType() == GL_TEXTURE_2D) + { + // Find OpenGL normalized texture coordinates. + float texX1 = srcX / (float) image->getTextureWidth(); + float texY1 = srcY / (float) image->getTextureHeight(); + float texX2 = (srcX + width) / (float) image->getTextureWidth(); + float texY2 = (srcY + height) / (float) image->getTextureHeight(); + + glTexCoord2f(texX1, texY1); + glVertex2i(dstX, dstY); + glTexCoord2f(texX2, texY1); + glVertex2i(dstX + desiredWidth, dstY); + glTexCoord2f(texX2, texY2); + glVertex2i(dstX + desiredWidth, dstY + desiredHeight); + glTexCoord2f(texX1, texY2); + glVertex2i(dstX, dstY + desiredHeight); + } + else + { + glTexCoord2i(srcX, srcY); + glVertex2i(dstX, dstY); + glTexCoord2i(srcX + width, srcY); + glVertex2i(dstX + desiredWidth, dstY); + glTexCoord2i(srcX + width, srcY + height); + glVertex2i(dstX + desiredWidth, dstY + desiredHeight); + glTexCoord2i(srcX, srcY + height); + glVertex2i(dstX, dstY + desiredHeight); + } +} + + bool OpenGLGraphics::drawImage(Image *image, int srcX, int srcY, int dstX, int dstY, int width, int height, bool useColor) @@ -168,6 +204,37 @@ bool OpenGLGraphics::drawImage(Image *image, int srcX, int srcY, return true; } +bool OpenGLGraphics::drawRescaledImage(Image *image, int srcX, int srcY, + int dstX, int dstY, + int width, int height, + int desiredWidth, int desiredHeight, + bool useColor) +{ + if (!image) + return false; + + srcX += image->mBounds.x; + srcY += image->mBounds.y; + + if (!useColor) + glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha); + + glBindTexture(Image::mTextureType, image->mGLImage); + + setTexturingAndBlending(true); + + // Draw a textured quad. + glBegin(GL_QUADS); + drawRescaledQuad(image, srcX, srcY, dstX, dstY, width, height, + desiredWidth, desiredHeight); + glEnd(); + + if (!useColor) + glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a); + + return true; +} + /* Optimising the functions that Graphics::drawImagePattern would call, * so that glBegin...glEnd are outside the main loop. */ void OpenGLGraphics::drawImagePattern(Image *image, int x, int y, int w, int h) @@ -210,6 +277,49 @@ void OpenGLGraphics::drawImagePattern(Image *image, int x, int y, int w, int h) glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a); } +void OpenGLGraphics::drawRescaledImagePattern(Image *image, int x, int y, + int w, int h, + int scaledWidth, int scaledHeight) +{ + if (!image) + return; + + const int srcX = image->mBounds.x; + const int srcY = image->mBounds.y; + + const int iw = scaledWidth; + const int ih = scaledHeight; + if (iw == 0 || ih == 0) + return; + + glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha); + + glBindTexture(Image::mTextureType, image->mGLImage); + + setTexturingAndBlending(true); + + // Draw a set of textured rectangles + glBegin(GL_QUADS); + + for (int py = 0; py < h; py += ih) + { + const int height = (py + ih >= h) ? h - py : ih; + const int dstY = y + py; + for (int px = 0; px < w; px += iw) + { + int width = (px + iw >= w) ? w - px : iw; + int dstX = x + px; + + drawRescaledQuad(image, srcX, srcY, dstX, dstY, + width, height, scaledWidth, scaledHeight); + } + } + + glEnd(); + + glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a); +} + void OpenGLGraphics::updateScreen() { glFlush(); diff --git a/src/openglgraphics.h b/src/openglgraphics.h index dc748804..0bee48b4 100644 --- a/src/openglgraphics.h +++ b/src/openglgraphics.h @@ -46,10 +46,26 @@ class OpenGLGraphics : public Graphics int width, int height, bool useColor); + /** + * Draws a resclaled version of the image + */ + bool drawRescaledImage(Image *image, int srcX, int srcY, + int dstX, int dstY, + int width, int height, + int desiredWidth, int desiredHeight, + bool useColor); + void drawImagePattern(Image *image, int x, int y, int w, int h); + /** + * Draw a pattern based on a rescaled version of the given image... + */ + void drawRescaledImagePattern(Image *image, + int x, int y, int w, int h, + int scaledWidth, int scaledHeight); + void updateScreen(); void _beginDraw(); diff --git a/src/player.cpp b/src/player.cpp index 3b2271bd..fd7cd0d6 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -255,21 +255,6 @@ void Player::updateCoords() } #ifdef TMWSERV_SUPPORT - -Path Player::findPath() -{ - Path path; - - if (mMap) - { - path = mMap->findSimplePath(getPosition().x / 32, getPosition().y / 32, - getDestination().x / 32, getDestination().y / 32, - getWalkMask()); - } - - return path; -} - Guild* Player::addGuild(short guildId, short rights) { Guild *guild = new Guild(guildId, rights); diff --git a/src/player.h b/src/player.h index cfd305a6..9a5c6c94 100644 --- a/src/player.h +++ b/src/player.h @@ -93,11 +93,6 @@ class Player : public Being #ifdef TMWSERV_SUPPORT /** - * Returns the path to the player's current destination - */ - Path findPath(); - - /** * Adds a guild to the player. */ Guild *addGuild(short guildId, short rights); diff --git a/src/playerrelations.cpp b/src/playerrelations.cpp index 316bd9ed..7bc1b14d 100644 --- a/src/playerrelations.cpp +++ b/src/playerrelations.cpp @@ -29,6 +29,7 @@ #include "playerrelations.h" #include "utils/dtor.h" +#include "utils/gettext.h" #define PLAYER_IGNORE_STRATEGY_NOP "nop" #define PLAYER_IGNORE_STRATEGY_EMOTE0 "emote0" @@ -292,7 +293,7 @@ class PIS_nothing : public PlayerIgnoreStrategy public: PIS_nothing() { - mDescription = "completely ignore"; + mDescription = _("Completely ignore"); mShortName = PLAYER_IGNORE_STRATEGY_NOP; } @@ -306,7 +307,7 @@ class PIS_dotdotdot : public PlayerIgnoreStrategy public: PIS_dotdotdot() { - mDescription = "print '...'"; + mDescription = _("Print '...'"); mShortName = "dotdotdot"; } @@ -322,7 +323,7 @@ class PIS_blinkname : public PlayerIgnoreStrategy public: PIS_blinkname() { - mDescription = "blink name"; + mDescription = _("Blink name"); mShortName = "blinkname"; } @@ -359,10 +360,10 @@ PlayerRelationsManager::getPlayerIgnoreStrategies() { // not initialised yet? mIgnoreStrategies.push_back(new PIS_emote(FIRST_IGNORE_EMOTE, - "floating '...' bubble", + _("Floating '...' bubble"), PLAYER_IGNORE_STRATEGY_EMOTE0)); mIgnoreStrategies.push_back(new PIS_emote(FIRST_IGNORE_EMOTE + 1, - "floating bubble", + _("Floating bubble"), "emote1")); mIgnoreStrategies.push_back(new PIS_nothing()); mIgnoreStrategies.push_back(new PIS_dotdotdot()); diff --git a/src/properties.h b/src/properties.h index a2ce5b88..e7aab157 100644 --- a/src/properties.h +++ b/src/properties.h @@ -74,6 +74,28 @@ class Properties } /** + * Gets a map property as a boolean. + * + * @param name The name of the property. + * @param def Default value, false by default. + * @return the value of the given property, or false when it doesn't + * exist. + */ + float getBoolProperty(const std::string &name, bool def = false) const + { + PropertyMap::const_iterator i = mProperties.find(name); + bool ret = def; + if (i != mProperties.end()) + { + if (i->second == "true") + ret = true; + if (i->second == "false") + ret = false; + } + return ret; + } + + /** * Returns whether a certain property is available. * * @param name The name of the property. diff --git a/src/resources/ambientoverlay.cpp b/src/resources/ambientoverlay.cpp index 93c7c3e1..8c851e2e 100644 --- a/src/resources/ambientoverlay.cpp +++ b/src/resources/ambientoverlay.cpp @@ -22,16 +22,41 @@ #include "resources/ambientoverlay.h" #include "resources/image.h" - +#include "resources/resourcemanager.h" #include "graphics.h" AmbientOverlay::AmbientOverlay(Image *img, float parallax, - float speedX, float speedY): + float speedX, float speedY, bool keepRatio): mImage(img), mParallax(parallax), mPosX(0), mPosY(0), - mSpeedX(speedX), mSpeedY(speedY) + mSpeedX(speedX), mSpeedY(speedY), + mKeepRatio(keepRatio) { - mImage->incRef(); + + if (keepRatio && !mImage->isAnOpenGLOne() + && defaultScreenWidth != 0 + && defaultScreenHeight != 0 + && graphics->getWidth() != defaultScreenWidth + && graphics->getHeight() != defaultScreenHeight) + { + // Rescale the overlay to keep the ratio as if we were on + // the default resolution... + Image *rescaledOverlay = mImage->SDLgetScaledImage( + (int) mImage->getWidth() / defaultScreenWidth * graphics->getWidth(), + (int) mImage->getHeight() / defaultScreenHeight * graphics->getHeight()); + + if (rescaledOverlay) + { + // Replace the resource with the new one... + std::string idPath = mImage->getIdPath() + "_rescaled"; + ResourceManager::getInstance()->addResource(idPath, rescaledOverlay); + mImage = rescaledOverlay; + } + else + mImage->incRef(); + } + else + mImage->incRef(); } AmbientOverlay::~AmbientOverlay() @@ -66,6 +91,13 @@ void AmbientOverlay::update(int timePassed, float dx, float dy) void AmbientOverlay::draw(Graphics *graphics, int x, int y) { - graphics->drawImagePattern(mImage, + if (!mImage->isAnOpenGLOne() || !mKeepRatio) + graphics->drawImagePattern(mImage, (int) -mPosX, (int) -mPosY, x + (int) mPosX, y + (int) mPosY); + else + graphics->drawRescaledImagePattern(mImage, + (int) -mPosX, (int) -mPosY, x + (int) mPosX, y + (int) mPosY, + (int) mImage->getWidth() / defaultScreenWidth * graphics->getWidth(), + (int) mImage->getHeight() / defaultScreenHeight * graphics->getHeight()); + } diff --git a/src/resources/ambientoverlay.h b/src/resources/ambientoverlay.h index 756d0eb7..f2d2e588 100644 --- a/src/resources/ambientoverlay.h +++ b/src/resources/ambientoverlay.h @@ -35,9 +35,11 @@ class AmbientOverlay * @param parallax scroll factor based on camera position * @param speedX scrolling speed in x-direction * @param speedY scrolling speed in y-direction + * @param keepRatio rescale the image to keep + * the same ratio than in 800x600 resolution mode. */ AmbientOverlay(Image *img, float parallax, - float speedX, float speedY); + float speedX, float speedY, bool keepRatio = false); ~AmbientOverlay(); @@ -52,6 +54,7 @@ class AmbientOverlay float mPosY; /**< Current layer Y position. */ float mSpeedX; /**< Scrolling speed in X direction. */ float mSpeedY; /**< Scrolling speed in Y direction. */ + bool mKeepRatio; /**< Keep overlay ratio on every resolution */ }; #endif diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 0c542a8b..9af3059a 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -26,6 +26,7 @@ #include "log.h" #include <SDL_image.h> +#include "resources/sdlrescalefacility.h" #ifdef USE_OPENGL bool Image::mUseOpenGL = false; @@ -289,16 +290,13 @@ void Image::unload() #endif } -Image *Image::getSubImage(int x, int y, int width, int height) +bool Image::isAnOpenGLOne() const { - // Create a new clipped sub-image #ifdef USE_OPENGL - if (mUseOpenGL) - return new SubImage(this, mGLImage, x, y, width, height, - mTexWidth, mTexHeight); + return mUseOpenGL; +#else + return false; #endif - - return new SubImage(this, mImage, x, y, width, height); } void Image::setAlpha(float a) @@ -345,7 +343,7 @@ Image* Image::merge(Image *image, int x, int y) cur_pix = ((Uint32*) mImage->pixels)[current_offset]; // Retreiving each channel of the pixel using pixel format - r = (Uint8)(((surface_pix & surface_fmt->Rmask) >> + r = (Uint8)(((surface_pix & surface_fmt->Rmask) >> surface_fmt->Rshift) << surface_fmt->Rloss); g = (Uint8)(((surface_pix & surface_fmt->Gmask) >> surface_fmt->Gshift) << surface_fmt->Gloss); @@ -360,14 +358,14 @@ Image* Image::merge(Image *image, int x, int y) // new pixel with no alpha or nothing on previous pixel if (a == SDL_ALPHA_OPAQUE || (p_a == 0 && a > 0)) - ((Uint32 *)(surface->pixels))[current_offset] = + ((Uint32 *)(surface->pixels))[current_offset] = SDL_MapRGBA(current_fmt, r, g, b, a); - else if (a > 0) + else if (a > 0) { // alpha is lower => merge color with previous value f_a = (double) a / 255.0; f_ca = 1.0 - f_a; f_pa = (double) p_a / 255.0; - p_r = (Uint8)(((cur_pix & current_fmt->Rmask) >> + p_r = (Uint8)(((cur_pix & current_fmt->Rmask) >> current_fmt->Rshift) << current_fmt->Rloss); p_g = (Uint8)(((cur_pix & current_fmt->Gmask) >> current_fmt->Gshift) << current_fmt->Gloss); @@ -395,6 +393,34 @@ float Image::getAlpha() const return mAlpha; } +Image* Image::SDLgetScaledImage(int width, int height) +{ + // No scaling on incorrect new values. + if (width == 0 || height == 0) + return NULL; + + // No scaling when there is ... no different given size ... + if (width == getWidth() && height == getHeight()) + return NULL; + + Image* scaledImage = NULL; + SDL_Surface* scaledSurface = NULL; + + if (mImage) + { + scaledSurface = _SDLzoomSurface(mImage, + (double) width / getWidth(), + (double) height / getHeight(), + 1); + + // The load function takes of the SDL<->OpenGL implementation + // and about freeing the given SDL_surface*. + if (scaledSurface) + scaledImage = load(scaledSurface); + } + return scaledImage; +} + #ifdef USE_OPENGL void Image::setLoadAsOpenGL(bool useOpenGL) { @@ -420,6 +446,18 @@ int Image::powerOfTwo(int input) } #endif +Image *Image::getSubImage(int x, int y, int width, int height) +{ + // Create a new clipped sub-image +#ifdef USE_OPENGL + if (mUseOpenGL) + return new SubImage(this, mGLImage, x, y, width, height, + mTexWidth, mTexHeight); +#endif + + return new SubImage(this, mImage, x, y, width, height); +} + //============================================================================ // SubImage Class //============================================================================ @@ -469,4 +507,3 @@ Image *SubImage::getSubImage(int x, int y, int w, int h) { return mParent->getSubImage(mBounds.x + x, mBounds.y + y, w, h); } - diff --git a/src/resources/image.h b/src/resources/image.h index 4422fcc8..f497f608 100644 --- a/src/resources/image.h +++ b/src/resources/image.h @@ -88,6 +88,16 @@ class Image : public Resource static Image *load(SDL_Surface *); /** + * Gets an scaled instance of an image. + * + * @param width The desired width of the scaled image. + * @param height The desired height of the scaled image. + * + * @return A new Image* object. + */ + Image* SDLgetScaledImage(int width, int height); + + /** * Frees the resources created by SDL. */ virtual void unload(); @@ -105,6 +115,12 @@ class Image : public Resource { return mBounds.h; } /** + * Tells if the image was loade using OpenGL or SDL + * @return true if OpenGL, false if SDL. + */ + bool isAnOpenGLOne() const; + + /** * Creates a new image with the desired clipping rectangle. * * @return <code>NULL</code> if creation failed and a valid diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp index b25f754f..900e3547 100644 --- a/src/resources/itemdb.cpp +++ b/src/resources/itemdb.cpp @@ -153,7 +153,7 @@ void ItemDB::load() ItemInfo *itemInfo = new ItemInfo; itemInfo->setId(id); itemInfo->setImageName(image); - itemInfo->setName(name.empty() ? _("Unnamed") : name); + itemInfo->setName(name.empty() ? _("unnamed") : name); itemInfo->setDescription(description); itemInfo->setType(itemTypeFromString(typeStr)); itemInfo->setView(view); diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp index 0b8d6c35..bc3267da 100644 --- a/src/resources/resourcemanager.cpp +++ b/src/resources/resourcemanager.cpp @@ -214,6 +214,19 @@ std::string ResourceManager::getPath(const std::string &file) return path; } +bool ResourceManager::addResource(const std::string &idPath, + Resource* resource) +{ + if (resource) + { + resource->incRef(); + resource->mIdPath = idPath; + mResources[idPath] = resource; + return true; + } + return false; +} + Resource *ResourceManager::get(const std::string &idPath, generator fun, void *data) { diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h index b2ad3069..88fd60fc 100644 --- a/src/resources/resourcemanager.h +++ b/src/resources/resourcemanager.h @@ -125,6 +125,15 @@ class ResourceManager Resource *load(const std::string &path, loader fun); /** + * Adds a preformatted resource to the resource map. + * + * @param path The file name. + * @param Resource The Resource to add. + * @return true if successfull, false otherwise. + */ + bool addResource(const std::string &idPath, Resource* resource); + + /** * Copies a file from one place to another (useful for extracting * raw files from a zip archive, for example) * diff --git a/src/resources/sdlrescalefacility.cpp b/src/resources/sdlrescalefacility.cpp new file mode 100644 index 00000000..49ba8aa4 --- /dev/null +++ b/src/resources/sdlrescalefacility.cpp @@ -0,0 +1,489 @@ +/* + * 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 Low GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + * + * Source code taken from: + * + * SDL_rotozoom - rotozoomer + * + * LGPL (c) A. Schiffler + * + */ + +#include "sdlrescalefacility.h" + +#define VALUE_LIMIT 0.001 + +typedef struct tColorRGBA { + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 a; +} tColorRGBA; + +void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, + int *dstwidth, int *dstheight) +{ + /* + * Sanity check zoom factors + */ + if (zoomx < VALUE_LIMIT) { + zoomx = VALUE_LIMIT; + } + if (zoomy < VALUE_LIMIT) { + zoomy = VALUE_LIMIT; + } + + /* + * Calculate target size + */ + *dstwidth = (int) ((double) width * zoomx); + *dstheight = (int) ((double) height * zoomy); + if (*dstwidth < 1) { + *dstwidth = 1; + } + if (*dstheight < 1) { + *dstheight = 1; + } +} + +int zoomSurfaceRGBA(SDL_Surface *src, SDL_Surface * dst, + int flipx, int flipy, int smooth) +{ + int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep, lx, ly; + tColorRGBA *c00, *c01, *c10, *c11, *cswap; + tColorRGBA *sp, *csp, *dp; + int dgap; + + /* + * Variable setup + */ + if (smooth) { + /* + * For interpolation: assume source dimension is one pixel + */ + /* + * smaller to avoid overflow on right and bottom edge. + */ + sx = (int) (65536.0 * (float) (src->w - 1) / (float) dst->w); + sy = (int) (65536.0 * (float) (src->h - 1) / (float) dst->h); + } else { + sx = (int) (65536.0 * (float) src->w / (float) dst->w); + sy = (int) (65536.0 * (float) src->h / (float) dst->h); + } + + /* + * Allocate memory for row increments + */ + if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) { + return (-1); + } + if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) { + free(sax); + return (-1); + } + + /* + * Precalculate row increments + */ + sp = csp = (tColorRGBA *) src->pixels; + dp = (tColorRGBA *) dst->pixels; + + if (flipx) csp += (src->w-1); + if (flipy) csp += (src->pitch*(src->h-1)); + + csx = 0; + csax = sax; + for (x = 0; x <= dst->w; x++) { + *csax = csx; + csax++; + csx &= 0xffff; + csx += sx; + } + csy = 0; + csay = say; + for (y = 0; y <= dst->h; y++) { + *csay = csy; + csay++; + csy &= 0xffff; + csy += sy; + } + + dgap = dst->pitch - dst->w * 4; + + /* + * Switch between interpolating and non-interpolating code + */ + if (smooth) { + + /* + * Interpolating Zoom + */ + + /* + * Scan destination + */ + ly = 0; + csay = say; + for (y = 0; y < dst->h; y++) { + /* + * Setup color source pointers + */ + c00 = csp; + c01 = csp; + c01++; + c10 = (tColorRGBA *) ((Uint8 *) csp + src->pitch); + c11 = c10; + c11++; + csax = sax; + if (flipx) { + cswap = c00; c00=c01; c01=cswap; + cswap = c10; c10=c11; c11=cswap; + } + if (flipy) { + cswap = c00; c00=c10; c10=cswap; + cswap = c01; c01=c11; c11=cswap; + } + lx = 0; + for (x = 0; x < dst->w; x++) { + /* + * Interpolate colors + */ + ex = (*csax & 0xffff); + ey = (*csay & 0xffff); + t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff; + t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff; + dp->r = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff; + t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff; + dp->g = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff; + t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff; + dp->b = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff; + t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff; + dp->a = (((t2 - t1) * ey) >> 16) + t1; + + /* + * Advance source pointers + */ + csax++; + sstep = (*csax >> 16); + lx += sstep; + if (lx >= src->w) sstep = 0; + if (flipx) sstep = -sstep; + c00 += sstep; + c01 += sstep; + c10 += sstep; + c11 += sstep; + /* + * Advance destination pointer + */ + dp++; + } + /* + * Advance source pointer + */ + csay++; + sstep = (*csay >> 16); + ly += sstep; + if (ly >= src->h) sstep = 0; + sstep *= src->pitch; + if (flipy) sstep = -sstep; + csp = (tColorRGBA *) ((Uint8 *) csp + sstep); + + /* + * Advance destination pointers + */ + dp = (tColorRGBA *) ((Uint8 *) dp + dgap); + } + } else { + + /* + * Non-Interpolating Zoom + */ + + csay = say; + for (y = 0; y < dst->h; y++) { + sp = csp; + csax = sax; + for (x = 0; x < dst->w; x++) { + /* + * Draw + */ + *dp = *sp; + /* + * Advance source pointers + */ + csax++; + sstep = (*csax >> 16); + if (flipx) sstep = -sstep; + sp += sstep; + /* + * Advance destination pointer + */ + dp++; + } + /* + * Advance source pointer + */ + csay++; + sstep = (*csay >> 16) * src->pitch; + if (flipy) sstep = -sstep; + csp = (tColorRGBA *) ((Uint8 *) csp + sstep); + + /* + * Advance destination pointers + */ + dp = (tColorRGBA *) ((Uint8 *) dp + dgap); + } + } + + /* + * Remove temp arrays + */ + free(sax); + free(say); + + return (0); +} + + + +int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy) +{ + int x, y; + Uint32 sx, sy, *sax, *say, *csax, *csay, csx, csy, sstep; + Uint8 *sp, *dp, *csp; + int dgap; + + /* + * Variable setup + */ + sx = (Uint32) (65536.0 * (float) src->w / (float) dst->w); + sy = (Uint32) (65536.0 * (float) src->h / (float) dst->h); + + + /* + * Allocate memory for row increments + */ + if ((sax = (Uint32 *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) { + return (-1); + } + if ((say = (Uint32 *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) { + free(sax); + return (-1); + } + + /* + * Pointer setup + */ + sp = csp = (Uint8 *) src->pixels; + dp = (Uint8 *) dst->pixels; + dgap = dst->pitch - dst->w; + + if (flipx) csp += (src->w-1); + if (flipy) csp = ( (Uint8*)csp + src->pitch*(src->h-1) ); + + /* + * Precalculate row increments + */ + csx = 0; + csax = sax; + for (x = 0; x <= dst->w; x++) { + *csax = csx; + csax++; + csx &= 0xffff; + csx += sx; + } + csy = 0; + csay = say; + for (y = 0; y <= dst->h; y++) { + *csay = csy; + csay++; + csy &= 0xffff; + csy += sy; + } + + + /* + * Draw + */ + csay = say; + for (y = 0; y < dst->h; y++) { + csax = sax; + sp = csp; + for (x = 0; x < dst->w; x++) { + /* + * Draw + */ + *dp = *sp; + /* + * Advance source pointers + */ + csax++; + sstep = (*csax >> 16); + if (flipx) sstep = -sstep; + sp += sstep; + /* + * Advance destination pointer + */ + dp++; + } + /* + * Advance source pointer (for row) + */ + csay++; + sstep = (*csay >> 16) * src->pitch; + if (flipy) sstep = -sstep; + csp = ((Uint8 *) csp + sstep); + + /* + * Advance destination pointers + */ + dp += dgap; + } + + /* + * Remove temp arrays + */ + free(sax); + free(say); + + return (0); +} + + + +SDL_Surface *_SDLzoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth) +{ + SDL_Surface *rz_src; + SDL_Surface *rz_dst; + int dstwidth, dstheight; + int is32bit; + int i, src_converted; + int flipx, flipy; + + /* + * Sanity check + */ + if (src == NULL) + return (NULL); + + /* + * Determine if source surface is 32bit or 8bit + */ + is32bit = (src->format->BitsPerPixel == 32); + if ((is32bit) || (src->format->BitsPerPixel == 8)) { + /* + * Use source surface 'as is' + */ + rz_src = src; + src_converted = 0; + } else { + /* + * New source surface is 32bit with a defined RGBA ordering + */ + rz_src = + SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 +#else + 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff +#endif + ); + SDL_BlitSurface(src, NULL, rz_src, NULL); + src_converted = 1; + is32bit = 1; + } + + flipx = (zoomx<0.0); + if (flipx) zoomx = -zoomx; + flipy = (zoomy<0.0); + if (flipy) zoomy = -zoomy; + + /* Get size if target */ + zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight); + + /* + * Alloc space to completely contain the zoomed surface + */ + rz_dst = NULL; + if (is32bit) { + /* + * Target surface is 32bit with source RGBA/ABGR ordering + */ + rz_dst = + SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32, + rz_src->format->Rmask, rz_src->format->Gmask, + rz_src->format->Bmask, rz_src->format->Amask); + } else { + /* + * Target surface is 8bit + */ + rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0); + } + + /* + * Lock source surface + */ + SDL_LockSurface(rz_src); + /* + * Check which kind of surface we have + */ + if (is32bit) { + /* + * Call the 32bit transformation routine to do the zooming (using alpha) + */ + zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth); + /* + * Turn on source-alpha support + */ + SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); + } else { + /* + * Copy palette and colorkey info + */ + for (i = 0; i < rz_src->format->palette->ncolors; i++) { + rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i]; + } + rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; + /* + * Call the 8bit transformation routine to do the zooming + */ + zoomSurfaceY(rz_src, rz_dst, flipx, flipy); + SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey); + } + /* + * Unlock source surface + */ + SDL_UnlockSurface(rz_src); + + /* + * Cleanup temp surface + */ + if (src_converted) { + SDL_FreeSurface(rz_src); + } + + /* + * Return destination surface + */ + return (rz_dst); +} diff --git a/src/resources/sdlrescalefacility.h b/src/resources/sdlrescalefacility.h new file mode 100644 index 00000000..971f5d73 --- /dev/null +++ b/src/resources/sdlrescalefacility.h @@ -0,0 +1,52 @@ +/* + * 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 Low GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + * + * Source code taken from: + * + * SDL_rotozoom - rotozoomer + * + * LGPL (c) A. Schiffler + * + */ + +#ifndef SDLRESCALEFACILITY_H +#define SDLRESCALEFACILITY_H + +#include <SDL.h> +#include "image.h" + +/** + * _SDLzoomSurface is internally used by Image::getScaledImage() to provide + * a rescaled copy of its internal mImage member. + * + * @see Image::getScaledImage() for more details + * + * @param src the original surface to rescale + * @param zoomx the zoom factor used to rescale the surface horizontally. 1.0 doesn't rescale. + * A value lesser than 1.O shrink the image. + * @param zoomy the zoom factor used to rescale the surface vertically. + * @param smooth transform the scaled surface into a 32bit aliased image to smooth the rescaling. + * + * @return SDL_Surface The rescaled surface. + */ + +SDL_Surface *_SDLzoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth); + +#endif @@ -220,8 +220,8 @@ <Unit filename="src/gui/chat.h" /> <Unit filename="src/gui/confirmdialog.cpp" /> <Unit filename="src/gui/confirmdialog.h" /> - <Unit filename="src/gui/connection.cpp" /> - <Unit filename="src/gui/connection.h" /> + <Unit filename="src/gui/connectiondialog.cpp" /> + <Unit filename="src/gui/connectiondialog.h" /> <Unit filename="src/gui/debugwindow.cpp" /> <Unit filename="src/gui/debugwindow.h" /> <Unit filename="src/gui/emotepopup.cpp" /> @@ -349,42 +349,14 @@ <Unit filename="src/gui/shortcutcontainer.h" /> <Unit filename="src/gui/shortcutwindow.cpp" /> <Unit filename="src/gui/shortcutwindow.h" /> - <Unit filename="src/gui/skill.cpp"> - <Option target="eAthena" /> - <Option target="UNIX eAthena" /> - </Unit> - <Unit filename="src/gui/skill.h"> - <Option target="eAthena" /> - <Option target="UNIX eAthena" /> - </Unit> - <Unit filename="src/gui/skilldialog.cpp"> - <Option target="TMWServ" /> - <Option target="Unix TMWSERV" /> - </Unit> - <Unit filename="src/gui/skilldialog.h"> - <Option target="TMWServ" /> - <Option target="Unix TMWSERV" /> - </Unit> + <Unit filename="src/gui/skilldialog.cpp" /> + <Unit filename="src/gui/skilldialog.h" /> <Unit filename="src/gui/skin.cpp" /> <Unit filename="src/gui/skin.h" /> <Unit filename="src/gui/speechbubble.cpp" /> <Unit filename="src/gui/speechbubble.h" /> - <Unit filename="src/gui/status.cpp"> - <Option target="eAthena" /> - <Option target="UNIX eAthena" /> - </Unit> - <Unit filename="src/gui/status.h"> - <Option target="eAthena" /> - <Option target="UNIX eAthena" /> - </Unit> - <Unit filename="src/gui/statuswindow.cpp"> - <Option target="TMWServ" /> - <Option target="Unix TMWSERV" /> - </Unit> - <Unit filename="src/gui/statuswindow.h"> - <Option target="TMWServ" /> - <Option target="Unix TMWSERV" /> - </Unit> + <Unit filename="src/gui/statuswindow.cpp" /> + <Unit filename="src/gui/statuswindow.h" /> <Unit filename="src/gui/storagewindow.cpp" /> <Unit filename="src/gui/storagewindow.h" /> <Unit filename="src/gui/table.cpp" /> @@ -470,6 +442,8 @@ <Unit filename="src/gui/widgets/textfield.h" /> <Unit filename="src/gui/widgets/textpreview.cpp" /> <Unit filename="src/gui/widgets/textpreview.h" /> + <Unit filename="src/gui/widgets/vertcontainer.cpp" /> + <Unit filename="src/gui/widgets/vertcontainer.h" /> <Unit filename="src/gui/widgets/whispertab.cpp" /> <Unit filename="src/gui/widgets/whispertab.h" /> <Unit filename="src/gui/widgets/window.cpp" /> @@ -655,11 +629,11 @@ <Option target="eAthena" /> <Option target="UNIX eAthena" /> </Unit> - <Unit filename="src/net/ea/skillhandler.cpp"> + <Unit filename="src/net/ea/specialhandler.cpp"> <Option target="eAthena" /> <Option target="UNIX eAthena" /> </Unit> - <Unit filename="src/net/ea/skillhandler.h"> + <Unit filename="src/net/ea/specialhandler.h"> <Option target="eAthena" /> <Option target="UNIX eAthena" /> </Unit> @@ -688,7 +662,7 @@ <Unit filename="src/net/npchandler.h" /> <Unit filename="src/net/partyhandler.h" /> <Unit filename="src/net/playerhandler.h" /> - <Unit filename="src/net/skillhandler.h" /> + <Unit filename="src/net/specialhandler.h" /> <Unit filename="src/net/tmwserv/accountserver/account.cpp"> <Option target="TMWServ" /> <Option target="Unix TMWSERV" /> @@ -920,11 +894,11 @@ <Option target="TMWServ" /> <Option target="Unix TMWSERV" /> </Unit> - <Unit filename="src/net/tmwserv/skillhandler.cpp"> + <Unit filename="src/net/tmwserv/specialhandler.cpp"> <Option target="TMWServ" /> <Option target="Unix TMWSERV" /> </Unit> - <Unit filename="src/net/tmwserv/skillhandler.h"> + <Unit filename="src/net/tmwserv/specialhandler.h"> <Option target="TMWServ" /> <Option target="Unix TMWSERV" /> </Unit> @@ -993,6 +967,8 @@ <Unit filename="src/resources/resource.h" /> <Unit filename="src/resources/resourcemanager.cpp" /> <Unit filename="src/resources/resourcemanager.h" /> + <Unit filename="src/resources/sdlrescalefacility.cpp" /> + <Unit filename="src/resources/sdlrescalefacility.h" /> <Unit filename="src/resources/soundeffect.cpp" /> <Unit filename="src/resources/soundeffect.h" /> <Unit filename="src/resources/spritedef.cpp" /> diff --git a/tmw.desktop b/tmw.desktop index d15ad3f7..49d8a59a 100644 --- a/tmw.desktop +++ b/tmw.desktop @@ -2,11 +2,13 @@ Version=1.0 Name=The Mana World Name[fr]=Le Monde de Mana +Name[sv]=Manavärlden Comment=An on-line fantasy role playing game Comment[fr]=Un jeu en ligne dans un univers fantastique Comment[de]=ein Online Fantasy Spiel Comment[it]=Un gioco fantasy online Comment[nl]=Een online role playing game +Comment[sv]=Ett fantasyrollspel online Exec=tmw StartupNotify=false Terminal=false diff --git a/tools/tmxcopy/map.cpp b/tools/tmxcopy/map.cpp index 0fd764b4..75bd9a45 100644 --- a/tools/tmxcopy/map.cpp +++ b/tools/tmxcopy/map.cpp @@ -390,7 +390,17 @@ bool Map::randomFill(Map* templateMap, const std::string& destLayerName, } /* Now generate extra tiles. - * TODO Need to configure this for desired density. For 2x1 trees, dW*dH/10 is very sparse, dW*dH/2 is dense */ + * + * After considering ways to specify the number of objects to add, I think + * the best user interface (without integrating it with Tiled) is to place + * a small number of objects each time, and have the user run the utility + * several times, reloading the map in Tiled each time until it looks + * right. Simpler than typing magic numbers in at a command prompt. + * + * This algorithm completes after a fixed number of attempts at placing an + * object; regardless of how many attempts are successful. + * For 2x1 trees, destWidth*destHeight/10 is very sparse, dW*dH/2 is dense. + */ srand(time(NULL)); int patternsGenerated = 0; int occupiedAreas = 0; @@ -418,7 +428,6 @@ bool Map::randomFill(Map* templateMap, const std::string& destLayerName, if (areaIsClear) { int p = rand() % templateMap->getNumberOfLayers(); - std::cout <<"Copying pattern "<<p<<" to "<<x<<", "<<y<<std::endl; Layer* srcLayer = templateMap->getLayer(p); for (int loop_y=0; loop_y<templateMap->getHeight(); loop_y++) @@ -436,11 +445,11 @@ bool Map::randomFill(Map* templateMap, const std::string& destLayerName, else { occupiedAreas++; - std::cout <<"Area occupied "<<x<<", "<<y<<std::endl; } } std::clog<<"Generated " << patternsGenerated << " new objects" <<std::endl; + (void) occupiedAreas; // Unused at the moment, but keep it without a compiler warning about unused variables return true; } @@ -461,7 +470,7 @@ bool Map::translateAllLayers(Map* templateMap, const std::string& destLayerName, } if (!checkPassed) return false; - //FIXME - as is, this will add tilesets that are in the template but + //TODO This will unnecessarily add tilesets that are in the template but //not used in the main map std::map<int, int> tilesetTranslation = addAndTranslateTilesets(templateMap); diff --git a/tools/tmxcopy/readme.txt b/tools/tmxcopy/readme.txt index 972d1f66..52af1048 100644 --- a/tools/tmxcopy/readme.txt +++ b/tools/tmxcopy/readme.txt @@ -1,3 +1,10 @@ +=== TMX Map Tools === + +A set of tools for manipulating TMX map files. + +After using any of these tools, load the map in Tiled and save it again; until this is done the game may not be able to load the file (see Bugs for an explanation). + + === TMXCopy === Tmxcopy is a little tool that allows to copy parts of one TMX map to another map. This will make it much easier to match the border areas of maps. The program is command line based. The usage is: @@ -61,22 +68,36 @@ The template is a map where each layer is a pattern. For example, to make a woo It will then randomly place trees, but only in places where they won't overlap with other things on that layer. The size of the template map is the size of the area which must be empty in the destination layer. +Running it several times (without specifying an output file) will add more objects. After considering ways to specify the number of objects to add, I think the easiest is to just reload the map in Tiled each time until it looks right (you don't need to quit Tiled while running tmx_random_fill). -=== TMX Translate === -This tool is still to be written. I guarantee it will be written before I get a woodland map finished. +=== TMX Collide / Translate === A big woodland with lots of randomly-placed trees needs a complex collision layer, most of which can be generated from the visible layers. -This tool takes a two-layer template map - one layer contains visible tiles, and one layer contains collision tiles. +This tool does that automatic generation. + +It's not limited to adding collision tiles; it can be used for any task where tiles are added to one layer based on the tiles present in other layers. + +Usage: tmxcollide [-c] mapFile destLayer templateFile [-o outfile] + -c create layers, if they don't already exist in the target + -o save results to outfile, instead of overwriting the original + +To fill the collision layer, "destLayer" should be "Collision". + +As with TMX Random Fill, this tool takes a template map; for this tool it should have exactly two layers. + Upper layer: tiles to translate to (collision tiles) + Lower layer: tiles to translate from (visible tiles) +Blank tiles in the lower layer will be ignored (put a blank in the upper layer too). === Bugs (for all these programs) === -The program works so far but there are still some minor problems: +The programs work so far but there are still some minor problems: --Only tested for TMW-compilant maps. I don't guarantee that it works with Tiled maps that are made for other games and thus use different features. It is assumed that the target map and the source maps have the same number of layers, for example. +-Only tested for TMW-compilant maps. I don't guarantee that it works with Tiled maps that are made for other games and thus use different features. -Compressed maps (tmx.gz) can not be handled yet (but compressed or uncompressed layers work properly) -When the target map has an object layer it is moved to the bottom of the layer list of the map (no problem for the game but inconvenient for editing). Objects on the source map are ignored. +-All tilesets included in the srcFile (TMXCopy) or template (TMXRandomFill and TMXCollide) will be added to the output file, even if they aren't needed for the tiles that are added. -Layer data of output file isn't gzip-compressed yet -Created TMX file is a bit malformated (but working properly) diff --git a/tools/tmxcopy/tmx_random_fill.cpp b/tools/tmxcopy/tmx_random_fill.cpp index d55c9b58..2cc232fe 100644 --- a/tools/tmxcopy/tmx_random_fill.cpp +++ b/tools/tmxcopy/tmx_random_fill.cpp @@ -31,7 +31,7 @@ void printUsage() <<" -o save results to outfile, instead of overwriting the original"<<std::endl <<std::endl <<"Fill a rectangular area of mapFile's layer 'destLayer' with a random selection from the templateFile"<<std::endl - <<"TODO - more help here"<<std::endl; + <<"See readme.txt for full documentation"<<std::endl; } int main(int argc, char * argv[] ) diff --git a/tools/tmxcopy/tmxcollide.cpp b/tools/tmxcopy/tmxcollide.cpp index 2ce6f90b..a3600f61 100644 --- a/tools/tmxcopy/tmxcollide.cpp +++ b/tools/tmxcopy/tmxcollide.cpp @@ -31,7 +31,7 @@ void printUsage() <<" -o save results to outfile, instead of overwriting the original"<<std::endl <<std::endl <<"Using the template, translate visible layers to the collision layer"<<std::endl - <<"TODO - more help here"<<std::endl; + <<"See readme.txt for full documentation"<<std::endl; } int main(int argc, char * argv[] ) |