diff options
Diffstat (limited to 'src/gui')
208 files changed, 8108 insertions, 2406 deletions
diff --git a/src/gui/browserbox.cpp b/src/gui/browserbox.cpp index 46c8bdf1..2f667237 100644 --- a/src/gui/browserbox.cpp +++ b/src/gui/browserbox.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -419,4 +418,3 @@ void BrowserBox::draw(gcn::Graphics *graphics) setHeight((mTextRows.size() + wrappedLines) * font->getHeight()); } } - diff --git a/src/gui/browserbox.h b/src/gui/browserbox.h index 500c9fba..090c03e1 100644 --- a/src/gui/browserbox.h +++ b/src/gui/browserbox.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -163,4 +162,3 @@ class BrowserBox : public gcn::Widget, public gcn::MouseListener }; #endif - diff --git a/src/gui/buddywindow.cpp b/src/gui/buddywindow.cpp new file mode 100644 index 00000000..37301c86 --- /dev/null +++ b/src/gui/buddywindow.cpp @@ -0,0 +1,68 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "buddywindow.h" +#include "chat.h" +#include "icon.h" + +#include "widgets/avatar.h" + +#include "../resources/resourcemanager.h" +#include "../utils/gettext.h" + +extern ChatWindow *chatWindow; + +BuddyWindow::BuddyWindow(): + Window(_("Buddy")) +{ + setVisible(false); + setWindowName("Buddy Window"); + setCaption(_("Buddy List")); + setResizable(true); + setCloseButton(true); + setMinWidth(110); + setMinHeight(200); + setDefaultSize(124, 41, 288, 330); + + Image *addImg = ResourceManager::getInstance()->getImage("buddyadd.png"); + Image *delImg = ResourceManager::getInstance()->getImage("buddydel.png"); + + if (addImg && delImg) + { + Icon *addBuddy = new Icon(addImg); + Icon *delBuddy = new Icon(delImg); + + add(addBuddy); + add(delBuddy); + } + + loadWindowState(); +} + +void BuddyWindow::action(const gcn::ActionEvent &event) +{ + +} + +void BuddyWindow::draw(gcn::Graphics *graphics) +{ + Window::draw(graphics); +} diff --git a/src/gui/buddywindow.h b/src/gui/buddywindow.h new file mode 100644 index 00000000..aa654477 --- /dev/null +++ b/src/gui/buddywindow.h @@ -0,0 +1,60 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef BUDDYWINDOW_H +#define BUDDYWINDOW_H + +#include <guichan/actionlistener.hpp> +#include <guichan/actionevent.hpp> + +#include "window.h" + +class Avatar; + +/** + * Window showing buddy list. + * + * \ingroup Interface + */ +class BuddyWindow : public Window, public gcn::ActionListener +{ + public: + /** + * Constructor. + */ + BuddyWindow(); + + /** + * Performs action. + */ + void action(const gcn::ActionEvent &event); + + /** + * Draws the window + */ + void draw(gcn::Graphics *graphics); + + + private: + std::list<Avatar*> mBuddyList; +}; + +#endif /* BUDDYWINDOW_H */ diff --git a/src/gui/button.cpp b/src/gui/button.cpp index 16a2853c..28b7c0d7 100644 --- a/src/gui/button.cpp +++ b/src/gui/button.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -67,7 +66,7 @@ Button::Button(): init(); } -Button::Button(const std::string& caption, const std::string &actionEventId, +Button::Button(const std::string &caption, const std::string &actionEventId, gcn::ActionListener *listener): gcn::Button(caption), mIsLogged(false) diff --git a/src/gui/button.h b/src/gui/button.h index f21d2661..abaf5c43 100644 --- a/src/gui/button.h +++ b/src/gui/button.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp index 43c423f1..6df2ae25 100644 --- a/src/gui/buy.cpp +++ b/src/gui/buy.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,29 +19,45 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "button.h" -#include "buy.h" -#include "label.h" -#include "scrollarea.h" -#include "shop.h" -#include "shoplistbox.h" -#include "slider.h" +#include "gui/buy.h" -#include "widgets/layout.h" +#include "gui/button.h" +#include "gui/label.h" +#include "gui/scrollarea.h" +#include "gui/shop.h" +#include "gui/shoplistbox.h" +#include "gui/slider.h" -#include "../npc.h" +#include "gui/widgets/layout.h" -#include "../net/messageout.h" -#include "../net/protocol.h" +#include "npc.h" +#include "shopitem.h" +#include "units.h" -#include "../utils/gettext.h" -#include "../utils/strprintf.h" +#ifdef TMWSERV_SUPPORT +#include "net/tmwserv/gameserver/player.h" +#else +#include "net/messageout.h" +#include "net/ea/protocol.h" +#endif +#include "resources/iteminfo.h" + +#include "utils/gettext.h" +#include "utils/strprintf.h" + +#ifdef TMWSERV_SUPPORT +BuyDialog::BuyDialog(): +#else BuyDialog::BuyDialog(Network *network): - Window("Buy"), mNetwork(network), +#endif + Window(_("Buy")), +#ifndef TMWSERV_SUPPORT + mNetwork(network), +#endif mMoney(0), mAmountItems(0), mMaxItems(0) { - setWindowName(_("Buy")); + setWindowName("Buy"); setResizable(true); setCloseButton(true); setMinWidth(260); @@ -56,10 +71,10 @@ BuyDialog::BuyDialog(Network *network): mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); mSlider = new Slider(1.0); - mQuantityLabel = new Label(strprintf("%d / %d", mAmountItems, mMaxItems)); mQuantityLabel->setAlignment(gcn::Graphics::CENTER); - mMoneyLabel = new Label(strprintf(_("Price: %d GP / Total: %d GP"), 0, 0)); + mMoneyLabel = new gcn::Label(strprintf(_("Price: %s / Total: %s"), + "", "")); mIncreaseButton = new Button("+", "+", this); mDecreaseButton = new Button("-", "-", this); @@ -99,6 +114,7 @@ BuyDialog::BuyDialog(Network *network): Layout &layout = getLayout(); layout.setRowHeight(0, Layout::AUTO_SET); + center(); loadWindowState(); } @@ -127,9 +143,9 @@ void BuyDialog::reset() setMoney(0); } -void BuyDialog::addItem(int id, int price) +void BuyDialog::addItem(int id, int amount, int price) { - mShopItems->addItem(id, price); + mShopItems->addItem(id, amount, price); mShopItemList->adjustSize(); } @@ -179,11 +195,16 @@ void BuyDialog::action(const gcn::ActionEvent &event) else if (event.getId() == "buy" && mAmountItems > 0 && mAmountItems <= mMaxItems) { +#ifdef TMWSERV_SUPPORT + Net::GameServer::Player::tradeWithNPC + (mShopItems->at(selectedItem)->getId(), mAmountItems); +#else MessageOut outMsg(mNetwork); outMsg.writeInt16(CMSG_NPC_BUY_REQUEST); outMsg.writeInt16(8); outMsg.writeInt16(mAmountItems); outMsg.writeInt16(mShopItems->at(selectedItem)->getId()); +#endif // Update money and adjust the max number of items that can be bought mMaxItems -= mAmountItems; @@ -250,7 +271,16 @@ void BuyDialog::updateButtonsAndLabels() // Update quantity and money labels mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems)); mMoneyLabel->setCaption - (strprintf(_("Price: %d GP / Total: %d GP"), price, mMoney - price)); + (strprintf(_("Price: %s / Total: %s"), + Units::formatCurrency(price).c_str(), + Units::formatCurrency(mMoney - price).c_str())); +} + +void BuyDialog::logic() +{ + Window::logic(); + + if (!current_npc) setVisible(false); } void BuyDialog::setVisible(bool visible) diff --git a/src/gui/buy.h b/src/gui/buy.h index ffd3f5c9..200394b9 100644 --- a/src/gui/buy.h +++ b/src/gui/buy.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,11 +25,13 @@ #include <guichan/actionlistener.hpp> #include <guichan/selectionlistener.hpp> -#include <SDL_types.h> - #include "window.h" +#include "../guichanfwd.h" + +#ifndef TMWSERV_SUPPORT class Network; +#endif class ShopItems; class ShopListBox; class ListBox; @@ -49,7 +50,11 @@ class BuyDialog : public Window, public gcn::ActionListener, * * @see Window::Window */ +#ifdef TMWSERV_SUPPORT + BuyDialog(); +#else BuyDialog(Network *network); +#endif /** * Destructor @@ -69,7 +74,7 @@ class BuyDialog : public Window, public gcn::ActionListener, /** * Adds an item to the shop inventory. */ - void addItem(int id, int price); + void addItem(int id, int amount, int price); /** * Called when receiving actions from the widgets. @@ -97,6 +102,11 @@ class BuyDialog : public Window, public gcn::ActionListener, void updateButtonsAndLabels(); /** + * Check for current NPC + */ + void logic(); + + /** * Sets the visibility of this window. */ void setVisible(bool visible); @@ -106,7 +116,9 @@ class BuyDialog : public Window, public gcn::ActionListener, */ void close(); private: +#ifdef EATHENA_SUPPORT Network *mNetwork; +#endif gcn::Button *mBuyButton; gcn::Button *mQuitButton; gcn::Button *mAddMaxButton; @@ -122,9 +134,9 @@ class BuyDialog : public Window, public gcn::ActionListener, ShopItems *mShopItems; - Uint32 mMoney; - Uint32 mAmountItems; - Uint32 mMaxItems; + int mMoney; + int mAmountItems; + int mMaxItems; }; extern BuyDialog *buyDialog; diff --git a/src/gui/buysell.cpp b/src/gui/buysell.cpp index df222797..b9a6a1dc 100644 --- a/src/gui/buysell.cpp +++ b/src/gui/buysell.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,7 +25,9 @@ #include "../npc.h" #include "../net/messageout.h" -#include "../net/protocol.h" +#ifdef EATHENA_SUPPORT +#include "../net/ea/protocol.h" +#endif #include "../utils/gettext.h" @@ -43,16 +44,18 @@ BuySellDialog::BuySellDialog(Network *network): for (const char **curBtn = buttonNames; *curBtn; curBtn++) { Button *btn = new Button(gettext(*curBtn), *curBtn, this); - if (!buyButton) buyButton = btn; // For focus request + if (!buyButton) + buyButton = btn; // For focus request btn->setPosition(x, y); add(btn); x += btn->getWidth() + 10; } buyButton->requestFocus(); - setDefaultSize(x + getPadding(), (2 * y + buyButton->getHeight() + - getTitleBarHeight()), ImageRect::CENTER); + setContentSize(x, 2 * y + buyButton->getHeight()); + center(); + setDefaultSize(); loadWindowState(); } @@ -77,7 +80,7 @@ void BuySellDialog::action(const gcn::ActionEvent &event) setVisible(false); int action = 0; - NPC::mTalking = false; + NPC::isTalking = false; if (event.getId() == "Buy") { @@ -93,8 +96,10 @@ void BuySellDialog::action(const gcn::ActionEvent &event) return; } +#ifdef EATHENA_SUPPORT MessageOut outMsg(mNetwork); outMsg.writeInt16(CMSG_NPC_BUY_SELL_REQUEST); outMsg.writeInt32(current_npc); outMsg.writeInt8(action); +#endif } diff --git a/src/gui/buysell.h b/src/gui/buysell.h index c6989709..4b137554 100644 --- a/src/gui/buysell.h +++ b/src/gui/buysell.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -46,8 +45,6 @@ class BuySellDialog : public Window, public gcn::ActionListener BuySellDialog(Network *network); /** -<<<<<<< HEAD:src/gui/buysell.h -======= * Check for current NPC */ void logic(); @@ -55,7 +52,6 @@ class BuySellDialog : public Window, public gcn::ActionListener void setVisible(bool visible); /** ->>>>>>> f64903f... Fix up the NPC interraction widnows a bit:src/gui/buysell.h * Called when receiving actions from the widgets. */ void action(const gcn::ActionEvent &event); diff --git a/src/gui/changeemaildialog.cpp b/src/gui/changeemaildialog.cpp new file mode 100644 index 00000000..0ed95bd7 --- /dev/null +++ b/src/gui/changeemaildialog.cpp @@ -0,0 +1,167 @@ +/* + * The Mana World + * Copyright (C) 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "changeemaildialog.h" + +#include <string> +#include <sstream> + +#include <guichan/widgets/label.hpp> + +#include "../main.h" +#include "../log.h" +#include "../logindata.h" + +#include "button.h" +#include "register.h" +#include "textfield.h" +#include "ok_dialog.h" + +#include "../utils/gettext.h" +#include "../utils/strprintf.h" + +ChangeEmailDialog::ChangeEmailDialog(Window *parent, LoginData *loginData): + Window(_("Change Email Address"), true, parent), + mWrongDataNoticeListener(new WrongDataNoticeListener()), + mLoginData(loginData) +{ + gcn::Label *accountLabel = new gcn::Label(strprintf(_("Account: %s"), + mLoginData->username.c_str())); + gcn::Label *newEmailLabel = new gcn::Label(_("Type New Email Address twice:")); + mFirstEmailField = new TextField(); + mSecondEmailField = new TextField(); + mChangeEmailButton = new Button(_("Change Email Address"), "change_email", this); + mCancelButton = new Button(_("Cancel"), "cancel", this); + + const int width = 200; + const int height = 130; + setContentSize(width, height); + + accountLabel->setPosition(5, 5); + accountLabel->setWidth(130); + + newEmailLabel->setPosition( + 5, accountLabel->getY() + accountLabel->getHeight() + 7); + newEmailLabel->setWidth(width - 5); + + mFirstEmailField->setPosition( + 5, newEmailLabel->getY() + newEmailLabel->getHeight() + 7); + mFirstEmailField->setWidth(130); + + mSecondEmailField->setPosition( + 5, mFirstEmailField->getY() + mFirstEmailField->getHeight() + 7); + mSecondEmailField->setWidth(130); + + mCancelButton->setPosition( + width - 5 - mCancelButton->getWidth(), + height - 5 - mCancelButton->getHeight()); + mChangeEmailButton->setPosition( + mCancelButton->getX() - 5 - mChangeEmailButton->getWidth(), + mCancelButton->getY()); + + add(accountLabel); + add(newEmailLabel); + add(mFirstEmailField); + add(mSecondEmailField); + add(mChangeEmailButton); + add(mCancelButton); + + setLocationRelativeTo(getParent()); + setVisible(true); + mFirstEmailField->requestFocus(); + + mFirstEmailField->setActionEventId("change_email"); + mSecondEmailField->setActionEventId("change_email"); +} + +ChangeEmailDialog::~ChangeEmailDialog() +{ + delete mWrongDataNoticeListener; +} + +void +ChangeEmailDialog::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "cancel") + { + scheduleDelete(); + } + else if (event.getId() == "change_email") + { + + const std::string username = mLoginData->username.c_str(); + const std::string newFirstEmail = mFirstEmailField->getText(); + const std::string newSecondEmail = mSecondEmailField->getText(); + logger->log("ChangeEmailDialog::Email change, Username is %s", + username.c_str()); + + std::stringstream errorMsg; + int error = 0; + + if (newFirstEmail.length() < LEN_MIN_PASSWORD) + { + // First email address too short + errorMsg << "The new email address needs to be at least " + << LEN_MIN_PASSWORD + << " characters long."; + error = 1; + } + else if (newFirstEmail.length() > LEN_MAX_PASSWORD - 1 ) + { + // First email address too long + errorMsg << "The new email address needs to be less than " + << LEN_MAX_PASSWORD + << " characters long."; + error = 1; + } + else if (newFirstEmail != newSecondEmail) + { + // Second Pass mismatch + errorMsg << "The email address entries mismatch."; + error = 2; + } + + if (error > 0) + { + if (error == 1) + { + mWrongDataNoticeListener->setTarget(this->mFirstEmailField); + } + else if (error == 2) + { + mWrongDataNoticeListener->setTarget(this->mSecondEmailField); + } + + OkDialog *dlg = new OkDialog("Error", errorMsg.str()); + dlg->addActionListener(mWrongDataNoticeListener); + } + else + { + // No errors detected, change account password. + mChangeEmailButton->setEnabled(false); + // Set the new email address + mLoginData->newEmail = newFirstEmail; + state = STATE_CHANGEEMAIL_ATTEMPT; + scheduleDelete(); + } + + } +} diff --git a/src/gui/changeemaildialog.h b/src/gui/changeemaildialog.h new file mode 100644 index 00000000..145c54b1 --- /dev/null +++ b/src/gui/changeemaildialog.h @@ -0,0 +1,72 @@ +/* + * The Mana World + * Copyright (C) 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef GUI_CHANGEEMAIL_H +#define GUI_CHANGEEMAIL_H + +#include <iosfwd> +#include <guichan/actionlistener.hpp> + +#include "window.h" +#include "../guichanfwd.h" + +class LoginData; +class OkDialog; +class WrongDataNoticeListener; + +/** + * The Change email dialog. + * + * \ingroup Interface + */ +class ChangeEmailDialog : public Window, public gcn::ActionListener +{ + public: + /** + * Constructor. + * + * @see Window::Window + */ + ChangeEmailDialog(Window *parent, LoginData *loginData); + + /** + * Destructor. + */ + ~ChangeEmailDialog(); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + private: + gcn::TextField *mFirstEmailField; + gcn::TextField *mSecondEmailField; + + gcn::Button *mChangeEmailButton; + gcn::Button *mCancelButton; + + WrongDataNoticeListener *mWrongDataNoticeListener; + + LoginData *mLoginData; +}; + +#endif // GUI_CHANGEEMAIL_H diff --git a/src/gui/changepassworddialog.cpp b/src/gui/changepassworddialog.cpp new file mode 100644 index 00000000..7c1e5bcd --- /dev/null +++ b/src/gui/changepassworddialog.cpp @@ -0,0 +1,193 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "changepassworddialog.h" + +#include <string> +#include <sstream> + +#include <guichan/widgets/label.hpp> + +#include "../main.h" +#include "../log.h" +#include "../logindata.h" + +#include "button.h" +#include "register.h" +#include "passwordfield.h" +#include "textfield.h" +#include "ok_dialog.h" + +#include "../utils/gettext.h" +#include "../utils/strprintf.h" + +ChangePasswordDialog::ChangePasswordDialog(Window *parent, LoginData *loginData): + Window(_("Change Password"), true, parent), + mWrongDataNoticeListener(new WrongDataNoticeListener()), + mLoginData(loginData) +{ + gcn::Label *accountLabel = new gcn::Label(strprintf(_("Account: %s"), + mLoginData->username.c_str())); + gcn::Label *oldPassLabel = new gcn::Label(_("Password:")); + mOldPassField = new PasswordField(); + gcn::Label *newPassLabel = new gcn::Label(_("Type New Password twice:")); + mFirstPassField = new PasswordField(); + mSecondPassField = new PasswordField(); + mChangePassButton = new Button(_("Change Password"), "change_password", this); + mCancelButton = new Button(_("Cancel"), "cancel", this); + + const int width = 200; + const int height = 170; + setContentSize(width, height); + + accountLabel->setPosition(5, 5); + accountLabel->setWidth(130); + oldPassLabel->setPosition( + 5, accountLabel->getY() + accountLabel->getHeight() + 7); + oldPassLabel->setWidth(130); + + mOldPassField->setPosition( + 5, oldPassLabel->getY() + oldPassLabel->getHeight() + 7); + mOldPassField->setWidth(130); + + newPassLabel->setPosition( + 5, mOldPassField->getY() + mOldPassField->getHeight() + 7); + newPassLabel->setWidth(width - 5); + + mFirstPassField->setPosition( + 5, newPassLabel->getY() + newPassLabel->getHeight() + 7); + mFirstPassField->setWidth(130); + + mSecondPassField->setPosition( + 5, mFirstPassField->getY() + mFirstPassField->getHeight() + 7); + mSecondPassField->setWidth(130); + + mCancelButton->setPosition( + width - 5 - mCancelButton->getWidth(), + height - 5 - mCancelButton->getHeight()); + mChangePassButton->setPosition( + mCancelButton->getX() - 5 - mChangePassButton->getWidth(), + mCancelButton->getY()); + + add(accountLabel); + add(oldPassLabel); + add(mOldPassField); + add(newPassLabel); + add(mFirstPassField); + add(mSecondPassField); + add(mChangePassButton); + add(mCancelButton); + + setLocationRelativeTo(getParent()); + setVisible(true); + mOldPassField->requestFocus(); + + mOldPassField->setActionEventId("change_password"); + mFirstPassField->setActionEventId("change_password"); + mSecondPassField->setActionEventId("change_password"); +} + +ChangePasswordDialog::~ChangePasswordDialog() +{ + delete mWrongDataNoticeListener; +} + +void +ChangePasswordDialog::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "cancel") + { + scheduleDelete(); + } + else if (event.getId() == "change_password") + { + + const std::string username = mLoginData->username.c_str(); + const std::string oldPassword = mOldPassField->getText(); + const std::string newFirstPass = mFirstPassField->getText(); + const std::string newSecondPass = mSecondPassField->getText(); + logger->log("ChangePasswordDialog::Password change, Username is %s", + username.c_str()); + + std::stringstream errorMsg; + int error = 0; + + // Check old Password + if (oldPassword.empty()) + { + // No old password + errorMsg << "Enter the old Password first."; + error = 1; + } + else if (newFirstPass.length() < LEN_MIN_PASSWORD) + { + // First password too short + errorMsg << "The new password needs to be at least " + << LEN_MIN_PASSWORD + << " characters long."; + error = 2; + } + else if (newFirstPass.length() > LEN_MAX_PASSWORD - 1 ) + { + // First password too long + errorMsg << "The new password needs to be less than " + << LEN_MAX_PASSWORD + << " characters long."; + error = 2; + } + else if (newFirstPass != newSecondPass) + { + // Second Pass mismatch + errorMsg << "The new password entries mismatch."; + error = 3; + } + + if (error > 0) + { + if (error == 1) + { + mWrongDataNoticeListener->setTarget(this->mOldPassField); + } + else if (error == 2) + { + mWrongDataNoticeListener->setTarget(this->mFirstPassField); + } + else if (error == 3) + { + mWrongDataNoticeListener->setTarget(this->mSecondPassField); + } + + OkDialog *dlg = new OkDialog("Error", errorMsg.str()); + dlg->addActionListener(mWrongDataNoticeListener); + } + else + { + // No errors detected, change account password. + mChangePassButton->setEnabled(false); + // Set the new password + mLoginData->password = oldPassword; + mLoginData->newPassword = newFirstPass; + state = STATE_CHANGEPASSWORD_ATTEMPT; + scheduleDelete(); + } + + } +} diff --git a/src/gui/changepassworddialog.h b/src/gui/changepassworddialog.h new file mode 100644 index 00000000..ad1c0b2a --- /dev/null +++ b/src/gui/changepassworddialog.h @@ -0,0 +1,72 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef CHANGEPASSWORDDIALOG_H +#define CHANGEPASSWORDDIALOG_H + +#include <iosfwd> +#include <guichan/actionlistener.hpp> + +#include "window.h" +#include "../guichanfwd.h" + +class LoginData; +class OkDialog; +class WrongDataNoticeListener; + +/** + * The Change password dialog. + * + * \ingroup Interface + */ +class ChangePasswordDialog : public Window, public gcn::ActionListener { + public: + /** + * Constructor + * + * @see Window::Window + */ + ChangePasswordDialog(Window *parent,LoginData *loginData); + + /** + * Destructor + */ + ~ChangePasswordDialog(); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + private: + gcn::TextField *mOldPassField; + gcn::TextField *mFirstPassField; + gcn::TextField *mSecondPassField; + + gcn::Button *mChangePassButton; + gcn::Button *mCancelButton; + + WrongDataNoticeListener *mWrongDataNoticeListener; + + LoginData *mLoginData; +}; + +#endif diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp index f88736c1..4ab3d9ef 100644 --- a/src/gui/char_select.cpp +++ b/src/gui/char_select.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,13 +31,29 @@ #include "playerbox.h" #include "textfield.h" +#ifdef TMWSERV_SUPPORT +#include "radiobutton.h" +#include "slider.h" + +#include "unregisterdialog.h" +#include "changepassworddialog.h" +#include "changeemaildialog.h" + +#include "../logindata.h" + +#include "../net/tmwserv/accountserver/account.h" +#include "../net/tmwserv/charserverhandler.h" +#else +#include "../net/ea/charserverhandler.h" +#endif + #include "widgets/layout.h" #include "../game.h" #include "../localplayer.h" #include "../main.h" +#include "../units.h" -#include "../net/charserverhandler.h" #include "../net/messageout.h" #include "../resources/colordb.h" @@ -47,6 +62,8 @@ #include "../utils/strprintf.h" #include "../utils/stringutils.h" +#define MAX_SLOT 2 + // Defined in main.cpp, used here for setting the char create dialog extern CharServerHandler charServerHandler; @@ -79,30 +96,80 @@ void CharDeleteConfirm::action(const gcn::ActionEvent &event) ConfirmDialog::action(event); } +#ifdef TMWSERV_SUPPORT +CharSelectDialog::CharSelectDialog(LockedArray<LocalPlayer*> *charInfo, + LoginData *loginData): + Window(_("Account and Character Management")), + mCharInfo(charInfo), mCharSelected(false), mLoginData(loginData) +#else CharSelectDialog::CharSelectDialog(Network *network, LockedArray<LocalPlayer*> *charInfo, Gender gender): Window(_("Select Character")), mNetwork(network), - mCharInfo(charInfo), mGender(gender), mCharSelected(false) + mCharInfo(charInfo), + mCharSelected(false), + mGender(gender) +#endif { + mSelectButton = new Button(_("Ok"), "ok", this); + mCancelButton = new Button(_("Cancel"), "cancel", this); + mPreviousButton = new Button(_("Previous"), "previous", this); + mNextButton = new Button(_("Next"), "next", this); + mNameLabel = new Label(strprintf(_("Name: %s"), "")); + mLevelLabel = new Label(strprintf(_("Level: %d"), 0)); +#ifdef TMWSERV_SUPPORT + mNewCharButton = new Button(_("New"), "new", this); + mDelCharButton = new Button(_("Delete"), "delete", this); + mUnRegisterButton = new Button(_("Unregister"), "unregister", this); + mChangePasswordButton = new Button(_("Change Password"), "change_password", this); + mChangeEmailButton = new Button(_("Change Email Address"), "change_email", this); + + mAccountNameLabel = new Label(strprintf(_("Account: %s"), mLoginData->username.c_str())); + mNameLabel = new Label(strprintf(_("Name: %s"), "")); + mLevelLabel = new Label(strprintf(_("Level: %d"), 0)); + mMoneyLabel = new Label(strprintf(_("Money: %d"), 0)); + + // Control that shows the Player + mPlayerBox = new PlayerBox; + mPlayerBox->setWidth(74); + + ContainerPlacer place; + place = getPlacer(0, 0); + place(0, 0, mAccountNameLabel); + place(0, 1, mUnRegisterButton); + place(0, 2, mChangePasswordButton); + place(1, 2, mChangeEmailButton); + place = getPlacer(0, 1); + place(0, 0, mPlayerBox, 1, 5).setPadding(3); + place(1, 0, mNameLabel, 3); + place(1, 1, mLevelLabel, 3); + place(1, 2, mMoneyLabel, 3); + place(1, 3, mPreviousButton); + place(2, 3, mNextButton); + place(1, 4, mNewCharButton); + place(2, 4, mDelCharButton); + place.getCell().matchColWidth(1, 2); + place = getPlacer(0, 2); + place(0, 0, mSelectButton); + place(1, 0, mCancelButton); + reflowLayout(265, 0); +#else + mCharInfo->select(0); + LocalPlayer *pi = mCharInfo->getEntry(); + if (pi) + mMoney = Units::formatCurrency(pi->getMoney()); // Control that shows the Player mPlayerBox = new PlayerBox; mPlayerBox->setWidth(74); - mNameLabel = new Label(strprintf(_("Name: %s"), "")); - mLevelLabel = new Label(strprintf(_("Level: %d"), 0)); mJobLevelLabel = new Label(strprintf(_("Job Level: %d"), 0)); - mMoneyLabel = new Label(strprintf(_("Money: %d"), 0)); + mMoneyLabel = new Label(strprintf(_("Money: %s"), mMoney.c_str())); const std::string tempString = getFont()->getWidth(_("New")) < getFont()->getWidth(_("Delete")) ? _("Delete") : _("New"); - mPreviousButton = new Button(_("Previous"), "previous", this); - mNextButton = new Button(_("Next"), "next", this); mNewDelCharButton = new Button(tempString, "newdel", this); - mSelectButton = new Button(_("Ok"), "ok", this); - mCancelButton = new Button(_("Cancel"), "cancel", this); ContainerPlacer place; place = getPlacer(0, 0); @@ -121,8 +188,9 @@ CharSelectDialog::CharSelectDialog(Network *network, place(5, 0, mSelectButton); reflowLayout(250, 0); +#endif - setLocationRelativeTo(getParent()); + center(); setVisible(true); mSelectButton->requestFocus(); updatePlayerInfo(); @@ -130,10 +198,21 @@ CharSelectDialog::CharSelectDialog(Network *network, void CharSelectDialog::action(const gcn::ActionEvent &event) { +#ifdef TMWSERV_SUPPORT + // The pointers are set to NULL if there is no character stored + if (event.getId() == "ok" && (mCharInfo->getEntry())) +#else if (event.getId() == "ok" && n_character > 0) +#endif { // Start game +#ifdef TMWSERV_SUPPORT + mNewCharButton->setEnabled(false); + mDelCharButton->setEnabled(false); + mUnRegisterButton->setEnabled(false); +#else mNewDelCharButton->setEnabled(false); +#endif mSelectButton->setEnabled(false); mPreviousButton->setEnabled(false); mNextButton->setEnabled(false); @@ -142,8 +221,35 @@ void CharSelectDialog::action(const gcn::ActionEvent &event) } else if (event.getId() == "cancel") { - state = EXIT_STATE; +#ifdef TMWSERV_SUPPORT + mCharInfo->clear(); + state = STATE_SWITCH_ACCOUNTSERVER_ATTEMPT; +#else + state = STATE_EXIT; +#endif + } +#ifdef TMWSERV_SUPPORT + else if (event.getId() == "new") + { + // TODO: Search the first free slot, and start CharCreateDialog + // maybe add that search to the constructor. + if (!(mCharInfo->getEntry())) + { + // Start new character dialog + CharCreateDialog *charCreateDialog = + new CharCreateDialog(this, mCharInfo->getPos()); + charServerHandler.setCharCreateDialog(charCreateDialog); + } + } + else if (event.getId() == "delete") + { + // Delete character + if (mCharInfo->getEntry()) + { + new CharDeleteConfirm(this); + } } +#else else if (event.getId() == "newdel") { // Check for a character @@ -160,14 +266,35 @@ void CharSelectDialog::action(const gcn::ActionEvent &event) charServerHandler.setCharCreateDialog(charCreateDialog); } } +#endif else if (event.getId() == "previous") { mCharInfo->prev(); + LocalPlayer *pi = mCharInfo->getEntry(); + if (pi) + mMoney = Units::formatCurrency(pi->getMoney()); } else if (event.getId() == "next") { mCharInfo->next(); + LocalPlayer *pi = mCharInfo->getEntry(); + if (pi) + mMoney = Units::formatCurrency(pi->getMoney()); + } +#ifdef TMWSERV_SUPPORT + else if (event.getId() == "unregister") + { + new UnRegisterDialog(this, mLoginData); + } + else if (event.getId() == "change_password") + { + new ChangePasswordDialog(this, mLoginData); } + else if (event.getId() == "change_email") + { + new ChangeEmailDialog(this, mLoginData); + } +#endif } void CharSelectDialog::updatePlayerInfo() @@ -176,13 +303,22 @@ void CharSelectDialog::updatePlayerInfo() if (pi) { - mNameLabel->setCaption(strprintf(_("Name: %s"), pi->getName().c_str())); - mLevelLabel->setCaption(strprintf(_("Level: %d"), pi->mLevel)); - mJobLevelLabel->setCaption(strprintf(_("Job Level: %d"), pi->mJobLevel)); - mMoneyLabel->setCaption(strprintf(_("Gold: %d"), pi->mGp)); + mNameLabel->setCaption(strprintf(_("Name: %s"), + pi->getName().c_str())); + mLevelLabel->setCaption(strprintf(_("Level: %d"), pi->getLevel())); +#ifndef TMWSERV_SUPPORT + mJobLevelLabel->setCaption(strprintf(_("Job Level: %d"), + pi->mJobLevel)); +#endif + mMoneyLabel->setCaption(strprintf(_("Money: %s"), mMoney.c_str())); if (!mCharSelected) { +#ifdef TMWSERV_SUPPORT + mNewCharButton->setEnabled(false); + mDelCharButton->setEnabled(true); +#else mNewDelCharButton->setCaption(_("Delete")); +#endif mSelectButton->setEnabled(true); } } @@ -190,9 +326,16 @@ void CharSelectDialog::updatePlayerInfo() { mNameLabel->setCaption(strprintf(_("Name: %s"), "")); mLevelLabel->setCaption(strprintf(_("Level: %d"), 0)); +#ifndef TMWSERV_SUPPORT mJobLevelLabel->setCaption(strprintf(_("Job Level: %d"), 0)); +#endif mMoneyLabel->setCaption(strprintf(_("Money: %s"), "")); +#ifdef TMWSERV_SUPPORT + mNewCharButton->setEnabled(true); + mDelCharButton->setEnabled(false); +#else mNewDelCharButton->setCaption(_("New")); +#endif mSelectButton->setEnabled(false); } @@ -201,20 +344,28 @@ void CharSelectDialog::updatePlayerInfo() void CharSelectDialog::attemptCharDelete() { +#ifdef TMWSERV_SUPPORT + Net::AccountServer::Account::deleteCharacter(mCharInfo->getPos()); +#else // Request character deletion MessageOut outMsg(mNetwork); outMsg.writeInt16(0x0068); outMsg.writeInt32(mCharInfo->getEntry()->mCharId); outMsg.writeString("a@a.com", 40); +#endif mCharInfo->lock(); } void CharSelectDialog::attemptCharSelect() { +#ifdef TMWSERV_SUPPORT + Net::AccountServer::Account::selectCharacter(mCharInfo->getPos()); +#else // Request character selection MessageOut outMsg(mNetwork); outMsg.writeInt16(0x0066); outMsg.writeInt8(mCharInfo->getPos()); +#endif mCharInfo->lock(); } @@ -246,16 +397,29 @@ bool CharSelectDialog::selectByName(const std::string &name) return false; } +#ifdef TMWSERV_SUPPORT +CharCreateDialog::CharCreateDialog(Window *parent, int slot): +#else CharCreateDialog::CharCreateDialog(Window *parent, int slot, Network *network, Gender gender): - Window(_("Create Character"), true, parent), mNetwork(network), mSlot(slot) +#endif + Window(_("Create Character"), true, parent), +#ifndef TMWSERV_SUPPORT + mNetwork(network), +#endif + mSlot(slot) { mPlayer = new Player(0, 0, NULL); +#ifdef TMWSERV_SUPPORT + mPlayer->setGender(GENDER_MALE); +#else mPlayer->setGender(gender); +#endif int numberOfHairColors = ColorDB::size(); - mPlayer->setHairStyle(rand() % mPlayer->getNumOfHairstyles(), rand() % numberOfHairColors); + mPlayer->setHairStyle(rand() % mPlayer->getNumOfHairstyles(), + rand() % numberOfHairColors); mNameField = new TextField(""); mNameLabel = new Label(_("Name:")); @@ -267,6 +431,19 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot, Network *network, mHairStyleLabel = new Label(_("Hair Style:")); mCreateButton = new Button(_("Create"), "create", this); mCancelButton = new Button(_("Cancel"), "cancel", this); +#ifdef TMWSERV_SUPPORT + mMale = new RadioButton(_("Male"), "gender"); + mFemale = new RadioButton(_("Female"), "gender"); + + // Default to a Male character + mMale->setSelected(true); + + mMale->setActionEventId("gender"); + mFemale->setActionEventId("gender"); + + mMale->addActionListener(this); + mFemale->addActionListener(this); +#endif mPlayerBox = new PlayerBox(mPlayer); mPlayerBox->setWidth(74); @@ -274,6 +451,81 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot, Network *network, mNameField->setActionEventId("create"); mNameField->addActionListener(this); +#ifdef TMWSERV_SUPPORT + mAttributeLabel[0] = new gcn::Label(_("Strength:")); + mAttributeLabel[1] = new gcn::Label(_("Agility:")); + mAttributeLabel[2] = new gcn::Label(_("Dexterity:")); + mAttributeLabel[3] = new gcn::Label(_("Vitality:")); + mAttributeLabel[4] = new gcn::Label(_("Intelligence:")); + mAttributeLabel[5] = new gcn::Label(_("Willpower:")); + for (int i = 0; i < 6; i++) + { + mAttributeLabel[i]->setWidth(70); + mAttributeSlider[i] = new Slider(1, 20); + mAttributeValue[i] = new gcn::Label("1"); + }; + + mAttributesLeft = new gcn::Label(strprintf(_("Please distribute %d points"), 99)); + + int w = 200; + int h = 330; + setContentSize(w, h); + mPlayerBox->setDimension(gcn::Rectangle(80, 30, 110, 85)); + mNameLabel->setPosition(5, 5); + mNameField->setDimension( + gcn::Rectangle(45, 5, w - 45 - 7, mNameField->getHeight())); + mPrevHairColorButton->setPosition(90, 35); + mNextHairColorButton->setPosition(165, 35); + mHairColorLabel->setPosition(5, 40); + mPrevHairStyleButton->setPosition(90, 64); + mNextHairStyleButton->setPosition(165, 64); + mHairStyleLabel->setPosition(5, 70); + for (int i=0; i<6; i++) + { + mAttributeSlider[i]->setValue(10); + mAttributeSlider[i]->setDimension(gcn::Rectangle( 75, 140 + i*20, + 100, 10)); + mAttributeSlider[i]->setActionEventId("statslider"); + mAttributeSlider[i]->addActionListener(this); + mAttributeValue[i]->setPosition(180, 140 + i*20); + mAttributeLabel[i]->setPosition(5, 140 + i*20); + }; + mAttributesLeft->setPosition(15, 280); + updateSliders(); + mCancelButton->setPosition( + w - 5 - mCancelButton->getWidth(), + h - 5 - mCancelButton->getHeight()); + mCreateButton->setPosition( + mCancelButton->getX() - 5 - mCreateButton->getWidth(), + h - 5 - mCancelButton->getHeight()); + + mMale->setPosition(30, 120); + mFemale->setPosition(100, 120); + + add(mPlayerBox); + add(mNameField); + add(mNameLabel); + add(mNextHairColorButton); + add(mPrevHairColorButton); + add(mHairColorLabel); + add(mNextHairStyleButton); + add(mPrevHairStyleButton); + add(mHairStyleLabel); + for (int i = 0; i < 6; i++) + { + add(mAttributeSlider[i]); + add(mAttributeValue[i]); + add(mAttributeLabel[i]); + }; + add(mAttributesLeft); + add(mCreateButton); + add(mCancelButton); + + add(mMale); + add(mFemale); + +#else + ContainerPlacer place; place = getPlacer(0, 0); @@ -292,8 +544,9 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot, Network *network, place(5, 0, mCreateButton); reflowLayout(225, 0); +#endif - setLocationRelativeTo(getParent()); + center(); setVisible(true); mNameField->requestFocus(); } @@ -315,12 +568,35 @@ void CharCreateDialog::action(const gcn::ActionEvent &event) { // Attempt to create the character mCreateButton->setEnabled(false); +#ifdef TMWSERV_SUPPORT + unsigned int genderSelected; + if (mMale->isSelected()) { + genderSelected = GENDER_MALE; + } else { + genderSelected = GENDER_FEMALE; + } + + Net::AccountServer::Account::createCharacter( + getName(), + mPlayer->getHairStyle(), + mPlayer->getHairColor(), + genderSelected, // gender + (int) mAttributeSlider[0]->getValue(), // STR + (int) mAttributeSlider[1]->getValue(), // AGI + (int) mAttributeSlider[2]->getValue(), // DEX + (int) mAttributeSlider[3]->getValue(), // VIT + (int) mAttributeSlider[4]->getValue(), // INT + (int) mAttributeSlider[5]->getValue() // WILL + ); +#else attemptCharCreate(); +#endif } else { - new OkDialog("Error", - "Your name needs to be at least 4 characters.", this); + new OkDialog(_("Error"), + _("Your name needs to be at least 4 characters."), + this); } } else if (event.getId() == "cancel") @@ -339,6 +615,18 @@ void CharCreateDialog::action(const gcn::ActionEvent &event) mPlayer->setHairStyle(mPlayer->getHairStyle() + mPlayer->getNumOfHairstyles() - 1, mPlayer->getHairColor()); +#ifdef TMWSERV_SUPPORT + else if (event.getId() == "statslider") { + updateSliders(); + } + else if (event.getId() == "gender"){ + if (mMale->isSelected()) { + mPlayer->setGender(GENDER_MALE); + } else { + mPlayer->setGender(GENDER_FEMALE); + } + } +#endif } std::string CharCreateDialog::getName() @@ -348,11 +636,60 @@ std::string CharCreateDialog::getName() return name; } +#ifdef TMWSERV_SUPPORT +void CharCreateDialog::updateSliders() +{ + for (int i = 0; i < 6; i++) + { + // Update captions + mAttributeValue[i]->setCaption( + toString((int) (mAttributeSlider[i]->getValue()))); + mAttributeValue[i]->adjustSize(); + } + + // Update distributed points + int pointsLeft = 60 - getDistributedPoints(); + if (pointsLeft == 0) + { + mAttributesLeft->setCaption(_("Character stats OK")); + mCreateButton->setEnabled(true); + } + else + { + mCreateButton->setEnabled(false); + if (pointsLeft > 0) + { + mAttributesLeft->setCaption(strprintf(_("Please distribute %d points"), pointsLeft)); + } + else + { + mAttributesLeft->setCaption(strprintf(_("Please remove %d points"), -pointsLeft)); + } + } + + mAttributesLeft->adjustSize(); +} +#endif + void CharCreateDialog::unlock() { mCreateButton->setEnabled(true); } +#ifdef TMWSERV_SUPPORT +int CharCreateDialog::getDistributedPoints() +{ + int points = 0; + + for (int i = 0; i < 6; i++) + { + points += (int) mAttributeSlider[i]->getValue(); + } + return points; +} +#endif + +#ifndef TMWSERV_SUPPORT void CharCreateDialog::attemptCharCreate() { // Send character infos @@ -369,3 +706,4 @@ void CharCreateDialog::attemptCharCreate() outMsg.writeInt16(mPlayer->getHairColor()); outMsg.writeInt16(mPlayer->getHairStyle()); } +#endif diff --git a/src/gui/char_select.h b/src/gui/char_select.h index 037b809f..7f376692 100644 --- a/src/gui/char_select.h +++ b/src/gui/char_select.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,10 +27,16 @@ #include "window.h" #include "../being.h" +#include "../guichanfwd.h" #include "../lockedarray.h" -class LocalPlayer; +#ifdef TMWSERV_SUPPORT +#include "../logindata.h" +#else class Network; +#endif + +class LocalPlayer; class Player; class PlayerBox; @@ -47,9 +52,14 @@ class CharSelectDialog : public Window, public gcn::ActionListener /** * Constructor. */ +#ifdef TMWSERV_SUPPORT + CharSelectDialog(LockedArray<LocalPlayer*> *charInfo, + LoginData *loginData); +#else CharSelectDialog(Network *network, LockedArray<LocalPlayer*> *charInfo, Gender gender); +#endif void action(const gcn::ActionEvent &event); @@ -60,25 +70,40 @@ class CharSelectDialog : public Window, public gcn::ActionListener bool selectByName(const std::string &name); private: +#ifdef EATHENA_SUPPORT Network *mNetwork; +#endif LockedArray<LocalPlayer*> *mCharInfo; gcn::Button *mSelectButton; gcn::Button *mCancelButton; - gcn::Button *mNewDelCharButton; gcn::Button *mPreviousButton; gcn::Button *mNextButton; gcn::Label *mNameLabel; gcn::Label *mLevelLabel; - gcn::Label *mJobLevelLabel; gcn::Label *mMoneyLabel; + std::string mMoney; PlayerBox *mPlayerBox; - Gender mGender; bool mCharSelected; +#ifdef TMWSERV_SUPPORT + gcn::Button *mNewCharButton; + gcn::Button *mDelCharButton; + gcn::Button *mUnRegisterButton; + gcn::Button *mChangePasswordButton; + gcn::Button *mChangeEmailButton; + gcn::Label *mAccountNameLabel; + + LoginData *mLoginData; +#else + gcn::Button *mNewDelCharButton; + gcn::Label *mJobLevelLabel; + Gender mGender; +#endif + /** * Communicate character deletion to the server. */ @@ -93,7 +118,7 @@ class CharSelectDialog : public Window, public gcn::ActionListener /** * Character creation dialog. * - * \ingroup GUI + * \ingroup Interface */ class CharCreateDialog : public Window, public gcn::ActionListener { @@ -101,8 +126,12 @@ class CharCreateDialog : public Window, public gcn::ActionListener /** * Constructor. */ +#ifdef TMWSERV_SUPPORT + CharCreateDialog(Window *parent, int slot); +#else CharCreateDialog(Window *parent, int slot, Network *network, Gender gender); +#endif /** * Destructor. @@ -117,6 +146,12 @@ class CharCreateDialog : public Window, public gcn::ActionListener void unlock(); private: +#ifdef TMWSERV_SUPPORT + int getDistributedPoints(); + + void updateSliders(); +#endif + /** * Returns the name of the character to create. */ @@ -127,7 +162,9 @@ class CharCreateDialog : public Window, public gcn::ActionListener */ void attemptCharCreate(); +#ifdef EATHENA_SUPPORT Network *mNetwork; +#endif gcn::TextField *mNameField; gcn::Label *mNameLabel; gcn::Button *mNextHairColorButton; @@ -136,6 +173,20 @@ class CharCreateDialog : public Window, public gcn::ActionListener gcn::Button *mNextHairStyleButton; gcn::Button *mPrevHairStyleButton; gcn::Label *mHairStyleLabel; + +#ifdef TMWSERV_SUPPORT + gcn::RadioButton *mMale; + gcn::RadioButton *mFemale; + + gcn::Slider *mAttributeSlider[6]; + gcn::Label *mAttributeLabel[6]; + gcn::Label *mAttributeValue[6]; + gcn::Label *mAttributesLeft; + + static const int mMaxPoints = 60; + int mUsedPoints; +#endif + gcn::Button *mCreateButton; gcn::Button *mCancelButton; diff --git a/src/gui/char_server.cpp b/src/gui/char_server.cpp index 6977a104..5cfcef4d 100644 --- a/src/gui/char_server.cpp +++ b/src/gui/char_server.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -51,7 +50,7 @@ ServerSelectDialog::ServerSelectDialog(LoginData *loginData, int nextState): mLoginData(loginData), mNextState(nextState) { - mServerListModel = new ServerListModel(); + mServerListModel = new ServerListModel; mServerList = new ListBox(mServerListModel); ScrollArea *mScrollArea = new ScrollArea(mServerList); mOkButton = new Button(_("OK"), "ok", this); @@ -86,7 +85,7 @@ ServerSelectDialog::ServerSelectDialog(LoginData *loginData, int nextState): // Select first server mServerList->setSelected(1); - setLocationRelativeTo(getParent()); + center(); setVisible(true); mOkButton->requestFocus(); } @@ -108,7 +107,7 @@ void ServerSelectDialog::action(const gcn::ActionEvent &event) state = mNextState; } else if (event.getId() == "cancel") - state = LOGIN_STATE; + state = STATE_LOGIN; } int ServerListModel::getNumberOfElements() diff --git a/src/gui/char_server.h b/src/gui/char_server.h index 207fb86e..49a5b47b 100644 --- a/src/gui/char_server.h +++ b/src/gui/char_server.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index 5ff9ed46..7861bdb6 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,68 +19,52 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <guichan/focushandler.hpp> - -#include "browserbox.h" #include "chat.h" -#include "chatinput.h" -#include "itemlinkhandler.h" -#include "recorder.h" -#include "scrollarea.h" -#include "sdlinput.h" -#include "windowcontainer.h" -#include "widgets/layout.h" +#include "gui/chatinput.h" +#include "gui/itemlinkhandler.h" +#include "gui/recorder.h" +#include "gui/scrollarea.h" +#include "gui/sdlinput.h" -#include "../beingmanager.h" -#include "../configuration.h" -#include "../game.h" -#include "../localplayer.h" -#include "../party.h" +#include "gui/widgets/tabbedarea.h" +#include "gui/widgets/whispertab.h" -#include "../net/messageout.h" -#include "../net/protocol.h" +#include "beingmanager.h" +#include "configuration.h" +#include "localplayer.h" -#include "../resources/iteminfo.h" -#include "../resources/itemdb.h" +#include "utils/dtor.h" +#include "utils/stringutils.h" -#include "../utils/gettext.h" -#include "../utils/strprintf.h" -#include "../utils/stringutils.h" +#include <guichan/focushandler.hpp> +#ifdef TMWSERV_SUPPORT +ChatWindow::ChatWindow(): + Window("Chat"), +#else ChatWindow::ChatWindow(Network * network): -Window(""), mNetwork(network), mTmpVisible(false) + Window(""), mNetwork(network), +#endif + mTmpVisible(false) { - setWindowName(_("Chat")); + setWindowName("Chat"); setResizable(true); setDefaultSize(600, 123, ImageRect::LOWER_LEFT); setMinWidth(150); setMinHeight(90); - mItemLinkHandler = new ItemLinkHandler(); + mItemLinkHandler = new ItemLinkHandler; mChatInput = new ChatInput; mChatInput->setActionEventId("chatinput"); mChatInput->addActionListener(this); - mTextOutput = new BrowserBox(BrowserBox::AUTO_WRAP); - mTextOutput->setOpaque(false); - mTextOutput->setMaxRow((int) config.getValue("ChatLogLength", 0)); - mTextOutput->setLinkHandler(mItemLinkHandler); - - mScrollArea = new ScrollArea(mTextOutput); - mScrollArea->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER, - gcn::ScrollArea::SHOW_ALWAYS); - mScrollArea->setScrollAmount(0, 1); - mScrollArea->setOpaque(false); + mChatTabs = new TabbedArea(); - place(0, 0, mScrollArea, 5, 5).setPadding(0); - place(0, 5, mChatInput, 5).setPadding(1); - - Layout &layout = getLayout(); - layout.setRowHeight(0, Layout::AUTO_SET); - layout.setMargin(2); + add(mChatTabs); + add(mChatInput); loadWindowState(); @@ -89,28 +72,33 @@ Window(""), mNetwork(network), mTmpVisible(false) mChatInput->addKeyListener(this); mCurHist = mHistory.end(); +#ifdef EATHENA_SUPPORT // Read the party prefix std::string partyPrefix = config.getValue("PartyPrefix", "$"); mPartyPrefix = (partyPrefix.empty() ? '$' : partyPrefix.at(0)); mReturnToggles = config.getValue("ReturnToggles", "0") == "1"; - mRecorder = new Recorder(this); - mParty = new Party(this, mNetwork); // If the player had @assert on in the last session, ask the server to // run the @assert command for the player again. Convenience for GMs. - if (config.getValue(player_node->getName() + "GMassert", 0)) - chatSend(player_node->getName(), "@assert"); + if (config.getValue(player_node->getName() + "GMassert", 0)) { + std::string cmd = "@assert"; + chatSend(cmd); + } +#endif + mRecorder = new Recorder(this); } ChatWindow::~ChatWindow() { +#ifdef EATHENA_SUPPORT char partyPrefix[2] = "."; *partyPrefix = mPartyPrefix; config.setValue("PartyPrefix", partyPrefix); config.setValue("ReturnToggles", mReturnToggles ? "1" : "0"); delete mRecorder; +#endif + delete_all(mWhispers); delete mItemLinkHandler; - delete mParty; } void ChatWindow::resetToDefaultSize() @@ -119,178 +107,63 @@ void ChatWindow::resetToDefaultSize() Window::resetToDefaultSize(); } -void ChatWindow::chatLog(std::string line, int own, bool ignoreRecord) +void ChatWindow::adjustTabSize() { - // Trim whitespace - trim(line); - - if (line.empty()) - return; - - CHATLOG tmp; - tmp.own = own; - tmp.nick = ""; - tmp.text = line; - - std::string::size_type pos = line.find(" : "); - if (pos != std::string::npos) - { - tmp.nick = line.substr(0, pos); - tmp.text = line.substr(pos + 3); - } - else - { - // Fix the owner of welcome message. - if (line.substr(0, 7) == "Welcome") - { - own = BY_SERVER; - } - } - - // *implements actions in a backwards compatible way* - if (own == BY_PLAYER && - tmp.text.at(0) == '*' && - tmp.text.at(tmp.text.length()-1) == '*') - { - tmp.text[0] = ' '; - tmp.text.erase(tmp.text.length() - 1); - own = ACT_IS; - } + const gcn::Rectangle area = getChildrenArea(); - std::string lineColor = "##C"; - switch (own) - { - case BY_GM: - if (tmp.nick.empty()) - { - tmp.nick = std::string(_("Global announcement: ")); - lineColor = "##G"; - } - else - { - tmp.nick = strprintf(_("Global announcement from %s: "), - tmp.nick.c_str()); - lineColor = "##1"; // Equiv. to BrowserBox::RED - } - break; - case BY_PLAYER: - tmp.nick += CAT_NORMAL; - lineColor = "##Y"; - break; - case BY_OTHER: - tmp.nick += CAT_NORMAL; - lineColor = "##C"; - break; - case BY_SERVER: - tmp.nick = _("Server:"); - tmp.nick += " "; - tmp.text = line; - lineColor = "##S"; - break; - case BY_PARTY: - tmp.nick += CAT_NORMAL; - lineColor = "##P"; - break; - case ACT_WHISPER: - tmp.nick += CAT_WHISPER; - lineColor = "##W"; - break; - case ACT_IS: - tmp.nick += CAT_IS; - lineColor = "##I"; - break; - case BY_LOGGER: - tmp.nick = ""; - tmp.text = line; - lineColor = "##L"; - break; - } + mChatInput->setPosition(mChatInput->getFrameSize(), + area.height - mChatInput->getHeight() - + mChatInput->getFrameSize()); + mChatInput->setWidth(area.width - 2 * mChatInput->getFrameSize()); - if (tmp.nick == ": ") - { - tmp.nick = ""; - lineColor = "##S"; - } + mChatTabs->setWidth(area.width - 2 * mChatTabs->getFrameSize()); + mChatTabs->setHeight(area.height - 2 * mChatTabs->getFrameSize() - + (mChatInput->getHeight() + mChatInput->getFrameSize() * 2)); - if (tmp.nick.empty() && tmp.text.substr(0, 17) == "Visible GM status") - { - player_node->setGM(); + ChatTab *tab = getFocused(); + if (tab) { + gcn::Widget *content = tab->mScrollArea; + content->setSize(mChatTabs->getWidth() - 2 * content->getFrameSize(), + mChatTabs->getContainerHeight() - 2 * content->getFrameSize()); + content->logic(); } +} - // Get the current system time - time_t t; - time(&t); - - // Format the time string properly - std::stringstream timeStr; - timeStr << "[" << ((((t / 60) / 60) % 24 < 10) ? "0" : "") - << (int) (((t / 60) / 60) % 24) - << ":" << (((t / 60) % 60 < 10) ? "0" : "") - << (int) ((t / 60) % 60) - << "] "; - - // Check for item link - std::string::size_type start = tmp.text.find('['); - while (start != std::string::npos && tmp.text[start+1] != '@') - { - std::string::size_type end = tmp.text.find(']', start); - if (start+1 != end && end != std::string::npos) - { - // Catch multiple embeds and ignore them - // so it doesn't crash the client. - while ((tmp.text.find('[', start + 1) != std::string::npos) && - (tmp.text.find('[', start + 1) < end)) - { - start = tmp.text.find('[', start + 1); - } - - std::string temp = tmp.text.substr(start+1, end - start - 1); +void ChatWindow::widgetResized(const gcn::Event &event) +{ + Window::widgetResized(event); - trim(temp); + adjustTabSize(); +} - for (unsigned int i = 0; i < temp.size(); i++) - { - temp[i] = (char) tolower(temp[i]); - } +void ChatWindow::logic() +{ + Window::logic(); - const ItemInfo itemInfo = ItemDB::get(temp); - if (itemInfo.getName() != _("Unknown item")) - { - tmp.text.insert(end, "@@"); - tmp.text.insert(start+1, "|"); - tmp.text.insert(start+1, toString(itemInfo.getId())); - tmp.text.insert(start+1, "@@"); - } - } - start = tmp.text.find('[', start + 1); + Tab *tab = getFocused(); + if (tab != mCurrentTab) { + mCurrentTab = tab; + adjustTabSize(); } +} - line = lineColor + timeStr.str() + tmp.nick + tmp.text; - - // We look if the Vertical Scroll Bar is set at the max before - // adding a row, otherwise the max will always be a row higher - // at comparison. - if (mScrollArea->getVerticalScrollAmount() == - mScrollArea->getVerticalMaxScroll()) - { - mTextOutput->addRow(line); - mScrollArea->setVerticalScrollAmount(mScrollArea-> - getVerticalMaxScroll()); - } - else - { - mTextOutput->addRow(line); - } +ChatTab *ChatWindow::getFocused() const +{ + return dynamic_cast<ChatTab*>(mChatTabs->getSelectedTab()); +} - mRecorder->record(line.substr(3)); +void ChatWindow::clearTab(ChatTab *tab) +{ + if (tab) + tab->clearText(); } -void ChatWindow::chatLog(CHATSKILL act) +void ChatWindow::clearTab() { - chatLog(const_msg(act), BY_SERVER); + clearTab(getFocused()); } -void ChatWindow::action(const gcn::ActionEvent & event) +void ChatWindow::action(const gcn::ActionEvent &event) { if (event.getId() == "chatinput") { @@ -307,7 +180,7 @@ void ChatWindow::action(const gcn::ActionEvent & event) mCurHist = mHistory.end(); // Send the message to the server - chatSend(player_node->getName(), message); + chatSend(message); // Clear the text from the chat input mChatInput->setText(""); @@ -326,7 +199,7 @@ void ChatWindow::action(const gcn::ActionEvent & event) } } -void ChatWindow::requestChatFocus() +bool ChatWindow::requestChatFocus() { // Make sure chatWindow is visible if (!isVisible()) @@ -341,9 +214,14 @@ void ChatWindow::requestChatFocus() mTmpVisible = true; } + // Don't do anything else if the input is already visible and has focus + if (mChatInput->isVisible() && mChatInput->isFocused()) + return false; + // Give focus to the chat input mChatInput->setVisible(true); mChatInput->requestFocus(); + return true; } bool ChatWindow::isInputFocused() @@ -351,376 +229,74 @@ bool ChatWindow::isInputFocused() return mChatInput->isFocused(); } -void ChatWindow::whisper(const std::string &nick, std::string msg) +void ChatWindow::removeTab(ChatTab *tab) { - std::string recvnick = ""; - - if (msg.substr(0, 1) == "\"") - { - const std::string::size_type pos = msg.find('"', 1); - if (pos != std::string::npos) - { - recvnick = msg.substr(1, pos - 1); - msg.erase(0, pos + 2); - } - } - else - { - const std::string::size_type pos = msg.find(" "); - if (pos != std::string::npos) - { - recvnick = msg.substr(0, pos); - msg.erase(0, pos + 1); - } - } - - trim(msg); - - std::string playerName = player_node->getName(); - std::string tempNick = recvnick; - - toLower(playerName); - toLower(tempNick); - - if (tempNick.compare(playerName) == 0 || msg.empty()) - return; - - MessageOut outMsg(mNetwork); - outMsg.writeInt16(CMSG_CHAT_WHISPER); - outMsg.writeInt16(msg.length() + 28); - outMsg.writeString(recvnick, 24); - outMsg.writeString(msg, msg.length()); - - chatLog(strprintf(_("Whispering to %s: %s"), - recvnick.c_str(), msg.c_str()), - BY_PLAYER); + // Prevent removal of the local chat tab + if (tab != localChatTab) mChatTabs->removeTab(tab); } -void ChatWindow::chatSend(const std::string &nick, std::string msg) +void ChatWindow::addTab(ChatTab *tab) { - /* Some messages are managed client side, while others - * require server handling by proper packet. Probably - * those if elses should be replaced by protocol calls */ - - trim(msg); + // Make sure we don't end up with duplicates in the gui + // TODO - if (msg.compare("") == 0) - return; - - // Send party message - if (msg.at(0) == mPartyPrefix) - { - msg.erase(0, 1); - std::size_t length = msg.length() + 1; + mChatTabs->addTab(tab, tab->mScrollArea); - if (length == 0) - { - chatLog(_("Trying to send a blank party message."), BY_SERVER); - return; - } - MessageOut outMsg(mNetwork); - - outMsg.writeInt16(CMSG_PARTY_MESSAGE); - outMsg.writeInt16(length + 4); - outMsg.writeString(msg, length); - return; - } - - // Prepare ordinary message - if (msg.substr(0, 1) != "/") - { - msg = nick + " : " + msg; - - MessageOut outMsg(mNetwork); - outMsg.writeInt16(CMSG_CHAT_MESSAGE); - // Added + 1 in order to let eAthena parse admin commands correctly - outMsg.writeInt16(msg.length() + 4 + 1); - outMsg.writeString(msg, msg.length() + 1); - return; - } - - msg.erase(0, 1); - trim(msg); - - std::size_t space = msg.find(" "); - std::string command = msg.substr(0, space); - - if (space == std::string::npos) - { - msg = ""; - } - else - { - msg = msg.substr(space); - trim(msg); - } - - if (command == "announce") - { - MessageOut outMsg(mNetwork); - outMsg.writeInt16(0x0099); - outMsg.writeInt16(msg.length() + 4); - outMsg.writeString(msg, msg.length()); - } - else if (command == "help") - { - trim(msg); - std::size_t space = msg.find(" "); - std::string msg1; - - if (space == std::string::npos) - { - msg1 = ""; - } - else - { - msg1 = msg.substr(space + 1, msg.length()); - msg = msg.substr(0, space); - } - - if (!msg.empty() && msg.at(0) == '/') - { - msg.erase(0, 1); - } + // Fix for layout issues when adding the first tab + if (tab == localChatTab) + adjustTabSize(); - trim(msg1); - help(msg, msg1); - } - else if (command == "where") - { - // Display the current map, X, and Y - std::ostringstream where; - where << map_path << " " << player_node->mX << "," << player_node->mY; - chatLog(where.str(), BY_SERVER); - } - else if (command == "who") - { - MessageOut outMsg(mNetwork); - outMsg.writeInt16(0x00c1); - } - else if (command == "clear") - mTextOutput->clearRows(); - else if (command == "whisper" || command == "msg" || command == "w") - whisper(nick, msg); - else if (command == "record") - mRecorder->changeRecordingStatus(msg); - else if (command == "toggle") - { - if (msg.empty()) - { - chatLog(mReturnToggles ? _("Return toggles chat.") - : _("Message closes chat."), BY_SERVER); - return; - } - - msg = msg.substr(0, 1); - - if (msg == "1" || - msg == "y" || msg == "Y" || - msg == "t" || msg == "T") - { - chatLog(_("Return now toggles chat."), BY_SERVER); - mReturnToggles = true; - return; - } - else if (msg == "0" || - msg == "n" || msg == "N" || - msg == "f" || msg == "F") - { - chatLog(_("Message now closes chat."), BY_SERVER); - mReturnToggles = false; - return; - } - else - chatLog(_("Options to /toggle are \"yes\", \"no\", \"true\", " - "\"false\", \"1\", \"0\"."), BY_SERVER); - } - else if (command == "party") - { - if (msg.empty()) - { - chatLog(_("Unknown party command... Type \"/help\" party for more " - "information."), BY_SERVER); - return; - } + // Update UI + logic(); +} - const std::string::size_type space = msg.find(" "); - std::string rest = (space == std::string::npos ? "" - : msg.substr(space + 1, msg.length())); +void ChatWindow::chatSend(std::string &msg) +{ + ChatTab *tab = getFocused(); + tab->chatSend(msg); +} - if (!rest.empty()) - { - msg = msg.substr(0, space); - trim(msg); - } +void ChatWindow::doPresent() +{ + Beings & beings = beingManager->getAll(); + std::string response = ""; - party(msg, rest); - return; - } - else if (command == "cast") + for (BeingIterator bi = beings.begin(), be = beings.end(); + bi != be; ++bi) { - /* - * This will eventually be replaced by a GUI, so - * we don't need to get too sophisticated - */ - MessageOut outMsg(mNetwork); - if (msg == "heal") - { - outMsg.writeInt16(0x03f3); - outMsg.writeInt16(0x01); - outMsg.writeInt32(0); - outMsg.writeInt8(0); - outMsg.writeInt8(0); - outMsg.writeString("", 24); - } - else if (msg == "gather") - { - outMsg.writeInt16(0x03f3); - outMsg.writeInt16(0x02); - outMsg.writeInt32(0); - outMsg.writeInt8(0); - outMsg.writeInt8(0); - outMsg.writeString("", 24); - } - else - chatLog(_("No such spell!"), BY_SERVER); - } - else if (command == "present") - { - Beings & beings = beingManager->getAll(); - std::string response = ""; - - for (BeingIterator bi = beings.begin(), be = beings.end(); - bi != be; ++bi) + if ((*bi)->getType() == Being::PLAYER) { - if ((*bi)->getType() == Being::PLAYER) + if (!response.empty()) { - if (!response.empty()) - { - response += ", "; - } - response += (*bi)->getName(); + response += ", "; } - } - - if (mRecorder->isRecording()) - { - // Get the current system time - time_t t; - time(&t); - - // Format the time string properly - std::stringstream timeStr; - timeStr << "[" << ((((t / 60) / 60) % 24 < 10) ? "0" : "") - << (int) (((t / 60) / 60) % 24) - << ":" << (((t / 60) % 60 < 10) ? "0" : "") - << (int) ((t / 60) % 60) - << "] "; - - - mRecorder->record(timeStr.str() + _("Present: ") + response + "."); - chatLog(_("Attendance written to record log."), BY_SERVER, true); - } - else - { - chatLog(_("Present: ") + response, BY_SERVER); + response += (*bi)->getName(); } } - else if (command == "me") - { - std::stringstream actionStr; - actionStr << "*" << msg << "*"; - chatSend(player_node->getName(), actionStr.str()); - } - else - { - chatLog(_("Unknown command"), BY_SERVER); - } -} -std::string ChatWindow::const_msg(CHATSKILL act) -{ - std::string msg; - if (act.success == SKILL_FAILED && act.skill == SKILL_BASIC) + if (mRecorder->isRecording()) { - switch (act.bskill) - { - case BSKILL_TRADE: - msg = _("Trade failed!"); - break; - case BSKILL_EMOTE: - msg = _("Emote failed!"); - break; - case BSKILL_SIT: - msg = _("Sit failed!"); - break; - case BSKILL_CREATECHAT: - msg = _("Chat creating failed!"); - break; - case BSKILL_JOINPARTY: - msg = _("Could not join party!"); - break; - case BSKILL_SHOUT: - msg = _("Cannot shout!"); - break; - } + // Get the current system time + time_t t; + time(&t); - msg += " "; + // Format the time string properly + std::stringstream timeStr; + timeStr << "[" << ((((t / 60) / 60) % 24 < 10) ? "0" : "") + << (int) (((t / 60) / 60) % 24) + << ":" << (((t / 60) % 60 < 10) ? "0" : "") + << (int) ((t / 60) % 60) + << "] "; - switch (act.reason) - { - case RFAIL_SKILLDEP: - msg += _("You have not yet reached a high enough lvl!"); - break; - case RFAIL_INSUFHP: - msg += _("Insufficient HP!"); - break; - case RFAIL_INSUFSP: - msg += _("Insufficient SP!"); - break; - case RFAIL_NOMEMO: - msg += _("You have no memos!"); - break; - case RFAIL_SKILLDELAY: - msg += _("You cannot do that right now!"); - break; - case RFAIL_ZENY: - msg += _("Seems you need more GP... ;-)"); - break; - case RFAIL_WEAPON: - msg += _("You cannot use this skill with that kind of weapon!"); - break; - case RFAIL_REDGEM: - msg += _("You need another red gem!"); - break; - case RFAIL_BLUEGEM: - msg += _("You need another blue gem!"); - break; - case RFAIL_OVERWEIGHT: - msg += _("You're carrying to much to do this!"); - break; - default: - msg += _("Huh? What's that?"); - break; - } + + mRecorder->record(timeStr.str() + _("Present: ") + response + "."); + localChatTab->chatLog(_("Attendance written to record log."), + BY_SERVER, true); } else { - switch (act.skill) - { - case SKILL_WARP : - msg = _("Warp failed..."); - break; - case SKILL_STEAL : - msg = _("Could not steal anything..."); - break; - case SKILL_ENVENOM : - msg = _("Poison had no effect..."); - break; - } + localChatTab->chatLog(_("Present: ") + response, BY_SERVER); } - - return msg; } void ChatWindow::scroll(int amount) @@ -728,16 +304,12 @@ void ChatWindow::scroll(int amount) if (!isVisible()) return; - int range = mScrollArea->getHeight() / 8 * amount; - gcn::Rectangle scr; - scr.y = mScrollArea->getVerticalScrollAmount() + range; - scr.height = abs(range); - mTextOutput->showPart(scr); + ChatTab *tab = getFocused(); + if (tab) tab->scroll(amount); } -void ChatWindow::keyPressed(gcn::KeyEvent & event) +void ChatWindow::keyPressed(gcn::KeyEvent &event) { - if (event.getKey().getValue() == Key::DOWN && mCurHist != mHistory.end()) { @@ -786,150 +358,36 @@ void ChatWindow::setVisible(bool isVisible) * For whatever reason, if setVisible is called, the mTmpVisible effect * should be disabled. */ - mTmpVisible = false; } -void ChatWindow::party(const std::string & command, const std::string & rest) +void ChatWindow::setRecordingFile(const std::string &msg) { - if (command == "prefix") - { - if (rest.empty()) - { - char temp[2] = "."; - *temp = mPartyPrefix; - chatLog(_("The current party prefix is ") + std::string(temp), - BY_SERVER); - } - else if (rest.length() != 1) - { - chatLog(_("Party prefix must be one character long."), BY_SERVER); - } - else - { - if (rest == "/") - { - chatLog(_("Cannot use a '/' as the prefix."), BY_SERVER); - } - else - { - mPartyPrefix = rest.at(0); - chatLog(_("Changing prefix to ") + rest, BY_SERVER); - } - } - } - else - mParty->respond(command, rest); + mRecorder->setRecordingFile(msg); } -void ChatWindow::help(const std::string & msg1, const std::string & msg2) +void ChatWindow::whisper(std::string nick, std::string mes, bool own) { - chatLog(_("-- Help --"), BY_SERVER); - if (msg1.empty()) - { - chatLog(_("/announce: Global announcement (GM only)"), BY_SERVER); - chatLog(_("/clear: Clears this window"), BY_SERVER); - chatLog(_("/help: Display this help"), BY_SERVER); - chatLog(_("/me <message>: Tell something about yourself"), BY_SERVER); - chatLog(_("/msg <nick> <message>: Alternate form for /whisper"), - BY_SERVER); - chatLog(_("/party <command> <params>: Party commands"), BY_SERVER); - chatLog(_("/present: Get list of players present"), BY_SERVER); - chatLog(_("/record <filename>: Start recording the chat to an " - "external file"), BY_SERVER); - chatLog(_("/toggle: Determine whether <return> toggles the chat log"), - BY_SERVER); - chatLog(_("/w <nick> <message>: Short form for /whisper"), BY_SERVER); - chatLog(_("/where: Display map name"), BY_SERVER); - chatLog(_("/whisper <nick> <message>: Sends a private <message> " - "to <nick>"), BY_SERVER); - chatLog(_("/who: Display number of online users"), BY_SERVER); - chatLog(_("For more information, type /help <command>"), BY_SERVER); - } - else if (msg1 == "announce") - { - chatLog(_("Command: /announce <msg>"), BY_SERVER); - chatLog(_("*** only available to a GM ***"), BY_SERVER); - chatLog(_("This command sends the message <msg> to " - "all players currently online."), BY_SERVER); - } - else if (msg1 == "clear") - { - chatLog(_("Command: /clear"), BY_SERVER); - chatLog(_("This command clears the chat log of previous chat."), - BY_SERVER); - } - else if (msg1 == "help") - { - chatLog(_("Command: /help"), BY_SERVER); - chatLog(_("This command displays a list of all commands available."), - BY_SERVER); - chatLog(_("Command: /help <command>"), BY_SERVER); - chatLog(_("This command displays help on <command>."), BY_SERVER); - } - else if (msg1 == "me") - { - chatLog(_("Command: /me <msg>"), BY_SERVER); - chatLog(_("This command tell others you are (doing) <msg>."), - BY_SERVER); - } - else if (msg1 == "party") - { - mParty->help(msg2); - } - else if (msg1 == "present") - { - chatLog(_("Command: /present"), BY_SERVER); - chatLog(_("This command gets a list of players within hearing and " - "sends it to either the record log if recording, or the chat " - "log otherwise."), BY_SERVER); - } - else if (msg1 == "record") - { - chatLog(_("Command: /record <filename>"), BY_SERVER); - chatLog(_("This command starts recording the chat log to the file " - "<filename>."), BY_SERVER); - chatLog(_("Command: /record"), BY_SERVER); - chatLog(_("This command finishes a recording session."), BY_SERVER); - } - else if (msg1 == "toggle") - { - chatLog(_("Command: /toggle <state>"), BY_SERVER); - chatLog(_("This command sets whether the return key should toggle the " - "chat log, or whether the chat log turns off automatically."), - BY_SERVER); - chatLog(_("<state> can be one of \"1\", \"yes\", \"true\" to " - "turn the toggle on, or \"0\", \"no\", \"false\" to turn the " - "toggle off."), BY_SERVER); - chatLog(_("Command: /toggle"), BY_SERVER); - chatLog(_("This command displays the return toggle status."), - BY_SERVER); - } - else if (msg1 == "where") - { - chatLog(_("Command: /where"), BY_SERVER); - chatLog(_("This command displays the name of the current map."), - BY_SERVER); - } - else if (msg1 == "whisper" || msg1 == "msg" || msg1 == "w") - { - chatLog(_("Command: /msg <nick> <msg>"), BY_SERVER); - chatLog(_("Command: /whisper <nick> <msg>"), BY_SERVER); - chatLog(_("Command: /w <nick> <msg>"), BY_SERVER); - chatLog(_("This command sends the message <msg> to <nick>."), - BY_SERVER); - chatLog(_("If the <nick> has spaces in it, enclose it in " - "double quotes (\")."), BY_SERVER); - } - else if (msg1 == "who") + if (mes.length() == 0) return; + std::string playerName = player_node->getName(); + std::string tempNick = nick; + + toLower(playerName); + toLower(tempNick); + + if (!own && tempNick.compare(playerName) == 0) + return; + + ChatTab *tab = mWhispers[tempNick]; + + if (!tab) { - chatLog(_("Command: /who"), BY_SERVER); - chatLog(_("This command displays the number of players currently " - "online."), BY_SERVER); + tab = new WhisperTab(tempNick); + mWhispers[tempNick] = tab; } + + if (own) + tab->chatSend(mes); else - { - chatLog(_("Unknown command."), BY_SERVER); - chatLog(_("Type /help for a list of commands."), BY_SERVER); - } + tab->chatLog(nick, mes); } diff --git a/src/gui/chat.h b/src/gui/chat.h index 8b710dc8..7c080960 100644 --- a/src/gui/chat.h +++ b/src/gui/chat.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,29 +24,28 @@ #include <list> #include <string> +#include <map> #include <guichan/actionlistener.hpp> #include <guichan/keylistener.hpp> +#include <guichan/widget.hpp> +#include <guichan/widgetlistener.hpp> + +#include "widgets/chattab.h" #include "window.h" class BrowserBox; -class Network; +class Channel; +class ChatTab; class Recorder; -class Party; class ScrollArea; +class TabbedArea; class ItemLinkHandler; - -#define BY_GM 0 // those should be self-explanatory =) -#define BY_PLAYER 1 -#define BY_OTHER 2 -#define BY_SERVER 3 -#define BY_PARTY 4 - -#define ACT_WHISPER 5 // getting whispered at -#define ACT_IS 6 // equivalent to "/me" on IRC - -#define BY_LOGGER 7 +#ifdef EATHENA_SUPPORT +class Network; +#endif +class WhisperTab; /** * gets in between usernick and message text depending on @@ -57,47 +55,14 @@ class ItemLinkHandler; #define CAT_IS "" #define CAT_WHISPER " whispers: " -/** job dependend identifiers (?) */ -#define SKILL_BASIC 0x0001 -#define SKILL_WARP 0x001b -#define SKILL_STEAL 0x0032 -#define SKILL_ENVENOM 0x0034 - -/** basic skills identifiers */ -#define BSKILL_TRADE 0x0000 -#define BSKILL_EMOTE 0x0001 -#define BSKILL_SIT 0x0002 -#define BSKILL_CREATECHAT 0x0003 -#define BSKILL_JOINPARTY 0x0004 -#define BSKILL_SHOUT 0x0005 -#define BSKILL_PK 0x0006 // ?? -#define BSKILL_SETALLIGN 0x0007 // ?? - -/** reasons why action failed */ -#define RFAIL_SKILLDEP 0x00 -#define RFAIL_INSUFHP 0x01 -#define RFAIL_INSUFSP 0x02 -#define RFAIL_NOMEMO 0x03 -#define RFAIL_SKILLDELAY 0x04 -#define RFAIL_ZENY 0x05 -#define RFAIL_WEAPON 0x06 -#define RFAIL_REDGEM 0x07 -#define RFAIL_BLUEGEM 0x08 -#define RFAIL_OVERWEIGHT 0x09 -#define RFAIL_GENERIC 0x0a - -/** should always be zero if failed */ -#define SKILL_FAILED 0x00 - #define DEFAULT_CHAT_WINDOW_SCROLL 7 // 1 means `1/8th of the window size'. -struct CHATSKILL +/** One item in the chat log */ +struct CHATLOG { - short skill; - short bskill; - short unused; - char success; - char reason; + std::string nick; + std::string text; + int own; }; /** @@ -105,14 +70,19 @@ struct CHATSKILL * * \ingroup Interface */ -class ChatWindow : public Window, public gcn::ActionListener, +class ChatWindow : public Window, + public gcn::ActionListener, public gcn::KeyListener { public: /** * Constructor. */ +#ifdef TMWSERV_SUPPORT + ChatWindow(); +#else ChatWindow(Network *network); +#endif /** * Destructor: used to write back values to the config file @@ -120,23 +90,33 @@ class ChatWindow : public Window, public gcn::ActionListener, ~ChatWindow(); /** + * Called when the widget changes size. Used for adapting the size of + * the tabbed area. + */ + void widgetResized(const gcn::Event &event); + + void logic(); + + /** * Reset the chat window and recorder window attached to it to their * default positions. */ void resetToDefaultSize(); /** - * Adds a line of text to our message list. Parameters: - * - * @param line Text message. - * @parem own Type of message (usually the owner-type). + * Gets the focused tab. */ - void chatLog(std::string line, int own, bool ignoreRecord = false); + ChatTab* getFocused() const; /** - * Calls original chat_log() after processing the packet. + * Clear the given tab. */ - void chatLog(CHATSKILL); + void clearTab(ChatTab* tab); + + /** + * Clear the current tab. + */ + void clearTab(); /** * Performs action. @@ -145,8 +125,11 @@ class ChatWindow : public Window, public gcn::ActionListener, /** * Request focus for typing chat message. + * + * \returns true if the input was shown + * false otherwise */ - void requestChatFocus(); + bool requestChatFocus(); /** * Checks whether ChatWindow is Focused or not. @@ -154,30 +137,12 @@ class ChatWindow : public Window, public gcn::ActionListener, bool isInputFocused(); /** - * Determines whether to send a command or an ordinary message, then - * contructs packets & sends them. - * - * @param nick The character's name to display in front. - * @param msg The message text which is to be send. + * Passes the text to the current tab as input * - * NOTE: - * The nickname is required by the server, if not specified - * the message may not be sent unless a command was intended - * which requires another packet to be constructed! you can - * achieve this by putting a slash ("/") infront of the - * message followed by the command name and the message. - * of course all slash-commands need implemented handler- - * routines. ;-) - * remember, a line starting with "@" is not a command that needs - * to be parsed rather is sent using the normal chat-packet. + * @param msg The message text which is to be sent. * - * EXAMPLE: - * // for an global announcement /- command - * chatlog.chat_send("", "/announce Hello to all logged in users!"); - * // for simple message by a user /- message - * chatlog.chat_send("Zaeiru", "Hello to all users on the screen!"); */ - void chatSend(const std::string &nick, std::string msg); + void chatSend(std::string &msg); /** Called when key is pressed */ void keyPressed(gcn::KeyEvent &event); @@ -191,65 +156,77 @@ class ChatWindow : public Window, public gcn::ActionListener, /** Override to reset mTmpVisible */ void setVisible(bool visible); - /** - * Scrolls the chat window - * - * @param amount direction and amount to scroll. Negative numbers scroll - * up, positive numbers scroll down. The absolute amount indicates the - * amount of 1/8ths of chat window real estate that should be scrolled. - */ - void scroll(int amount); - /** - * party implements the partying chat commands + * Scrolls the chat window * - * @param command is the party command to perform - * @param msg is the remainder of the message + * @param amount direction and amount to scroll. Negative numbers scroll + * up, positive numbers scroll down. The absolute amount indicates the + * amount of 1/8ths of chat window real estate that should be scrolled. */ - void party(const std::string &command, const std::string &msg); + void scroll(int amount); + +#ifdef EATHENA_SUPPORT + char getPartyPrefix() const { return mPartyPrefix; } + void setPartyPrefix(char prefix) { mPartyPrefix = prefix; } +#endif /** - * help implements the /help command + * Sets the file being recorded to * - * @param msg1 is the command that the player needs help on - * @param msg2 is the sub-command relating to the command + * @param msg The file to write out to. If null, then stop recording. */ - void help(const std::string &msg1, const std::string &msg2); + void setRecordingFile(const std::string &msg); - private: + bool getReturnTogglesChat() const { return mReturnToggles; } + void setReturnTogglesChat(bool toggles) { mReturnToggles = toggles; } + + void doPresent(); + + void whisper(std::string nick, std::string mes, bool own = false); + + protected: + friend class ChatTab; + friend class WhisperTab; + /** Remove the given tab from the window */ + void removeTab(ChatTab *tab); + + /** Add the tab to the window */ + void addTab(ChatTab *tab); + + void adjustTabSize(); + +#ifdef EATHENA_SUPPORT Network *mNetwork; - bool mTmpVisible; + char mPartyPrefix; /**< Messages beginning with the prefix are sent to + the party */ +#endif + /** Used for showing item popup on clicking links **/ + ItemLinkHandler *mItemLinkHandler; + Recorder *mRecorder; - void whisper(const std::string &nick, std::string msg); + /** Input box for typing chat messages. */ + gcn::TextField *mChatInput; - /** One item in the chat log */ - struct CHATLOG - { - std::string nick; - std::string text; - int own; - }; + private: + bool mTmpVisible; - /** Constructs failed messages for actions */ - std::string const_msg(CHATSKILL); + /** Tabbed area for holding each channel. */ + TabbedArea *mChatTabs; + Tab *mCurrentTab; + + typedef std::map<const std::string, ChatTab*> TabMap; + /** Manage whisper tabs */ + TabMap mWhispers; - gcn::TextField *mChatInput; /**< Input box for typing chat messages */ - BrowserBox *mTextOutput; /**< Text box for displaying chat history */ - ScrollArea *mScrollArea; /**< Scroll area around text output */ - ItemLinkHandler *mItemLinkHandler; /** Used for showing item popup on - clicking links **/ typedef std::list<std::string> History; typedef History::iterator HistoryIterator; - History mHistory; /**< Command history */ - HistoryIterator mCurHist; /**< History iterator */ - Recorder *mRecorder; /**< Recording class */ - char mPartyPrefix; /**< Messages beginning with the prefix are - sent to the party */ - bool mReturnToggles; /**< Marks whether <Return> toggles the chat - log or not */ - Party *mParty; + History mHistory; /**< Command history. */ + HistoryIterator mCurHist; /**< History iterator. */ + bool mReturnToggles; /**< Marks whether <Return> toggles the chat log + or not */ }; + extern ChatWindow *chatWindow; #endif diff --git a/src/gui/chatinput.cpp b/src/gui/chatinput.cpp index 42c6d4de..43f3cde4 100644 --- a/src/gui/chatinput.cpp +++ b/src/gui/chatinput.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/chatinput.h b/src/gui/chatinput.h index 96c30b3f..3bc16928 100644 --- a/src/gui/chatinput.h +++ b/src/gui/chatinput.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,6 +26,8 @@ #include "textfield.h" +#include <guichan/focuslistener.hpp> + /** * The chat input hides when it loses focus. It is also invisible by default. */ diff --git a/src/gui/checkbox.cpp b/src/gui/checkbox.cpp index f6cce581..2623e2c6 100644 --- a/src/gui/checkbox.cpp +++ b/src/gui/checkbox.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,7 +35,7 @@ Image *CheckBox::checkBoxChecked; Image *CheckBox::checkBoxDisabled; Image *CheckBox::checkBoxDisabledChecked; -CheckBox::CheckBox(const std::string& caption, bool selected): +CheckBox::CheckBox(const std::string &caption, bool selected): gcn::CheckBox(caption, selected) { if (instances == 0) diff --git a/src/gui/checkbox.h b/src/gui/checkbox.h index 93b62b9d..303782b0 100644 --- a/src/gui/checkbox.h +++ b/src/gui/checkbox.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,7 +37,7 @@ class CheckBox : public gcn::CheckBox /** * Constructor. */ - CheckBox(const std::string& caption, bool selected = false); + CheckBox(const std::string &caption, bool selected = false); /** * Destructor. diff --git a/src/gui/confirm_dialog.cpp b/src/gui/confirm_dialog.cpp index 4c08eb73..e1c32759 100644 --- a/src/gui/confirm_dialog.cpp +++ b/src/gui/confirm_dialog.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,7 +33,7 @@ ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg, Window *parent): Window(title, true, parent) { - mTextBox = new TextBox(); + mTextBox = new TextBox; mTextBox->setEditable(false); mTextBox->setOpaque(false); @@ -75,11 +74,11 @@ ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg, add(yesButton); add(noButton); - setLocationRelativeTo(getParent()); - if (getParent()) + { + center(); getParent()->moveToTop(this); - + } setVisible(true); yesButton->requestFocus(); } diff --git a/src/gui/confirm_dialog.h b/src/gui/confirm_dialog.h index 493e9dda..8d8c0436 100644 --- a/src/gui/confirm_dialog.h +++ b/src/gui/confirm_dialog.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -56,7 +55,6 @@ class ConfirmDialog : public Window, public gcn::ActionListener private: TextBox *mTextBox; ScrollArea *mTextArea; - gcn::Button *okButton; }; #endif diff --git a/src/gui/connection.cpp b/src/gui/connection.cpp index d4a2b18a..5fb21ff2 100644 --- a/src/gui/connection.cpp +++ b/src/gui/connection.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,31 +19,22 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <guichan/actionlistener.hpp> - #include "button.h" #include "connection.h" #include "label.h" #include "progressbar.h" #include "../main.h" +#include "../log.h" #include "../utils/gettext.h" -namespace -{ - struct ConnectionActionListener : public gcn::ActionListener - { - void action(const gcn::ActionEvent &event) { state = EXIT_STATE; } - } listener; -} - -ConnectionDialog::ConnectionDialog(): - Window("Info"), mProgress(0) +ConnectionDialog::ConnectionDialog(int previousState): + Window("Info"), mProgress(0), mPreviousState(previousState) { setContentSize(200, 100); - Button *cancelButton = new Button(_("Cancel"), "cancelButton", &listener); + Button *cancelButton = new Button(_("Cancel"), "cancelButton", this); mProgressBar = new ProgressBar(0.0, 200 - 10, 20, 128, 128, 128); gcn::Label *label = new Label(_("Connecting...")); @@ -56,10 +46,16 @@ ConnectionDialog::ConnectionDialog(): add(cancelButton); add(mProgressBar); - setLocationRelativeTo(getParent()); + center(); setVisible(true); } +void ConnectionDialog::action(gcn::ActionEvent const &) +{ + logger->log("Cancel pressed"); + state = mPreviousState; +} + void ConnectionDialog::logic() { mProgress += 0.005f; diff --git a/src/gui/connection.h b/src/gui/connection.h index f91a0ad1..0e347266 100644 --- a/src/gui/connection.h +++ b/src/gui/connection.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,6 +22,8 @@ #ifndef CONNECTION_H #define CONNECTION_H +#include <guichan/actionlistener.hpp> + #include "window.h" class ProgressBar; @@ -32,7 +33,7 @@ class ProgressBar; * * \ingroup Interface */ -class ConnectionDialog : public Window +class ConnectionDialog : public Window, gcn::ActionListener { public: /** @@ -40,13 +41,20 @@ class ConnectionDialog : public Window * * @see Window::Window */ - ConnectionDialog(); + ConnectionDialog(int previousState); + + /** + * Called when the user presses Cancel. Restores the global state to + * the previous one. + */ + void action(gcn::ActionEvent const &); void logic(); private: ProgressBar *mProgressBar; float mProgress; + int mPreviousState; }; #endif diff --git a/src/gui/debugwindow.cpp b/src/gui/debugwindow.cpp index 9b8ea6bd..a98c9af4 100644 --- a/src/gui/debugwindow.cpp +++ b/src/gui/debugwindow.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/debugwindow.h b/src/gui/debugwindow.h index c82521f9..8097132c 100644 --- a/src/gui/debugwindow.h +++ b/src/gui/debugwindow.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/emotecontainer.cpp b/src/gui/emotecontainer.cpp index 22b4cf50..ececd9aa 100644 --- a/src/gui/emotecontainer.cpp +++ b/src/gui/emotecontainer.cpp @@ -2,8 +2,7 @@ * Extended support for activating emotes * Copyright (C) 2009 Aethyra Development Team * - * This file is part of Aethyra derived from original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/emotecontainer.h b/src/gui/emotecontainer.h index 7e88cb71..88df29fc 100644 --- a/src/gui/emotecontainer.h +++ b/src/gui/emotecontainer.h @@ -2,8 +2,7 @@ * Extended support for activating emotes * Copyright (C) 2009 Aethyra Development Team * - * This file is part of Aethyra derived from original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/emoteshortcutcontainer.cpp b/src/gui/emoteshortcutcontainer.cpp index 47fb9b06..661f42a7 100644 --- a/src/gui/emoteshortcutcontainer.cpp +++ b/src/gui/emoteshortcutcontainer.cpp @@ -2,8 +2,7 @@ * Extended support for activating emotes * Copyright (C) 2009 Aethyra Development Team * - * This file is part of Aethyra derived from original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/emoteshortcutcontainer.h b/src/gui/emoteshortcutcontainer.h index ff9f929c..2997cb09 100644 --- a/src/gui/emoteshortcutcontainer.h +++ b/src/gui/emoteshortcutcontainer.h @@ -2,8 +2,7 @@ * Extended support for activating emotes * Copyright (C) 2009 Aethyra Development Team * - * This file is part of Aethyra derived from original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/emotewindow.cpp b/src/gui/emotewindow.cpp index 77168993..d4b3cf2e 100644 --- a/src/gui/emotewindow.cpp +++ b/src/gui/emotewindow.cpp @@ -2,7 +2,7 @@ * Extended support for activating emotes * Copyright (C) 2009 Aethyra Development Team * - * This file is part of Aethyra. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,7 +35,7 @@ EmoteWindow::EmoteWindow(): Window(_("Emote")) { - setWindowName(_("Emote")); + setWindowName("Emote"); setResizable(true); setCloseButton(true); setMinWidth(80); @@ -44,7 +44,7 @@ EmoteWindow::EmoteWindow(): mUseButton = new Button(_("Use"), "use", this); - mEmotes = new EmoteContainer(); + mEmotes = new EmoteContainer; mEmotes->addSelectionListener(this); mEmoteScroll = new ScrollArea(mEmotes); diff --git a/src/gui/emotewindow.h b/src/gui/emotewindow.h index 81ee4f05..8af24a7b 100644 --- a/src/gui/emotewindow.h +++ b/src/gui/emotewindow.h @@ -2,7 +2,7 @@ * Extended support for activating emotes * Copyright (C) 2009 Aethyra Development Team * - * This file is part of Aethyra. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp index 168ae22f..96500e88 100644 --- a/src/gui/equipmentwindow.cpp +++ b/src/gui/equipmentwindow.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra derived from original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,6 +37,7 @@ #include "../item.h" #include "../localplayer.h" +#include "../resources/image.h" #include "../resources/iteminfo.h" #include "../resources/resourcemanager.h" @@ -59,11 +59,19 @@ static const int boxPosition[][2] = { {129, 78} // EQUIP_AMMO_SLOT }; +#ifdef TMWSERV_SUPPORT +EquipmentWindow::EquipmentWindow(Equipment *equipment): +#else EquipmentWindow::EquipmentWindow(): +#endif Window(_("Equipment")), +#ifdef TMWSERV_SUPPORT + mEquipment(equipment), +#endif + mBackground(NULL), mSelected(-1) { - mItemPopup = new ItemPopup(); + mItemPopup = new ItemPopup; mItemPopup->setOpaque(false); // Control that shows the Player @@ -84,19 +92,31 @@ EquipmentWindow::EquipmentWindow(): add(mPlayerBox); add(mUnequip); +#ifdef TMWSERV_SUPPORT + for (int i = 0; i < EQUIPMENT_SIZE; i++) +#else for (int i = EQUIP_LEGS_SLOT; i < EQUIP_VECTOREND; i++) +#endif { mEquipBox[i].posX = boxPosition[i][0] + getPadding(); mEquipBox[i].posY = boxPosition[i][1] + getTitleBarHeight(); } + ResourceManager *resman = ResourceManager::getInstance(); + mBackground = resman->getImage("graphics/gui/equip_bg.png"); + mBackground->setAlpha(0.3); + +#ifdef EATHENA_SUPPORT mEquipment = player_node->mEquipment.get(); mInventory = player_node->getInventory(); +#endif } EquipmentWindow::~EquipmentWindow() { + mBackground->decRef(); delete mItemPopup; + delete mUnequip; } void EquipmentWindow::draw(gcn::Graphics *graphics) @@ -107,13 +127,15 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) // Draw window graphics Window::draw(graphics); - Item* item; - Graphics *g = static_cast<Graphics*>(graphics); Window::drawChildren(graphics); +#ifdef TMWSERV_SUPPORT + for (int i = 0; i < EQUIPMENT_SIZE; i++) +#else for (int i = EQUIP_LEGS_SLOT; i < EQUIP_VECTOREND; i++) +#endif { if (i == mSelected) { @@ -131,14 +153,19 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) g->drawRectangle(gcn::Rectangle(mEquipBox[i].posX, mEquipBox[i].posY, BOX_WIDTH, BOX_HEIGHT)); - item = (i != EQUIP_AMMO_SLOT) ? +#ifdef TMWSERV_SUPPORT + Item *item = mEquipment->getEquipment(i); +#else + Item *item = (i != EQUIP_AMMO_SLOT) ? mInventory->getItem(mEquipment->getEquipment(i)) : mInventory->getItem(mEquipment->getArrows()); +#endif if (item) { // Draw Item. - Image* image = item->getImage(); + Image *image = item->getImage(); g->drawImage(image, mEquipBox[i].posX, mEquipBox[i].posY); +#ifdef EATHENA_SUPPORT if (i == EQUIP_AMMO_SLOT) { g->setColor(guiPalette->getColor(Palette::TEXT)); @@ -147,6 +174,7 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) mEquipBox[i].posY - getFont()->getHeight(), gcn::Graphics::CENTER); } +#endif } } } @@ -155,26 +183,38 @@ void EquipmentWindow::action(const gcn::ActionEvent &event) { if (event.getId() == "unequip" && mSelected > -1) { +#ifdef TMWSERV_SUPPORT + player_node->unequipItem(mSelected); +#else Item* item = (mSelected != EQUIP_AMMO_SLOT) ? mInventory->getItem(mEquipment->getEquipment(mSelected)) : mInventory->getItem(mEquipment->getArrows()); player_node->unequipItem(item); +#endif mSelected = -1; } } -Item* EquipmentWindow::getItem(const int &x, const int &y) +Item* EquipmentWindow::getItem(int x, int y) const { +#ifdef TMWSERV_SUPPORT + for (int i = 0; i < EQUIPMENT_SIZE; i++) +#else for (int i = EQUIP_LEGS_SLOT; i < EQUIP_VECTOREND; i++) +#endif { gcn::Rectangle tRect(mEquipBox[i].posX, mEquipBox[i].posY, BOX_WIDTH, BOX_HEIGHT); if (tRect.isPointInRect(x, y)) { +#ifdef TMWSERV_SUPPORT + return mEquipment->getEquipment(i); +#else return (i != EQUIP_AMMO_SLOT) ? mInventory->getItem(mEquipment->getEquipment(i)) : mInventory->getItem(mEquipment->getArrows()); +#endif } } return NULL; @@ -192,11 +232,19 @@ void EquipmentWindow::mousePressed(gcn::MouseEvent& mouseEvent) if (mouseEvent.getButton() == gcn::MouseEvent::LEFT) { // Checks if any of the presses were in the equip boxes. +#ifdef TMWSERV_SUPPORT + for (int i = 0; i < EQUIPMENT_SIZE; i++) +#else for (int i = EQUIP_LEGS_SLOT; i < EQUIP_VECTOREND; i++) +#endif { +#ifdef TMWSERV_SUPPORT + item = mEquipment->getEquipment(i); +#else item = (i != EQUIP_AMMO_SLOT) ? mInventory->getItem(mEquipment->getEquipment(i)) : mInventory->getItem(mEquipment->getArrows()); +#endif gcn::Rectangle tRect(mEquipBox[i].posX, mEquipBox[i].posY, BOX_WIDTH, BOX_HEIGHT); diff --git a/src/gui/equipmentwindow.h b/src/gui/equipmentwindow.h index 7fdbaac8..7f7150ff 100644 --- a/src/gui/equipmentwindow.h +++ b/src/gui/equipmentwindow.h @@ -1,33 +1,33 @@ /* - * Aethyra - * Copyright 2004 The Mana World Development Team + * The Mana World + * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra derived from original code - * from The Mana World. + * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * - * The Mana World is distributed in the hope that it will be useful, + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef EQUIPMENT_WINDOW_H -#define EQUIPMENT_WINDOW_H +#ifndef EQUIPMENTWINDOW_H +#define EQUIPMENTWINDOW_H #include <guichan/actionlistener.hpp> #include "window.h" class Equipment; +class Image; class Inventory; class Item; class ItemPopup; @@ -53,7 +53,11 @@ class EquipmentWindow : public Window, public gcn::ActionListener /** * Constructor. */ +#ifdef TMWSERV_SUPPORT + EquipmentWindow(Equipment *equipment); +#else EquipmentWindow(); +#endif /** * Destructor. @@ -69,6 +73,23 @@ class EquipmentWindow : public Window, public gcn::ActionListener void mousePressed(gcn::MouseEvent& mouseEvent); +#ifdef TMWSERV_SUPPORT + enum{ + // Equipment rules: + EQUIP_TORSO_SLOT = 0, + EQUIP_ARMS_SLOT = 1, + EQUIP_HEAD_SLOT = 2, + EQUIP_LEGS_SLOT = 3, + EQUIP_FEET_SLOT = 4, + EQUIP_RING1_SLOT = 5, + EQUIP_RING2_SLOT = 6, + EQUIP_NECKLACE_SLOT = 7, + EQUIP_FIGHT1_SLOT = 8, + EQUIP_FIGHT2_SLOT = 9, + EQUIP_PROJECTILE_SLOT = 10, + EQUIP_VECTOREND + }; +#else enum { // Equipment rules: EQUIP_LEGS_SLOT = 0, @@ -84,17 +105,20 @@ class EquipmentWindow : public Window, public gcn::ActionListener EQUIP_AMMO_SLOT, EQUIP_VECTOREND }; - +#endif private: void mouseExited(gcn::MouseEvent &event); void mouseMoved(gcn::MouseEvent &event); - Item* getItem(const int &x, const int &y); + Item* getItem(int x, int y) const; Equipment *mEquipment; +#ifdef EATHENA_SUPPORT Inventory *mInventory; +#endif gcn::Button *mUnequip; /**< Button for unequipping. */ + Image *mBackground; /**< Background Image. */ EquipBox mEquipBox[EQUIP_VECTOREND]; /**< Equipment Boxes. */ ItemPopup *mItemPopup; diff --git a/src/gui/focushandler.cpp b/src/gui/focushandler.cpp index c642127d..b9cfd789 100644 --- a/src/gui/focushandler.cpp +++ b/src/gui/focushandler.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/focushandler.h b/src/gui/focushandler.h index fc5dd240..b0639bd8 100644 --- a/src/gui/focushandler.h +++ b/src/gui/focushandler.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/gccontainer.cpp b/src/gui/gccontainer.cpp index 7aebed15..8325ccd4 100644 --- a/src/gui/gccontainer.cpp +++ b/src/gui/gccontainer.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/gccontainer.h b/src/gui/gccontainer.h index 2071955d..da584a42 100644 --- a/src/gui/gccontainer.h +++ b/src/gui/gccontainer.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 5bdab453..87ce74fa 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -95,7 +94,7 @@ Gui::Gui(Graphics *graphics): mFocusHandler = new FocusHandler; // Initialize top GUI widget - WindowContainer *guiTop = new WindowContainer(); + WindowContainer *guiTop = new WindowContainer; guiTop->setDimension(gcn::Rectangle(0, 0, graphics->getWidth(), graphics->getHeight())); guiTop->setOpaque(false); @@ -105,7 +104,8 @@ Gui::Gui(Graphics *graphics): ResourceManager *resman = ResourceManager::getInstance(); // Set global font - std::string path = resman->getPath("fonts/dejavusans.ttf"); + std::string path = resman->getPath( + branding.getValue("font", "fonts/dejavusans.ttf")); try { const int fontSize = (int)config.getValue("fontSize", 11); @@ -119,7 +119,8 @@ Gui::Gui(Graphics *graphics): } // Set bold font - path = resman->getPath("fonts/dejavusans-bold.ttf"); + path = resman->getPath( + branding.getValue("boldFont", "fonts/dejavusans.ttf")); try { const int fontSize = (int)config.getValue("fontSize", 11); @@ -139,7 +140,7 @@ Gui::Gui(Graphics *graphics): config.addListener("customcursor", mConfigListener); // Create the viewport - viewport = new Viewport(); + viewport = new Viewport; viewport->setDimension(gcn::Rectangle(0, 0, graphics->getWidth(), graphics->getHeight())); guiTop->add(viewport); diff --git a/src/gui/gui.h b/src/gui/gui.h index 609648fd..2ce153db 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/guildlistbox.cpp b/src/gui/guildlistbox.cpp new file mode 100644 index 00000000..a4d39741 --- /dev/null +++ b/src/gui/guildlistbox.cpp @@ -0,0 +1,130 @@ +/* + * The Mana World + * Copyright (C) 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "guildlistbox.h" + +#include "../graphics.h" + +#include "../resources/image.h" +#include "../resources/resourcemanager.h" + +#include <guichan/font.hpp> + +GuildListBox::GuildListBox(): + ListBox(NULL) +{ + onlineIcon = ResourceManager::getInstance()->getImage("graphics/gui/circle-green.png"); + offlineIcon = ResourceManager::getInstance()->getImage("graphics/gui/circle-gray.png"); +} + +void GuildListBox::draw(gcn::Graphics *gcnGraphics) +{ + if (!mListModel) + return; + + Graphics *graphics = static_cast<Graphics*>(gcnGraphics); + + graphics->setColor(gcn::Color(110, 160, 255)); + graphics->setFont(getFont()); + + int fontHeight = getFont()->getHeight(); + + // Draw rectangle below the selected list element + if (mSelected >= 0) { + graphics->fillRectangle(gcn::Rectangle(0, fontHeight * mSelected, + getWidth(), fontHeight)); + } + + // Draw the list elements + for (int i = 0, y = 0; + i < mListModel->getNumberOfElements(); + ++i, y += fontHeight) + { + // Draw online status + bool online = false; + UserMap::iterator itr = mUsers.find(mListModel->getElementAt(i)); + if (itr != mUsers.end()) + { + online = itr->second; + } + Image *icon = online ? onlineIcon : offlineIcon; + if (icon) + graphics->drawImage(icon, 1, y); + // Draw Name + graphics->setColor(gcn::Color(0, 0, 0)); + graphics->drawText(mListModel->getElementAt(i), 33, y); + } +} +/* +void GuildListBox::setSelected(int selected) +{ + if (!mListModel) + { + mSelected = -1; + } + else + { + // Update mSelected with bounds checking + mSelected = std::min(mListModel->getNumberOfElements() - 1, + std::max(-1, selected)); + + gcn::Widget *parent; + parent = (gcn::Widget*)getParent(); + if (parent) + { + gcn::Rectangle scroll; + scroll.y = (mSelected < 0) ? 0 : getFont()->getHeight() * mSelected; + scroll.height = getFont()->getHeight(); + parent->showWidgetPart(this, scroll); + } + } + + distributeValueChangedEvent(); +} +*/ +void GuildListBox::mousePressed(gcn::MouseEvent &event) +{ + if (event.getButton() == gcn::MouseEvent::LEFT) + { + int y = event.getY(); + setSelected(y / getFont()->getHeight()); + distributeActionEvent(); + } + // TODO: Add guild functions, ie private messaging + if (event.getButton() == gcn::MouseEvent::RIGHT) + { + // Show context menu + } +} + +void GuildListBox::setOnlineStatus(const std::string &user, bool online) +{ + UserMap::iterator itr = mUsers.find(user); + if (itr == mUsers.end()) + { + mUsers.insert(std::pair<std::string, bool>(user, online)); + } + else + { + itr->second = online; + } + adjustSize(); +} diff --git a/src/gui/guildlistbox.h b/src/gui/guildlistbox.h new file mode 100644 index 00000000..8d6e74f1 --- /dev/null +++ b/src/gui/guildlistbox.h @@ -0,0 +1,65 @@ +/* + * The Mana World + * Copyright (C) 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef GUI_GUILDLISTBOX_H +#define GUI_GUILDLISTBOX_H + +#include <map> +#include <string> +#include <vector> + +#include "listbox.h" + +class Image; + +class GuildListBox : public ListBox +{ +public: + /** + * Constructor + */ + GuildListBox(); + + /** + * Draws the list box. + */ + void draw(gcn::Graphics *gcnGraphics); + + void mousePressed(gcn::MouseEvent &event); + + /** + * Sets the index of the selected element. + */ +// void setSelected(int selected); + + /** + * Set whether a member is online or offline + */ + void setOnlineStatus(const std::string &user, bool online); + +private: + Image *onlineIcon; + Image *offlineIcon; + typedef std::map<std::string, bool> UserMap; + UserMap mUsers; +}; + +#endif diff --git a/src/gui/guildwindow.cpp b/src/gui/guildwindow.cpp new file mode 100644 index 00000000..c8a1872f --- /dev/null +++ b/src/gui/guildwindow.cpp @@ -0,0 +1,273 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * $$ + */ + +#include "guildwindow.h" + +#include "button.h" +#include "chat.h" +#include "confirm_dialog.h" +#include "guildlistbox.h" +#include "scrollarea.h" +#include "textdialog.h" +#include "windowcontainer.h" + +#include "widgets/layout.h" +#include "widgets/tabbedarea.h" + +#include "../guild.h" +#include "../log.h" +#include "../localplayer.h" + +#include "../net/tmwserv/chatserver/guild.h" +#include "../utils/dtor.h" +#include "../utils/gettext.h" + +#include <algorithm> + +#include <guichan/widgets/tab.hpp> + +GuildWindow::GuildWindow(): + Window(_("Guild")), + mFocus(false) +{ + setWindowName("Guild"); + setCaption(_("Guild")); + setResizable(false); + setCloseButton(true); + setMinWidth(200); + setMinHeight(280); + setDefaultSize(124, 41, 288, 330); + + // Set button events Id + mGuildButton[0] = new Button(_("Create Guild"), "CREATE_GUILD", this); + mGuildButton[1] = new Button(_("Invite User"), "INVITE_USER", this); + mGuildButton[2] = new Button(_("Quit Guild"), "QUIT_GUILD", this); + mGuildButton[1]->setEnabled(false); + mGuildButton[2]->setEnabled(false); + + mGuildTabs = new TabbedArea(); + + place(0, 0, mGuildButton[0]); + place(1, 0, mGuildButton[1]); + place(2, 0, mGuildButton[2]); + place(0, 1, mGuildTabs); + Layout &layout = getLayout(); + layout.setColWidth(0, 48); + layout.setColWidth(1, 65); + + loadWindowState(); +} + +GuildWindow::~GuildWindow() +{ + delete mGuildTabs; +} + +void GuildWindow::update() +{ + updateTab(); + + if (mGuildButton[2]->isEnabled() && mGuildTabs->getNumberOfTabs() <= 0) + { + mGuildButton[2]->setEnabled(false); + mGuildButton[1]->setEnabled(false); + } +} + +void GuildWindow::draw(gcn::Graphics *g) +{ + update(); + + Window::draw(g); +} + +void GuildWindow::action(const gcn::ActionEvent &event) +{ + const std::string &eventId = event.getId(); + + // Stats Part + if (eventId == "CREATE_GUILD") + { + // Set focus so that guild name to be created can be typed. + mFocus = true; + guildDialog = new TextDialog("Guild Name", "Choose your guild's name", this); + guildDialog->setOKButtonActionId("CREATE_GUILD_OK"); + guildDialog->addActionListener(this); + } + else if (eventId == "INVITE_USER") + { + // TODO - Give feedback on whether the invite succeeded + mFocus = true; + inviteDialog = new TextDialog("Member Invite", "Who would you like to invite?", this); + inviteDialog->setOKButtonActionId("INVITE_USER_OK"); + inviteDialog->addActionListener(this); + } + else if (eventId == "QUIT_GUILD") + { + short guild = getSelectedGuild(); + if (guild) + { + Net::ChatServer::Guild::quitGuild(guild); + localChatTab->chatLog("Guild " + mGuildTabs->getSelectedTab()->getCaption() + " quit", BY_SERVER); + } + } + else if (eventId == "CREATE_GUILD_OK") + { + std::string name = guildDialog->getText(); + if(name.size() > 16) + { + // TODO : State too many characters in input. + return; + } + // Process guild name to be created, and unfocus. + Net::ChatServer::Guild::createGuild(name); + + // Defocus dialog + mFocus = false; + localChatTab->chatLog("Creating Guild called " + name, BY_SERVER); + guildDialog->scheduleDelete(); + } + else if (eventId == "INVITE_USER_OK") + { + std::string name = inviteDialog->getText(); + short selectedGuild = getSelectedGuild(); + + // Process invited user to be created and unfocus. + Net::ChatServer::Guild::invitePlayer(name, selectedGuild); + + // Defocus dialog + mFocus = false; + localChatTab->chatLog("Invited user " + name, BY_SERVER); + inviteDialog->scheduleDelete(); + } + else if (eventId == "yes") + { + logger->log("Sending invitation acceptance."); + Net::ChatServer::Guild::acceptInvite(invitedGuild); + } +} + +void GuildWindow::newGuildTab(const std::string &guildName) +{ + // Create new tab + GuildListBox *list = new GuildListBox(); + list->setListModel(player_node->getGuild(guildName)); + ScrollArea *sa = new ScrollArea(list); + sa->setDimension(gcn::Rectangle(5, 5, 135, 250)); + + // Add the listbox to the map + mGuildLists.insert(std::pair<std::string, GuildListBox*>(guildName, list)); + + mGuildTabs->addTab(guildName, sa); + mGuildTabs->setDimension(gcn::Rectangle(28,35,140,250)); + + updateTab(); +} + +void GuildWindow::updateTab() +{ + gcn::Tab *tab = mGuildTabs->getSelectedTab(); + if (tab) + { + setTab(tab->getCaption()); + } + mGuildTabs->logic(); +} + +void GuildWindow::setTab(const std::string &guildName) +{ + // Only enable invite button if user has rights + if(player_node->checkInviteRights(guildName)) + { + mGuildButton[1]->setEnabled(true); + } + else + { + mGuildButton[1]->setEnabled(false); + } + + mGuildButton[2]->setEnabled(true); +} + +bool GuildWindow::isWindowFocused() +{ + return mFocus; +} + +short GuildWindow::getSelectedGuild() +{ + if (mGuildTabs->getNumberOfTabs() > 0) + { + + Guild *guild = player_node->getGuild(mGuildTabs->getSelectedTab()->getCaption()); + + if (guild) + { + return guild->getId(); + } + } + + return 0; +} + +void GuildWindow::openAcceptDialog(const std::string &inviterName, + const std::string &guildName) +{ + std::string msg = inviterName + " has invited you to join the guild " + guildName; + localChatTab->chatLog(msg, BY_SERVER); + + acceptDialog = new ConfirmDialog("Accept Guild Invite", msg, this); + acceptDialog->addActionListener(this); + + invitedGuild = guildName; +} + +void GuildWindow::requestMemberList(short guildId) +{ + // Get the list of members for displaying in the guild window. + Net::ChatServer::Guild::getGuildMembers(guildId); +} + +void GuildWindow::removeTab(int guildId) +{ + Guild* guild = player_node->getGuild(guildId); + if (guild) + { + Tab *tab = mGuildTabs->getTab(guild->getName()); + if (tab) + { + mGuildTabs->removeTab(tab); + } + updateTab(); + } + mGuildTabs->logic(); +} + +void GuildWindow::setOnline(const std::string &guildName, const std::string &member, + bool online) +{ + GuildListMap::iterator itr = mGuildLists.find(guildName); + if (itr != mGuildLists.end()) + { + itr->second->setOnlineStatus(member, online); + } +} diff --git a/src/gui/guildwindow.h b/src/gui/guildwindow.h new file mode 100644 index 00000000..88a084e9 --- /dev/null +++ b/src/gui/guildwindow.h @@ -0,0 +1,135 @@ +/* + * The Mana World + * Copyright (C) 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef GUI_GUILDWINDOW_H +#define GUI_GUILDWINDOW_H + +#include <iosfwd> +#include <map> +#include <vector> + +#include <guichan/actionlistener.hpp> +#include <guichan/widgets/listbox.hpp> + +#include "window.h" + +#include "../guichanfwd.h" + +class LocalPlayer; +class TextDialog; +class ConfirmDialog; +class GuildListBox; +class ScrollArea; +class GCContainer; +class TabbedArea; + +class GuildWindow : public Window, public gcn::ActionListener +{ +public: + /** + * Constructor. + */ + GuildWindow(); + + /** + * Destructor. + */ + ~GuildWindow(); + + /** + * Called when receiving actions from widget. + */ + void action(const gcn::ActionEvent &event); + + /** + * Draw this window. + */ + void draw(gcn::Graphics *graphics); + + /** + * Updates this dialog. + */ + void update(); + + /** + * Create a new tab for a guild list. + */ + void newGuildTab(const std::string &guildName); + + /** + * Display guild's member list to active tab + */ + void setTab(const std::string &guildName); + + /** + * Update the contents of the active tab + */ + void updateTab(); + + /** + * Check if the window is in focus. + */ + bool isWindowFocused(); + + /** + * Create a dialog for accepting an invite + */ + void openAcceptDialog(const std::string &inviterName, const std::string &guildName); + + /** + * Request member list + */ + void requestMemberList(short guildId); + + /** + * Removes the selected tab + */ + void removeTab(int guildId); + + /** + * Set guild member status in userlist + */ + void setOnline(const std::string &guildName, const std::string &member, + bool online); + +protected: + /** + * Get selected guild tab + * @return Returns selected guild + */ + short getSelectedGuild(); + +private: + gcn::Button *mGuildButton[3]; + TextDialog *guildDialog; + TextDialog *inviteDialog; + ConfirmDialog *acceptDialog; + TabbedArea *mGuildTabs; + ScrollArea *mScrollArea; + bool mFocus; + std::string invitedGuild; + typedef std::map<std::string, GuildListBox*> GuildListMap; + GuildListMap mGuildLists; +}; + +extern GuildWindow *guildWindow; + +#endif diff --git a/src/gui/help.cpp b/src/gui/help.cpp index 0974abf7..4b4ba983 100644 --- a/src/gui/help.cpp +++ b/src/gui/help.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,12 +36,12 @@ HelpWindow::HelpWindow(): setMinWidth(300); setMinHeight(250); setContentSize(455, 350); - setWindowName(_("Help")); + setWindowName("Help"); setResizable(true); setDefaultSize(500, 400, ImageRect::CENTER); - mBrowserBox = new BrowserBox(); + mBrowserBox = new BrowserBox; mBrowserBox->setOpaque(false); mScrollArea = new ScrollArea(mBrowserBox); Button *okButton = new Button(_("Close"), "close", this); @@ -71,7 +70,7 @@ void HelpWindow::action(const gcn::ActionEvent &event) } } -void HelpWindow::handleLink(const std::string& link) +void HelpWindow::handleLink(const std::string &link) { std::string helpFile = link; loadHelp(helpFile); diff --git a/src/gui/help.h b/src/gui/help.h index 93d32c18..8764e733 100644 --- a/src/gui/help.h +++ b/src/gui/help.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -50,7 +49,7 @@ class HelpWindow : public Window, public LinkHandler, /** * Handles link action. */ - void handleLink(const std::string& link); + void handleLink(const std::string &link); /** * Loads help in the dialog. diff --git a/src/gui/icon.cpp b/src/gui/icon.cpp new file mode 100644 index 00000000..c4f0ecc3 --- /dev/null +++ b/src/gui/icon.cpp @@ -0,0 +1,58 @@ +/* + * The Mana World + * Copyright (C) 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "icon.h" + +#include "../graphics.h" + +#include "../resources/image.h" +#include "../resources/resourcemanager.h" + +Icon::Icon(const std::string &file) + : mImage(0) +{ + mImage = ResourceManager::getInstance()->getImage(file); + setSize(mImage->getWidth(), mImage->getHeight()); + +} + +Icon::Icon(Image *image) + : mImage(image) +{ + setSize(mImage->getWidth(), mImage->getHeight()); +} + +void Icon::setImage(Image *image) +{ + mImage = image; + setSize(mImage->getWidth(), mImage->getHeight()); +} + +void Icon::draw(gcn::Graphics *g) +{ + if(mImage) + { + Graphics *graphics = static_cast<Graphics*>(g); + const int x = (getWidth() - mImage->getWidth()) / 2; + const int y = (getHeight() - mImage->getHeight()) / 2; + graphics->drawImage(mImage, x, y); + } +} diff --git a/src/gui/icon.h b/src/gui/icon.h new file mode 100644 index 00000000..f8d77e0f --- /dev/null +++ b/src/gui/icon.h @@ -0,0 +1,66 @@ +/* + * The Mana World + * Copyright (C) 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef ICON_H +#define ICON_H + +#include <guichan/widget.hpp> + +class Image; + +/** + * An icon. + * + * \ingroup GUI + */ +class Icon : public gcn::Widget +{ + public: + /** + * Constructor. + */ + Icon(const std::string &filename); + + /** + * Constructor, uses an existing Image. + */ + Icon(Image *image); + + /** + * Gets the current Image. + */ + Image *getImage() const { return mImage; } + + /** + * Sets the image to display. + */ + void setImage(Image *image); + + /** + * Draws the Icon. + */ + void draw(gcn::Graphics *g); + + private: + Image *mImage; +}; + +#endif // ICON_H diff --git a/src/gui/inttextfield.cpp b/src/gui/inttextfield.cpp index 40bbd887..d3fe448b 100644 --- a/src/gui/inttextfield.cpp +++ b/src/gui/inttextfield.cpp @@ -1,8 +1,8 @@ /* - * Aethyra - * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> + * The Mana World + * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -57,6 +57,16 @@ void IntTextField::setRange(int min, int max) { mMin = min; mMax = max; + + if (mValue < mMin) + mValue = mMin; + else if (mValue > mMax) + mValue = mMax; + + if (mDefault < mMin) + mDefault = mMin; + else if (mDefault > mMax) + mDefault = mMax; } int IntTextField::getValue() @@ -66,18 +76,28 @@ int IntTextField::getValue() void IntTextField::setValue(int i) { - if (i >= mMin && i <= mMax) - mValue = i; - else if (i < mMin) + if (i < mMin) mValue = mMin; else if (i > mMax) mValue = mMax; + else + mValue = i; const std::string valStr = toString(mValue); setText(valStr); setCaretPosition(valStr.length() + 1); } +void IntTextField::setDefaultValue(int value) +{ + if (value < mMin) + mDefault = mMin; + else if (value > mMax) + mDefault = mMax; + else + mDefault = value; +} + void IntTextField::reset() { setValue(mDefault); diff --git a/src/gui/inttextfield.h b/src/gui/inttextfield.h index f2e294ca..ec768bea 100644 --- a/src/gui/inttextfield.h +++ b/src/gui/inttextfield.h @@ -1,8 +1,8 @@ /* - * Aethyra - * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> + * The Mana World + * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -56,6 +56,11 @@ class IntTextField : public TextField void setValue(int value); /** + * Set the default value of the text box to the specified value. + */ + void setDefaultValue(int value); + + /** * Responds to key presses. */ void keyPressed(gcn::KeyEvent &event); diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index fef55b6c..21d2df3f 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,6 +31,7 @@ #include "label.h" #include "progressbar.h" #include "scrollarea.h" +#include "sdlinput.h" #include "viewport.h" #include "widgets/layout.h" @@ -39,6 +39,7 @@ #include "../inventory.h" #include "../item.h" #include "../localplayer.h" +#include "../units.h" #include "../resources/iteminfo.h" @@ -48,14 +49,19 @@ InventoryWindow::InventoryWindow(int invSize): Window(_("Inventory")), mMaxSlots(invSize), + mSplit(false), mItemDesc(false) { - setWindowName(_("Inventory")); - setResizable(true); + setWindowName("Inventory"); + setResizable(false); setCloseButton(true); - + // LEEOR/TODO: Since this window is not resizable, do we really need to set these + // values or can we drop them? + setMinWidth(375); + setMinHeight(283); // If you adjust these defaults, don't forget to adjust the trade window's. setDefaultSize(375, 300, ImageRect::CENTER); + addKeyListener(this); std::string longestUseString = getFont()->getWidth(_("Equip")) > getFont()->getWidth(_("Use")) ? @@ -69,16 +75,23 @@ InventoryWindow::InventoryWindow(int invSize): mUseButton = new Button(longestUseString, "use", this); mDropButton = new Button(_("Drop"), "drop", this); - - mItems = new ItemContainer(player_node->getInventory(), 2); +#ifdef TMWSERV_SUPPORT + mSplitButton = new Button(_("Split"), "split", this); +#endif + +#ifdef TMWSERV_SUPPORT + mItems = new ItemContainer(player_node->getInventory(), 10, 5); +#else + mItems = new ItemContainer(player_node->getInventory(), 10, 5, 2); +#endif mItems->addSelectionListener(this); mInvenScroll = new ScrollArea(mItems); mInvenScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - mTotalWeight = player_node->mTotalWeight; - mMaxWeight = player_node->mMaxWeight; - mUsedSlots = player_node->getInventory()->getNumberOfSlotsUsed(); + mTotalWeight = -1; + mMaxWeight = -1; + mUsedSlots = -1; mSlotsLabel = new Label(_("Slots: ")); mWeightLabel = new Label(_("Weight: ")); @@ -93,12 +106,15 @@ InventoryWindow::InventoryWindow(int invSize): place(1, 0, mWeightBar, 3); place(4, 0, mSlotsLabel).setPadding(3); place(5, 0, mSlotsBar, 2); - place(0, 1, mInvenScroll, 7, 4); - place(5, 5, mDropButton); - place(6, 5, mUseButton); + place(0, 1, mInvenScroll, 100).setPadding(3); + place(0, 2, mUseButton); + place(1, 2, mDropButton); +#ifdef TMWSERV_SUPPORT + place(2, 2, mSplitButton); +#endif Layout &layout = getLayout(); - layout.setRowHeight(0, mDropButton->getHeight()); + layout.setRowHeight(0, Layout::AUTO_SET); loadWindowState(); } @@ -121,17 +137,18 @@ void InventoryWindow::logic() const int usedSlots = player_node->getInventory()->getNumberOfSlotsUsed(); - if (mMaxWeight != player_node->mMaxWeight || - mTotalWeight != player_node->mTotalWeight || mUsedSlots != usedSlots) + if (mMaxWeight != player_node->getMaxWeight() || + mTotalWeight != player_node->getTotalWeight() || + mUsedSlots != usedSlots) { - mTotalWeight = player_node->mTotalWeight; - mMaxWeight = player_node->mMaxWeight; + mTotalWeight = player_node->getTotalWeight(); + mMaxWeight = player_node->getMaxWeight(); mUsedSlots = usedSlots; // Weight Bar coloration if (mTotalWeight < (mMaxWeight / 3)) mWeightBar->setColor(0, 0, 255); // Blue - else if (mTotalWeight < ((mMaxWeight / 3) * 2)) + else if (mTotalWeight < ((mMaxWeight * 2) / 3)) mWeightBar->setColor(255, 255, 0); // Yellow else mWeightBar->setColor(255, 0, 0); // Red @@ -141,7 +158,9 @@ void InventoryWindow::logic() mWeightBar->setProgress((float) mTotalWeight / mMaxWeight); mSlotsBar->setText(strprintf("%d/%d", mUsedSlots, mMaxSlots)); - mWeightBar->setText(strprintf("%dg/%dg", mTotalWeight, mMaxWeight)); + mWeightBar->setText(strprintf("%s/%s", + Units::formatWeight(mTotalWeight).c_str(), + Units::formatWeight(mMaxWeight).c_str())); } } @@ -154,6 +173,14 @@ void InventoryWindow::action(const gcn::ActionEvent &event) if (event.getId() == "use") { +#ifdef TMWSERV_SUPPORT + if (item->isEquipment()) { + player_node->equipItem(item); + } + else { + player_node->useItem(item->getInvIndex()); + } +#else if (item->isEquipment()) { if (item->isEquipped()) @@ -163,19 +190,33 @@ void InventoryWindow::action(const gcn::ActionEvent &event) } else player_node->useItem(item); +#endif } else if (event.getId() == "drop") { - if (item->getQuantity() == 1) - player_node->dropItem(item, 1); - else - { + if (item->getQuantity() > 1) { // Choose amount of items to drop new ItemAmountWindow(AMOUNT_ITEM_DROP, this, item); } + else { + player_node->dropItem(item, 1); + } + mItems->selectNone(); + } + else if (event.getId() == "split") + { + if (item && !item->isEquipment() && item->getQuantity() > 1) { + new ItemAmountWindow(AMOUNT_ITEM_SPLIT, this, item, + (item->getQuantity() - 1)); + } } } +Item* InventoryWindow::getSelectedItem() const +{ + return mItems->getSelectedItem(); +} + void InventoryWindow::mouseClicked(gcn::MouseEvent &event) { Window::mouseClicked(event); @@ -196,15 +237,55 @@ void InventoryWindow::mouseClicked(gcn::MouseEvent &event) } } +#ifdef TMWSERV_SUPPORT +void InventoryWindow::keyPressed(gcn::KeyEvent &event) +{ + switch (event.getKey().getValue()) + { + case Key::LEFT_SHIFT: + case Key::RIGHT_SHIFT: + mSplit = true; + break; + } +} + +void InventoryWindow::keyReleased(gcn::KeyEvent &event) +{ + switch (event.getKey().getValue()) + { + case Key::LEFT_SHIFT: + case Key::RIGHT_SHIFT: + mSplit = false; + break; + } +} +#endif + +void InventoryWindow::valueChanged(const gcn::SelectionEvent &event) +{ + if (mSplit) + { + Item *item = mItems->getSelectedItem(); + + if (item && !item->isEquipment() && item->getQuantity() > 1) + { + mSplit = false; + new ItemAmountWindow(AMOUNT_ITEM_SPLIT, this, item, (item->getQuantity() - 1)); + } + } +} + void InventoryWindow::updateButtons() { const Item *selectedItem = mItems->getSelectedItem(); if (selectedItem && selectedItem->isEquipment()) { +#ifdef EATHENA_SUPPORT if (selectedItem->isEquipped()) mUseButton->setCaption(_("Unequip")); else +#endif mUseButton->setCaption(_("Equip")); } else @@ -212,9 +293,15 @@ void InventoryWindow::updateButtons() mUseButton->setEnabled(selectedItem != 0); mDropButton->setEnabled(selectedItem != 0); -} -Item* InventoryWindow::getSelectedItem() const -{ - return mItems->getSelectedItem(); +#ifdef TMWSERV_SUPPORT + if (selectedItem && !selectedItem->isEquipment() && + selectedItem->getQuantity() > 1) + { + mSplitButton->setEnabled(true); + } + else { + mSplitButton->setEnabled(false); + } +#endif } diff --git a/src/gui/inventorywindow.h b/src/gui/inventorywindow.h index 5035bf1c..0bdc8809 100644 --- a/src/gui/inventorywindow.h +++ b/src/gui/inventorywindow.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,13 +22,14 @@ #ifndef INVENTORYWINDOW_H #define INVENTORYWINDOW_H -#include <guichan/actionlistener.hpp> -#include <guichan/selectionlistener.hpp> - #include "window.h" #include "../inventory.h" +#include <guichan/actionlistener.hpp> +#include <guichan/keylistener.hpp> +#include <guichan/selectionlistener.hpp> + class Item; class ItemContainer; class ProgressBar; @@ -40,14 +40,20 @@ class TextBox; * * \ingroup Interface */ -class InventoryWindow : public Window, gcn::ActionListener, - gcn::SelectionListener +class InventoryWindow : public Window, + public gcn::ActionListener, + public gcn::KeyListener, + public gcn::SelectionListener { public: /** * Constructor. */ +#ifdef TMWSERV_SUPPORT + InventoryWindow(int invSize = (INVENTORY_SIZE)); +#else InventoryWindow(int invSize = (INVENTORY_SIZE - 2)); +#endif /** * Destructor. @@ -69,8 +75,28 @@ class InventoryWindow : public Window, gcn::ActionListener, */ Item* getSelectedItem() const; + /** + * Handles the mouse clicks. + */ void mouseClicked(gcn::MouseEvent &event); +#ifdef TMWSERV_SUPPORT + /** + * Handles the key presses. + */ + void keyPressed(gcn::KeyEvent &event); + + /** + * Handles the key releases. + */ + void keyReleased(gcn::KeyEvent &event); +#endif + + /** + * Updates labels to currently selected item. + */ + void valueChanged(const gcn::SelectionEvent &event); + private: void updateButtons(); /**< Updates button states. */ @@ -81,9 +107,12 @@ class InventoryWindow : public Window, gcn::ActionListener, int mUsedSlots; int mTotalWeight; int mMaxWeight; - gcn::Button *mUseButton, *mDropButton; - gcn::ScrollArea *mInvenScroll; - + gcn::Button *mUseButton; + gcn::Button *mDropButton; +#ifdef TMWSERV_SUPPORT + gcn::Button *mSplitButton; +#endif + gcn::ScrollArea *mInvenScroll; /**< Inventory Scroll Area. */ gcn::Label *mWeightLabel; gcn::Label *mSlotsLabel; @@ -92,6 +121,7 @@ class InventoryWindow : public Window, gcn::ActionListener, int mMaxSlots; + bool mSplit; bool mItemDesc; }; diff --git a/src/gui/item_amount.cpp b/src/gui/item_amount.cpp index 5b3380c2..0f6aa593 100644 --- a/src/gui/item_amount.cpp +++ b/src/gui/item_amount.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,7 +23,9 @@ #include "item_amount.h" #include "label.h" #include "slider.h" +#ifdef EATHENA_SUPPORT #include "storagewindow.h" +#endif #include "trade.h" #include "widgets/layout.h" @@ -35,12 +36,16 @@ #include "../utils/gettext.h" #include "../utils/strprintf.h" -ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item): +ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item, + int maxRange): Window("", true, parent), mItem(item), - mMax(item->getQuantity()), + mMax(maxRange), mUsage(usage) { + if (!mMax) + mMax = mItem->getQuantity(); + setCloseButton(true); // Integer field @@ -94,6 +99,9 @@ ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item): case AMOUNT_STORE_REMOVE: setCaption(_("Select amount of items to retrieve.")); break; + case AMOUNT_ITEM_SPLIT: + setCaption(_("Select amount of items to split.")); + break; default: break; } @@ -140,12 +148,18 @@ void ItemAmountWindow::action(const gcn::ActionEvent &event) case AMOUNT_ITEM_DROP: player_node->dropItem(mItem, amount); break; +#ifdef TMWSERV_SUPPORT + case AMOUNT_ITEM_SPLIT: + player_node->splitItem(mItem, amount); + break; +#else case AMOUNT_STORE_ADD: storageWindow->addStore(mItem, amount); break; case AMOUNT_STORE_REMOVE: storageWindow->removeStore(mItem, amount); break; +#endif default: return; break; diff --git a/src/gui/item_amount.h b/src/gui/item_amount.h index 34b33b37..344f8c28 100644 --- a/src/gui/item_amount.h +++ b/src/gui/item_amount.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,9 +33,10 @@ class Item; #define AMOUNT_ITEM_DROP 2 #define AMOUNT_STORE_ADD 3 #define AMOUNT_STORE_REMOVE 4 +#define AMOUNT_ITEM_SPLIT 5 /** - * Window used for selecting the amount of items to drop or trade. + * Window used for selecting the amount of items to drop, trade or split. * * \ingroup Interface */ @@ -46,7 +46,7 @@ class ItemAmountWindow : public Window, public gcn::ActionListener /** * Constructor. */ - ItemAmountWindow(int usage, Window *parent, Item *item); + ItemAmountWindow(int usage, Window *parent, Item *item, int maxRange = 0); /** * Called when receiving actions from widget. diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp index 8139e85e..960f58ad 100644 --- a/src/gui/itemcontainer.cpp +++ b/src/gui/itemcontainer.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,49 +19,72 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <guichan/mouseinput.hpp> -#include <guichan/selectionlistener.hpp> +#include "gui/itemcontainer.h" -#include "itemcontainer.h" -#include "itempopup.h" -#include "palette.h" -#include "viewport.h" +#include "gui/chat.h" +#include "gui/itempopup.h" +#include "gui/palette.h" +#include "gui/sdlinput.h" +#include "gui/viewport.h" -#include "../graphics.h" -#include "../inventory.h" -#include "../item.h" -#include "../itemshortcut.h" -#include "../localplayer.h" -#include "../log.h" +#include "graphics.h" +#include "inventory.h" +#include "item.h" +#include "itemshortcut.h" +#include "localplayer.h" +#include "log.h" -#include "../resources/image.h" -#include "../resources/resourcemanager.h" +#include "resources/image.h" +#include "resources/iteminfo.h" +#include "resources/resourcemanager.h" -#include "../utils/stringutils.h" +#include "utils/stringutils.h" -const int ItemContainer::gridWidth = 36; // item icon width + 4 -const int ItemContainer::gridHeight = 42; // item icon height + 10 +#include <guichan/mouseinput.hpp> +#include <guichan/selectionlistener.hpp> -static const int NO_ITEM = -1; +// TODO: Add support for adding items to the item shortcut window (global +// itemShortcut). -ItemContainer::ItemContainer(Inventory *inventory, int offset): +static const int BOX_WIDTH = 36; +static const int BOX_HEIGHT = 44; + +enum +{ + SEL_NONE = 0, + SEL_SELECTED, + SEL_SELECTING, + SEL_DESELECTING, + SEL_DRAGGING +}; + +ItemContainer::ItemContainer(Inventory *inventory, + int gridColumns, + int gridRows, + int offset): mInventory(inventory), - mSelectedItemIndex(NO_ITEM), - mLastSelectedItemId(NO_ITEM), - mOffset(offset) + mGridColumns(gridColumns), + mGridRows(gridRows), + mOffset(offset), + mSelectedItem(NULL), + mHighlightedItem(NULL), + mSelectionStatus(SEL_NONE), + mSwapItems(false), + mDescItems(false) { mItemPopup = new ItemPopup(); - mItemPopup->setOpaque(false); + setFocusable(true); ResourceManager *resman = ResourceManager::getInstance(); mSelImg = resman->getImage("graphics/gui/selection.png"); if (!mSelImg) logger->error("Unable to load selection.png"); - mMaxItems = mInventory->getLastUsedSlot() - (mOffset - 1); // Count from 0, usage from 2 - + addKeyListener(this); addMouseListener(this); - addWidgetListener(this); + + setSize((BOX_WIDTH - 1) * mGridColumns + 1, + (BOX_HEIGHT - 1) * mGridRows + 1); } ItemContainer::~ItemContainer() @@ -71,185 +93,214 @@ ItemContainer::~ItemContainer() delete mItemPopup; } -void ItemContainer::logic() -{ - if (!isVisible()) - return; - - gcn::Widget::logic(); - - int i = mInventory->getLastUsedSlot() - (mOffset - 1); // Count from 0, usage from 2 - - if (i != mMaxItems) - { - mMaxItems = i; - recalculateHeight(); - } -} - void ItemContainer::draw(gcn::Graphics *graphics) { - if (!isVisible()) - return; - - int columns = getWidth() / gridWidth; + Graphics *g = static_cast<Graphics*>(graphics); - // Have at least 1 column - if (columns < 1) - columns = 1; - - /* - * mOffset is used to compensate for some weirdness that eAthena inherited - * from Ragnarok Online. Inventory slots and cart slots are +2 from their - * actual index, while storage slots are +1. - */ - for (int i = mOffset; i < mInventory->getSize(); i++) + for (int i = 0; i < mGridColumns; i++) { - Item *item = mInventory->getItem(i); - - if (!item || item->getQuantity() <= 0) - continue; + for (int j = 0; j < mGridRows; j++) + { + // Items positions made to overlap on another. + int itemX = i * (BOX_WIDTH - 1); + int itemY = j * (BOX_HEIGHT - 1); - int itemX = ((i - mOffset) % columns) * gridWidth; - int itemY = ((i - mOffset) / columns) * gridHeight; + // Set color to black. + g->setColor(gcn::Color(0, 0, 0)); + // Draw box border. + g->drawRectangle( + gcn::Rectangle(itemX, itemY, BOX_WIDTH, BOX_HEIGHT)); - // Draw selection image below selected item - if (mSelectedItemIndex == i) - static_cast<Graphics*>(graphics)->drawImage(mSelImg, itemX, itemY); + Item *item = mInventory->getItem((j * mGridColumns) + i); - // Draw item icon - Image* image = item->getImage(); + if (!item || item->getId() == 0) + continue; - if (image) - static_cast<Graphics*>(graphics)->drawImage(image, itemX, itemY); + Image *image = item->getImage(); + if (image) + { + if (item == mSelectedItem) + { + if (mSelectionStatus == SEL_DRAGGING) { + // Reposition the coords to that of the cursor. + itemX = mDragPosX - (BOX_WIDTH / 2); + itemY = mDragPosY - (BOX_HEIGHT / 2); + } + else { + // Draw selected image. + g->drawImage(mSelImg, itemX, itemY); + } + } + g->drawImage(image, itemX, itemY); + } + if (item->getQuantity() > 1) { + // Draw item caption + g->drawText( + toString(item->getQuantity()), + itemX + BOX_WIDTH / 2, + itemY + BOX_HEIGHT - 14, + gcn::Graphics::CENTER); + } - // Draw item caption - graphics->setFont(getFont()); - graphics->setColor(guiPalette->getColor(Palette::TEXT)); - graphics->drawText( - (item->isEquipped() ? "Eq." : toString(item->getQuantity())), - itemX + gridWidth / 2, itemY + gridHeight - 11, - gcn::Graphics::CENTER); + } } -} -void ItemContainer::widgetResized(const gcn::Event &event) -{ - recalculateHeight(); + if (isFocused() && mHighlightedItem) { + // Items positions made to overlap on another. + const int i = mHighlightedItem->getInvIndex(); + const int itemX = (i % mGridColumns) * (BOX_WIDTH - 1); + const int itemY = (i / mGridColumns) * (BOX_HEIGHT - 1); + // Set color to orange. + g->setColor(gcn::Color(255, 128, 0)); + // Draw box border. + g->drawRectangle(gcn::Rectangle(itemX, itemY, BOX_WIDTH, BOX_HEIGHT)); + } } -void ItemContainer::recalculateHeight() +void ItemContainer::selectNone() { - int cols = getWidth() / gridWidth; - - if (cols < 1) - cols = 1; - - const int rows = (mMaxItems / cols) + (mMaxItems % cols > 0 ? 1 : 0); - const int height = rows * gridHeight + 8; - - if (height != getHeight()) - setHeight(height); + setSelectedItem(NULL); } -Item *ItemContainer::getSelectedItem() +void ItemContainer::setSelectedItem(Item *item) { - refindSelectedItem(); // Make sure that we're still current - - if (mSelectedItemIndex == NO_ITEM) - return NULL; - - return mInventory->getItem(mSelectedItemIndex); + if (mSelectedItem != item) + { + mSelectedItem = item; + distributeValueChangedEvent(); + } } -void ItemContainer::selectNone() +void ItemContainer::distributeValueChangedEvent() { - setSelectedItemIndex(NO_ITEM); -} + SelectionListenerIterator iter; -void ItemContainer::refindSelectedItem() -{ - if (mSelectedItemIndex != NO_ITEM) + for (iter = mSelectionListeners.begin(); iter != mSelectionListeners.end(); + ++iter) { - - if (mInventory->getItem(mSelectedItemIndex) && - mInventory->getItem(mSelectedItemIndex)->getId() == mLastSelectedItemId) - return; // we're already fine - - // Otherwise ensure the invariant: we must point to an item of the specified last ID, - // or nowhere at all. - - for (int i = 0; i <= mMaxItems + 1; i++) - if (mInventory->getItem(i) && - mInventory->getItem(i)->getId() == mLastSelectedItemId) - { - mSelectedItemIndex = i; - return; - } + gcn::SelectionEvent event(this); + (*iter)->valueChanged(event); } - - mLastSelectedItemId = mSelectedItemIndex = NO_ITEM; } -void ItemContainer::setSelectedItemIndex(int index) +void ItemContainer::keyPressed(gcn::KeyEvent &event) { - int newSelectedItemIndex; - - /* - * mOffset is used to compensate for some weirdness that eAthena inherited from - * Ragnarok Online. Inventory slots and cart slots are +2 from their actual index, - * while storage slots are +1. - */ - if (index < 0 || index > mMaxItems + mOffset || mInventory->getItem(index) == NULL) - newSelectedItemIndex = NO_ITEM; - else - newSelectedItemIndex = index; - if (mSelectedItemIndex != newSelectedItemIndex) + switch (event.getKey().getValue()) { - mSelectedItemIndex = newSelectedItemIndex; - - if (mSelectedItemIndex == NO_ITEM) - mLastSelectedItemId = NO_ITEM; - else - mLastSelectedItemId = mInventory->getItem(index)->getId(); - - distributeValueChangedEvent(); + case Key::LEFT: + moveHighlight(MOVE_SELECTED_LEFT); + break; + case Key::RIGHT: + moveHighlight(MOVE_SELECTED_RIGHT); + break; + case Key::UP: + moveHighlight(MOVE_SELECTED_UP); + break; + case Key::DOWN: + moveHighlight(MOVE_SELECTED_DOWN); + break; + case Key::SPACE: + keyAction(); + break; + case Key::LEFT_ALT: + case Key::RIGHT_ALT: + mSwapItems = true; + break; + case Key::RIGHT_CONTROL: + mDescItems = true; + break; } } -void ItemContainer::distributeValueChangedEvent() +void ItemContainer::keyReleased(gcn::KeyEvent &event) { - gcn::SelectionEvent event(this); - std::list<gcn::SelectionListener*>::iterator i_end = mListeners.end(); - std::list<gcn::SelectionListener*>::iterator i; - - for (i = mListeners.begin(); i != i_end; ++i) + switch (event.getKey().getValue()) { - (*i)->valueChanged(event); + case Key::LEFT_ALT: + case Key::RIGHT_ALT: + mSwapItems = false; + break; + case Key::RIGHT_CONTROL: + mDescItems = false; + break; } } void ItemContainer::mousePressed(gcn::MouseEvent &event) { const int button = event.getButton(); - if (button == gcn::MouseEvent::LEFT || button == gcn::MouseEvent::RIGHT) { - int columns = getWidth() / gridWidth; - int mx = event.getX(); - int my = event.getY(); - int index = mx / gridWidth + ((my / gridHeight) * columns) + mOffset; - - itemShortcut->setItemSelected(-1); - setSelectedItemIndex(index); + const int index = getSlotIndex(event.getX(), event.getY()); + if (index == Inventory::NO_SLOT_INDEX) { + return; + } Item *item = mInventory->getItem(index); - if (item) + // put item name into chat window + if (mDescItems) + { + chatWindow->addItemText(item->getInfo().getName()); + } + + if (mSelectedItem && mSelectedItem == item) + { + mSelectionStatus = SEL_DESELECTING; + } + else if (item && item->getId()) + { + setSelectedItem(item); + mSelectionStatus = SEL_SELECTING; + itemShortcut->setItemSelected(item->getId()); + } + else + { + setSelectedItem(NULL); + mSelectionStatus = SEL_NONE; + } + } +} + +void ItemContainer::mouseDragged(gcn::MouseEvent &event) +{ + if (mSelectionStatus != SEL_NONE) + { + mSelectionStatus = SEL_DRAGGING; + mDragPosX = event.getX(); + mDragPosY = event.getY(); } } +void ItemContainer::mouseReleased(gcn::MouseEvent &event) +{ + switch (mSelectionStatus) + { + case SEL_SELECTING: + mSelectionStatus = SEL_SELECTED; + return; + case SEL_DESELECTING: + setSelectedItem(NULL); + mSelectionStatus = SEL_NONE; + return; + case SEL_DRAGGING: + mSelectionStatus = SEL_SELECTED; + break; + default: + return; + }; + + int index = getSlotIndex(event.getX(), event.getY()); + if (index == Inventory::NO_SLOT_INDEX) return; + Item *item = mInventory->getItem(index); + if (item == mSelectedItem) return; + player_node->moveInvItem(mSelectedItem, index); + setSelectedItem(NULL); + mSelectionStatus = SEL_NONE; +} + + // Show ItemTooltip void ItemContainer::mouseMoved(gcn::MouseEvent &event) { @@ -276,9 +327,95 @@ void ItemContainer::mouseExited(gcn::MouseEvent &event) int ItemContainer::getSlotIndex(const int posX, const int posY) const { - int columns = getWidth() / gridWidth; - int index = posX / gridWidth + ((posY / gridHeight) * columns) + mOffset; + if (getDimension().isPointInRect(posX, posY)) + { + // Takes into account, boxes are overlapping each other. + return (posY / (BOX_HEIGHT - 1)) * mGridColumns + (posX / (BOX_WIDTH - 1)); + } + return Inventory::NO_SLOT_INDEX; +} + +void ItemContainer::keyAction() +{ + // If there is no highlight then return. + if (!mHighlightedItem) + return; - return (index); + // If the highlight is on the selected item, then deselect it. + if (mHighlightedItem == mSelectedItem) + { + setSelectedItem(NULL); + mSelectionStatus = SEL_NONE; + } + // Check and swap items if necessary. + else if (mSwapItems && + mSelectedItem && + mHighlightedItem->getId()) + { + player_node->moveInvItem( + mSelectedItem, mHighlightedItem->getInvIndex()); + setSelectedItem(mHighlightedItem); + } + // If the highlight is on an item then select it. + else if (mHighlightedItem->getId()) + { + setSelectedItem(mHighlightedItem); + mSelectionStatus = SEL_SELECTED; + } + // If the highlight is on a blank space then move it. + else if (mSelectedItem) + { + player_node->moveInvItem( + mSelectedItem, mHighlightedItem->getInvIndex()); + setSelectedItem(NULL); + mSelectionStatus = SEL_NONE; + } } +void ItemContainer::moveHighlight(int direction) +{ + if (!mHighlightedItem) + { + if (mSelectedItem) { + mHighlightedItem = mSelectedItem; + } + else { + mHighlightedItem = mInventory->getItem(0); + } + return; + } + + switch (direction) + { + case MOVE_SELECTED_LEFT: + if (mHighlightedItem->getInvIndex() % mGridColumns == 0) + { + mHighlightedItem += mGridColumns; + } + mHighlightedItem--; + break; + case MOVE_SELECTED_RIGHT: + if ((mHighlightedItem->getInvIndex() % mGridColumns) == + (mGridColumns - 1)) + { + mHighlightedItem -= mGridColumns; + } + mHighlightedItem++; + break; + case MOVE_SELECTED_UP: + if (mHighlightedItem->getInvIndex() / mGridColumns == 0) + { + mHighlightedItem += (mGridColumns * mGridRows); + } + mHighlightedItem -= mGridColumns; + break; + case MOVE_SELECTED_DOWN: + if ((mHighlightedItem->getInvIndex() / mGridColumns) == + (mGridRows - 1)) + { + mHighlightedItem -= (mGridColumns * mGridRows); + } + mHighlightedItem += mGridColumns; + break; + } +} diff --git a/src/gui/itemcontainer.h b/src/gui/itemcontainer.h index fba4656f..38eaba01 100644 --- a/src/gui/itemcontainer.h +++ b/src/gui/itemcontainer.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,9 +24,9 @@ #include <list> +#include <guichan/keylistener.hpp> #include <guichan/mouselistener.hpp> #include <guichan/widget.hpp> -#include <guichan/widgetlistener.hpp> class Image; class Inventory; @@ -44,14 +43,19 @@ namespace gcn { * \ingroup GUI */ class ItemContainer : public gcn::Widget, - public gcn::MouseListener, - public gcn::WidgetListener + public gcn::KeyListener, + public gcn::MouseListener { public: /** * Constructor. Initializes the graphic. + * @param inventory + * @param gridColumns Amount of columns in grid. + * @param gridRows Amount of rows in grid. + * @param offset Index offset */ - ItemContainer(Inventory *inventory, int offset); + ItemContainer(Inventory *inventory, int gridColumns, int gridRows, + int offset = 0); /** * Destructor. @@ -59,19 +63,19 @@ class ItemContainer : public gcn::Widget, virtual ~ItemContainer(); /** - * Handles the logic of the ItemContainer + * Draws the items. */ - void logic(); + void draw(gcn::Graphics *graphics); /** - * Draws the items. + * Handles the key presses. */ - void draw(gcn::Graphics *graphics); + void keyPressed(gcn::KeyEvent &event); /** - * Called whenever the widget changes size. + * Handles the key releases. */ - void widgetResized(const gcn::Event &event); + void keyReleased(gcn::KeyEvent &event); /** * Handles mouse click. @@ -79,9 +83,20 @@ class ItemContainer : public gcn::Widget, void mousePressed(gcn::MouseEvent &event); /** + * Handles mouse dragged. + */ + void mouseDragged(gcn::MouseEvent &event); + + /** + * Handles mouse released. + */ + void mouseReleased(gcn::MouseEvent &event); + + /** * Returns the selected item. */ - Item* getSelectedItem(); + Item* getSelectedItem() const + { return mSelectedItem; } /** * Sets selected item to NULL. @@ -94,7 +109,7 @@ class ItemContainer : public gcn::Widget, */ void addSelectionListener(gcn::SelectionListener *listener) { - mListeners.push_back(listener); + mSelectionListeners.push_back(listener); } /** @@ -103,33 +118,50 @@ class ItemContainer : public gcn::Widget, */ void removeSelectionListener(gcn::SelectionListener *listener) { - mListeners.remove(listener); + mSelectionListeners.remove(listener); } + enum { + MOVE_SELECTED_LEFT, // 0 + MOVE_SELECTED_RIGHT, // 1 + MOVE_SELECTED_UP, // 2 + MOVE_SELECTED_DOWN // 3 + }; private: + /** + * Execute all the functionality associated with the action key. + */ + void keyAction(); + void mouseExited(gcn::MouseEvent &event); void mouseMoved(gcn::MouseEvent &event); /** + * Moves the highlight in the direction specified. + * + * @param direction The move direction of the highlighter. + */ + void moveHighlight(int direction); - * Sets the currently selected item. Invalid (e.g., negative) indices set `no item'. + /** + * Sets the currently selected item. */ - void setSelectedItemIndex(int index); + void setSelectedItem(Item *item); /** * Find the current item index by the most recently used item ID */ - void refindSelectedItem(void); + void refindSelectedItem(); /** * Determine and set the height of the container. */ - void recalculateHeight(void); + void recalculateHeight(); /** * Sends out selection events to the list of selection listeners. */ - void distributeValueChangedEvent(void); + void distributeValueChangedEvent(); /** * Gets the slot index based on the cursor position. @@ -138,22 +170,24 @@ class ItemContainer : public gcn::Widget, * @param posY The Y Coordinate position. * @return The slot index on success, -1 on failure. */ - int getSlotIndex(const int posX, const int posY) const; + int getSlotIndex(int posX, int posY) const; Inventory *mInventory; - Image *mSelImg; - - int mSelectedItemIndex; - int mLastSelectedItemId; // last selected item ID. If we lose the item, find again by ID. - int mMaxItems; + int mGridColumns, mGridRows; int mOffset; + Image *mSelImg; + Item *mSelectedItem, *mHighlightedItem; + int mSelectionStatus; + bool mSwapItems; + bool mDescItems; + int mDragPosX, mDragPosY; ItemPopup *mItemPopup; - std::list<gcn::SelectionListener*> mListeners; + typedef std::list<gcn::SelectionListener*> SelectionListenerList; + typedef SelectionListenerList::iterator SelectionListenerIterator; - static const int gridWidth; - static const int gridHeight; + SelectionListenerList mSelectionListeners; }; #endif diff --git a/src/gui/itemlinkhandler.cpp b/src/gui/itemlinkhandler.cpp index e9993c2d..29fa310d 100644 --- a/src/gui/itemlinkhandler.cpp +++ b/src/gui/itemlinkhandler.cpp @@ -1,22 +1,21 @@ /* - * Aethyra - * Copyright 2009 The Mana World Development Team + * The Mana World + * Copyright (C) 2009 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * - * The Mana World is distributed in the hope that it will be useful, + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ diff --git a/src/gui/itemlinkhandler.h b/src/gui/itemlinkhandler.h index e4c3ea4a..c04afa9e 100644 --- a/src/gui/itemlinkhandler.h +++ b/src/gui/itemlinkhandler.h @@ -1,27 +1,26 @@ /* - * Aethyra - * Copyright 2009 The Mana World Development Team + * The Mana World + * Copyright (C) 2009 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * - * The Mana World is distributed in the hope that it will be useful, + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef ITEM_LINK_HANDLER_H_ -#define ITEM_LINK_HANDLER_H_ +#ifndef ITEM_LINK_HANDLER_H +#define ITEM_LINK_HANDLER_H #include "linkhandler.h" diff --git a/src/gui/itempopup.cpp b/src/gui/itempopup.cpp index f2ac374a..66729605 100644 --- a/src/gui/itempopup.cpp +++ b/src/gui/itempopup.cpp @@ -1,10 +1,9 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2008 The Legend of Mazzeroth Development Team * Copyright (C) 2008 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Legend of Mazzeroth. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,6 +32,8 @@ #include "../graphics.h" +#include "../units.h" + #include "../resources/iteminfo.h" #include "../utils/gettext.h" @@ -41,15 +42,13 @@ ItemPopup::ItemPopup(): Popup("ItemPopup") { - mItemType = ""; - // Item Name - mItemName = new gcn::Label(""); + mItemName = new gcn::Label; mItemName->setFont(boldFont); mItemName->setPosition(2, 2); // Item Description - mItemDesc = new TextBox(); + mItemDesc = new TextBox; mItemDesc->setEditable(false); mItemDescScroll = new ScrollArea(mItemDesc); @@ -60,7 +59,7 @@ ItemPopup::ItemPopup(): mItemDescScroll->setPosition(2, getFont()->getHeight()); // Item Effect - mItemEffect = new TextBox(); + mItemEffect = new TextBox; mItemEffect->setEditable(false); mItemEffectScroll = new ScrollArea(mItemEffect); @@ -72,7 +71,7 @@ ItemPopup::ItemPopup(): (2 * getPadding())); // Item Weight - mItemWeight = new TextBox(); + mItemWeight = new TextBox; mItemWeight->setEditable(false); mItemWeightScroll = new ScrollArea(mItemWeight); @@ -111,9 +110,11 @@ void ItemPopup::setItem(const ItemInfo &item) mItemName->setWidth(boldFont->getWidth(item.getName())); mItemDesc->setTextWrapped(item.getDescription(), 196); mItemEffect->setTextWrapped(item.getEffect(), 196); - mItemWeight->setTextWrapped(_("Weight: ") + toString(item.getWeight()) + - _(" grams"), 196); + mItemWeight->setTextWrapped(_("Weight: ") + + Units::formatWeight(item.getWeight()), 196); +#ifdef EATHENA_SUPPORT mItemType = item.getType(); +#endif int minWidth = mItemName->getWidth(); @@ -161,11 +162,13 @@ void ItemPopup::setItem(const ItemInfo &item) void ItemPopup::updateColors() { +#ifdef EATHENA_SUPPORT mItemName->setForegroundColor(getColor(mItemType)); +#endif graphics->setColor(guiPalette->getColor(Palette::TEXT)); } -gcn::Color ItemPopup::getColor(const std::string& type) +gcn::Color ItemPopup::getColor(const std::string &type) { gcn::Color color; @@ -213,9 +216,9 @@ unsigned int ItemPopup::getNumRows() void ItemPopup::view(int x, int y) { if (graphics->getWidth() < (x + getWidth() + 5)) - x = graphics->getWidth() - getWidth(); + x = graphics->getWidth() - getWidth(); if ((y - getHeight() - 10) < 0) - y = 0; + y = 0; else y = y - getHeight() - 10; setPosition(x, y); diff --git a/src/gui/itempopup.h b/src/gui/itempopup.h index 29fd127a..0e386ef7 100644 --- a/src/gui/itempopup.h +++ b/src/gui/itempopup.h @@ -1,10 +1,9 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2008 The Legend of Mazzeroth Development Team * Copyright (C) 2008 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Legend of Mazzeroth. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -78,7 +77,7 @@ class ItemPopup : public Popup ScrollArea *mItemEffectScroll; ScrollArea *mItemWeightScroll; - gcn::Color getColor(const std::string& type); + static gcn::Color getColor(const std::string &type); }; #endif // ITEMPOPUP_H diff --git a/src/gui/itemshortcutcontainer.cpp b/src/gui/itemshortcutcontainer.cpp index a0697c5d..d4de3477 100644 --- a/src/gui/itemshortcutcontainer.cpp +++ b/src/gui/itemshortcutcontainer.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2007 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,24 +19,26 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "inventorywindow.h" -#include "itemshortcutcontainer.h" -#include "itempopup.h" -#include "palette.h" -#include "viewport.h" +#include "gui/itemshortcutcontainer.h" -#include "../configuration.h" -#include "../graphics.h" -#include "../inventory.h" -#include "../item.h" -#include "../itemshortcut.h" -#include "../keyboardconfig.h" -#include "../localplayer.h" +#include "gui/inventorywindow.h" +#include "gui/itempopup.h" +#include "gui/palette.h" +#include "gui/viewport.h" -#include "../resources/image.h" -#include "../resources/resourcemanager.h" +#include "configuration.h" +#include "graphics.h" +#include "inventory.h" +#include "item.h" +#include "itemshortcut.h" +#include "keyboardconfig.h" +#include "localplayer.h" -#include "../utils/stringutils.h" +#include "resources/image.h" +#include "resources/iteminfo.h" +#include "resources/resourcemanager.h" + +#include "utils/stringutils.h" ItemShortcutContainer::ItemShortcutContainer(): ShortcutContainer(), @@ -47,7 +48,7 @@ ItemShortcutContainer::ItemShortcutContainer(): addMouseListener(this); addWidgetListener(this); - mItemPopup = new ItemPopup(); + mItemPopup = new ItemPopup; mItemPopup->setOpaque(false); ResourceManager *resman = ResourceManager::getInstance(); @@ -109,7 +110,10 @@ void ItemShortcutContainer::draw(gcn::Graphics *graphics) if (image) { const std::string label = - item->isEquipped() ? "Eq." : toString(item->getQuantity()); +#ifdef EATHENA_SUPPORT + item->isEquipped() ? "Eq." : +#endif + toString(item->getQuantity()); g->drawImage(image, itemX, itemY); g->drawText(label, itemX + mBoxWidth / 2, itemY + mBoxHeight - 14, gcn::Graphics::CENTER); @@ -233,7 +237,7 @@ void ItemShortcutContainer::mouseMoved(gcn::MouseEvent &event) Item *item = player_node->getInventory()->findItem(itemId); - if (item) + if (item && inventoryWindow->isVisible()) { if (item->getInfo().getName() != mItemPopup->getItemName()) mItemPopup->setItem(item->getInfo()); diff --git a/src/gui/itemshortcutcontainer.h b/src/gui/itemshortcutcontainer.h index 0149754e..9d188bf0 100644 --- a/src/gui/itemshortcutcontainer.h +++ b/src/gui/itemshortcutcontainer.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2007 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/itemshortcutwindow.cpp b/src/gui/itemshortcutwindow.cpp new file mode 100644 index 00000000..6fe1a10b --- /dev/null +++ b/src/gui/itemshortcutwindow.cpp @@ -0,0 +1,71 @@ +/* + * The Mana World + * Copyright (C) 2007 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "itemshortcutwindow.h" + +#include "itemshortcutcontainer.h" +#include "scrollarea.h" + +static const int SCROLL_PADDING = 0; + +ItemShortcutWindow::ItemShortcutWindow() +{ + setWindowName("ItemShortcut"); + // no title presented, title bar is padding so window can be moved. + gcn::Window::setTitleBarHeight(gcn::Window::getPadding()); + setShowTitle(false); + setResizable(true); + setDefaultSize(758, 174, 42, 426); + + mItems = new ItemShortcutContainer; + + const int border = SCROLL_PADDING * 2 + getPadding() * 2; + setMinWidth(mItems->getBoxWidth() + border); + setMinHeight(mItems->getBoxHeight() + border); + setMaxWidth(mItems->getBoxWidth() * mItems->getMaxItems() + border); + setMaxHeight(mItems->getBoxHeight() * mItems->getMaxItems() + border); + + mScrollArea = new ScrollArea(mItems); + mScrollArea->setPosition(SCROLL_PADDING, SCROLL_PADDING); + mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mScrollArea->setOpaque(false); + + add(mScrollArea); + + loadWindowState(); +} + +ItemShortcutWindow::~ItemShortcutWindow() +{ + delete mItems; + delete mScrollArea; +} + +void ItemShortcutWindow::widgetResized(const gcn::Event &event) +{ + Window::widgetResized(event); + + const gcn::Rectangle &area = getChildrenArea(); + + mScrollArea->setSize( + area.width - SCROLL_PADDING, + area.height - SCROLL_PADDING); +} diff --git a/src/gui/itemshortcutwindow.h b/src/gui/itemshortcutwindow.h new file mode 100644 index 00000000..baa34b13 --- /dev/null +++ b/src/gui/itemshortcutwindow.h @@ -0,0 +1,61 @@ +/* + * The Mana World + * Copyright (C) 2007 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef ITEMSHORTCUTWINDOW_H +#define ITEMSHORTCUTWINDOW_H + +#include "window.h" + +class ItemShortcutContainer; +class ScrollArea; + +/** + * A window around the ItemShortcutContainer. + * + * \ingroup Interface + */ +class ItemShortcutWindow : public Window +{ + public: + /** + * Constructor. + */ + ItemShortcutWindow(); + + /** + * Destructor. + */ + ~ItemShortcutWindow(); + + /** + * Called whenever the widget changes size. + */ + void widgetResized(const gcn::Event &event); + + private: + ItemShortcutContainer *mItems; + + ScrollArea *mScrollArea; +}; + +extern ItemShortcutWindow *itemShortcutWindow; + +#endif diff --git a/src/gui/label.cpp b/src/gui/label.cpp index f3e7bd04..d2fba12b 100644 --- a/src/gui/label.cpp +++ b/src/gui/label.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (c) 2009 Aethyra Development Team * - * This file is part of Aethyra based on original code - * from GUIChan. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include "label.h" #include "palette.h" @@ -27,12 +27,12 @@ Label::Label() : { } -Label::Label(const std::string& caption) : +Label::Label(const std::string &caption) : gcn::Label(caption) { } -void Label::draw(gcn::Graphics* graphics) +void Label::draw(gcn::Graphics *graphics) { setForegroundColor(guiPalette->getColor(Palette::TEXT)); gcn::Label::draw(static_cast<gcn::Graphics*>(graphics)); diff --git a/src/gui/label.h b/src/gui/label.h index 4a9bb805..dcda8e9d 100644 --- a/src/gui/label.h +++ b/src/gui/label.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (c) 2009 Aethyra Development Team * - * This file is part of Aethyra based on original code - * from GUIChan. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -43,12 +42,12 @@ class Label : public gcn::Label * Constructor. This version of the constructor sets the label with an * inintialization string. */ - Label(const std::string& caption); + Label(const std::string &caption); /** * Draws the label. */ - void draw(gcn::Graphics* graphics); + void draw(gcn::Graphics *graphics); }; #endif diff --git a/src/gui/linkhandler.h b/src/gui/linkhandler.h index ea1b25c8..30267f87 100644 --- a/src/gui/linkhandler.h +++ b/src/gui/linkhandler.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,6 +24,8 @@ #include <string> +#include <string> + /** * A simple interface to windows that need to handle links from BrowserBox * widget. @@ -34,7 +35,7 @@ class LinkHandler public: virtual ~LinkHandler() { } - virtual void handleLink(const std::string& link) = 0; + virtual void handleLink(const std::string &link) = 0; }; #endif diff --git a/src/gui/listbox.cpp b/src/gui/listbox.cpp index 71e92eaf..7ba84ee7 100644 --- a/src/gui/listbox.cpp +++ b/src/gui/listbox.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/listbox.h b/src/gui/listbox.h index 09f00cdf..cfb58f15 100644 --- a/src/gui/listbox.h +++ b/src/gui/listbox.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/login.cpp b/src/gui/login.cpp index 7b9829fb..281a25a2 100644 --- a/src/gui/login.cpp +++ b/src/gui/login.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -50,70 +49,81 @@ LoginDialog::LoginDialog(LoginData *loginData): { gcn::Label *userLabel = new Label(_("Name:")); gcn::Label *passLabel = new Label(_("Password:")); +#ifdef EATHENA_SUPPORT gcn::Label *serverLabel = new Label(_("Server:")); gcn::Label *portLabel = new Label(_("Port:")); gcn::Label *dropdownLabel = new Label(_("Recent:")); std::vector<std::string> dfltServer; - dfltServer.push_back("www.aethyra.org"); - dfltServer.push_back("www.aethyra.org"); - dfltServer.push_back("209.168.213.109"); + dfltServer.push_back("server.themanaworld.org"); std::vector<std::string> dfltPort; - dfltPort.push_back("21001"); - dfltPort.push_back("22001"); - dfltPort.push_back("21001"); + dfltPort.push_back("6901"); mServerList = new DropDownList("MostRecent00", dfltServer, dfltPort, MAX_SERVER_LIST_SIZE); mServerListBox = new ListBox(mServerList); - mServerScrollArea = new ScrollArea(); + mServerScrollArea = new ScrollArea; +#endif mUserField = new TextField(mLoginData->username); mPassField = new PasswordField(mLoginData->password); +#ifdef EATHENA_SUPPORT mServerField = new TextField(mServerList->getServerAt(0)); mPortField = new TextField(mServerList->getPortAt(0)); mServerDropDown = new DropDown(mServerList, mServerScrollArea, mServerListBox); mServerDropDown->setOpaque(false); +#endif - mKeepCheck = new CheckBox(_("Keep"), mLoginData->remember); + mKeepCheck = new CheckBox(_("Remember Username"), mLoginData->remember); mOkButton = new Button(_("OK"), "ok", this); mCancelButton = new Button(_("Cancel"), "cancel", this); mRegisterButton = new Button(_("Register"), "register", this); mUserField->setActionEventId("ok"); mPassField->setActionEventId("ok"); +#ifdef EATHENA_SUPPORT mServerField->setActionEventId("ok"); + mPortField->setActionEventId("ok"); mServerDropDown->setActionEventId("changeSelection"); +#endif mUserField->addKeyListener(this); mPassField->addKeyListener(this); +#ifdef EATHENA_SUPPORT mServerField->addKeyListener(this); mPortField->addKeyListener(this); mServerDropDown->addKeyListener(this); +#endif mUserField->addActionListener(this); mPassField->addActionListener(this); +#ifdef EATHENA_SUPPORT mServerField->addActionListener(this); mPortField->addActionListener(this); mServerDropDown->addActionListener(this); mKeepCheck->addActionListener(this); +#endif place(0, 0, userLabel); place(0, 1, passLabel); +#ifdef EATHENA_SUPPORT place(0, 2, serverLabel); place(0, 3, portLabel); place(0, 4, dropdownLabel); +#endif place(1, 0, mUserField, 3).setPadding(1); place(1, 1, mPassField, 3).setPadding(1); +#ifdef EATHENA_SUPPORT place(1, 2, mServerField, 3).setPadding(1); place(1, 3, mPortField, 3).setPadding(1); place(1, 4, mServerDropDown, 3).setPadding(1); +#endif place(0, 5, mKeepCheck, 4); place(0, 6, mRegisterButton).setHAlign(LayoutCell::LEFT); place(2, 6, mCancelButton); place(3, 6, mOkButton); reflowLayout(250, 0); - setLocationRelativeTo(getParent()); + center(); setVisible(true); if (mUserField->getText().empty()) @@ -128,8 +138,10 @@ void LoginDialog::action(const gcn::ActionEvent &event) { if (event.getId() == "ok" && canSubmit()) { +#ifdef EATHENA_SUPPORT mLoginData->hostname = mServerField->getText(); mLoginData->port = getUShort(mPortField->getText()); +#endif mLoginData->username = mUserField->getText(); mLoginData->password = mPassField->getText(); mLoginData->remember = mKeepCheck->isSelected(); @@ -137,21 +149,32 @@ void LoginDialog::action(const gcn::ActionEvent &event) mOkButton->setEnabled(false); mRegisterButton->setEnabled(false); +#ifdef EATHENA_SUPPORT mServerList->save(mServerField->getText(), mPortField->getText()); - state = ACCOUNT_STATE; + state = STATE_ACCOUNT; +#else + state = STATE_LOGIN_ATTEMPT; +#endif } +#ifdef EATHENA_SUPPORT else if (event.getId() == "changeSelection") { int selected = mServerListBox->getSelected(); mServerField->setText(mServerList->getServerAt(selected)); mPortField->setText(mServerList->getPortAt(selected)); } +#endif else if (event.getId() == "cancel") { - state = EXIT_STATE; +#ifdef TMWSERV_SUPPORT + state = STATE_SWITCH_ACCOUNTSERVER; +#else + state = STATE_EXIT; +#endif } else if (event.getId() == "register") { +#ifdef EATHENA_SUPPORT // Transfer these fields on to the register dialog mLoginData->hostname = mServerField->getText(); @@ -159,11 +182,12 @@ void LoginDialog::action(const gcn::ActionEvent &event) mLoginData->port = getUShort(mPortField->getText()); else mLoginData->port = 6901; +#endif mLoginData->username = mUserField->getText(); mLoginData->password = mPassField->getText(); - state = REGISTER_STATE; + state = STATE_REGISTER; } } @@ -176,11 +200,14 @@ bool LoginDialog::canSubmit() { return !mUserField->getText().empty() && !mPassField->getText().empty() && +#ifdef EATHENA_SUPPORT !mServerField->getText().empty() && isUShort(mPortField->getText()) && - state == LOGIN_STATE; +#endif + state == STATE_LOGIN; } +#ifdef EATHENA_SUPPORT bool LoginDialog::isUShort(const std::string &str) { if (str.empty()) @@ -305,3 +332,4 @@ std::string LoginDialog::DropDownList::getPortAt(int i) return mPorts.at(i); } +#endif diff --git a/src/gui/login.h b/src/gui/login.h index 4d63ec63..9a97cd4d 100644 --- a/src/gui/login.h +++ b/src/gui/login.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,13 +27,17 @@ #include <guichan/actionlistener.hpp> #include <guichan/keylistener.hpp> +#ifdef EATHENA_SUPPORT #include <guichan/listmodel.hpp> +#endif #include "window.h" -class DropDown; class LoginData; +#ifdef EATHENA_SUPPORT +class DropDown; class ScrollArea; +#endif /** * The login dialog. @@ -69,6 +72,7 @@ class LoginDialog : public Window, public gcn::ActionListener, */ bool canSubmit(); +#ifdef EATHENA_SUPPORT /** * Function to decide whether string is an unsigned short or not * @@ -87,11 +91,14 @@ class LoginDialog : public Window, public gcn::ActionListener, */ static unsigned short getUShort(const std::string &str); - DropDown *mServerDropDown; +#endif gcn::TextField *mUserField; gcn::TextField *mPassField; +#ifdef EATHENA_SUPPORT gcn::TextField *mServerField; gcn::TextField *mPortField; + DropDown *mServerDropDown; +#endif gcn::CheckBox *mKeepCheck; gcn::Button *mOkButton; gcn::Button *mCancelButton; @@ -99,6 +106,7 @@ class LoginDialog : public Window, public gcn::ActionListener, LoginData *mLoginData; +#ifdef EATHENA_SUPPORT /** * Helper class to keep a list of all the recent entries for the * dropdown @@ -126,6 +134,7 @@ class LoginDialog : public Window, public gcn::ActionListener, DropDownList *mServerList; gcn::ListBox *mServerListBox; gcn::ScrollArea *mServerScrollArea; +#endif }; #endif diff --git a/src/gui/magic.cpp b/src/gui/magic.cpp new file mode 100644 index 00000000..117c1f14 --- /dev/null +++ b/src/gui/magic.cpp @@ -0,0 +1,92 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <guichan/widgets/label.hpp> +#include <guichan/widgets/container.hpp> + +#include "magic.h" + +#include "button.h" + +#include "../localplayer.h" + +#include "../utils/dtor.h" +#include "../utils/gettext.h" + +MagicDialog::MagicDialog(): + Window(_("Magic")) +{ + setWindowName("Magic"); + setCloseButton(true); + setDefaultSize(255, 30, 175, 225); + + gcn::Button *spellButton1 = new Button(_("Cast Test Spell 1"), "spell_1", this); + gcn::Button *spellButton2 = new Button(_("Cast Test Spell 2"), "spell_2", this); + gcn::Button *spellButton3 = new Button(_("Cast Test Spell 3"), "spell_3", this); + + spellButton1->setPosition(10, 30); + spellButton2->setPosition(10, 60); + spellButton3->setPosition(10, 90); + + add(spellButton1); + add(spellButton2); + add(spellButton3); + + update(); + + setLocationRelativeTo(getParent()); + loadWindowState(); +} + +MagicDialog::~MagicDialog() +{ +} + +void MagicDialog::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "spell_1") + { + player_node->useSpecial(1); + } + if (event.getId() == "spell_2") + { + player_node->useSpecial(2); + } + if (event.getId() == "spell_3") + { + player_node->useSpecial(3); + } + else if (event.getId() == "close") + { + setVisible(false); + } +} + +void MagicDialog::draw(gcn::Graphics *g) +{ + update(); + + Window::draw(g); +} + +void MagicDialog::update() +{ +} diff --git a/src/gui/magic.h b/src/gui/magic.h new file mode 100644 index 00000000..74529396 --- /dev/null +++ b/src/gui/magic.h @@ -0,0 +1,75 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MAGIC_H +#define MAGIC_H + +#include <guichan/actionlistener.hpp> + +#include "window.h" +#include "gccontainer.h" + +#include "../guichanfwd.h" + + +/** + * The skill dialog. + * + * \ingroup Interface + */ +class MagicDialog : public Window, public gcn::ActionListener +{ + public: + /** + * Constructor. + */ + MagicDialog(); + + /** + * Destructor. + */ + ~MagicDialog(); + + /** + * Called when receiving actions from widget. + */ + void action(const gcn::ActionEvent &event); + + /** + * Update the tabs in this dialog + */ + void update(); + + /** + * Draw this window. + */ + void draw(gcn::Graphics *g); + + private: + +}; + + + + +extern MagicDialog *magicDialog; + +#endif diff --git a/src/gui/menuwindow.cpp b/src/gui/menuwindow.cpp index e1be908b..e6ae2d3b 100644 --- a/src/gui/menuwindow.cpp +++ b/src/gui/menuwindow.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,6 +39,11 @@ extern Window *emoteWindow; extern Window *setupWindow; extern Window *skillDialog; extern Window *statusWindow; +#ifdef TMWSERV_SUPPORT +extern Window *buddyWindow; +extern Window *guildWindow; +extern Window *magicDialog; +#endif namespace { struct MenuWindowListener : public gcn::ActionListener @@ -57,14 +61,19 @@ MenuWindow::MenuWindow(): // Buttons static const char *buttonNames[] = { - _("Chat"), - _("Status"), - _("Equipment"), - _("Inventory"), - _("Skills"), - _("Shortcut"), - _("Emote"), - _("Setup"), + N_("Chat"), + N_("Status"), + N_("Equipment"), + N_("Inventory"), + N_("Skills"), +#ifdef TMWSERV_SUPPORT + N_("Magic"), + N_("Guilds"), + N_("Buddys"), +#endif + N_("Shortcut"), + N_("Emote"), + N_("Setup"), 0 }; int x = 0, h = 0; @@ -91,35 +100,49 @@ void MenuWindowListener::action(const gcn::ActionEvent &event) { Window *window = NULL; - if (event.getId() == _("Chat")) + if (event.getId() == "Chat") { window = chatWindow; } - else if (event.getId() == _("Status")) + else if (event.getId() == "Status") { window = statusWindow; } - else if (event.getId() == _("Equipment")) + else if (event.getId() == "Equipment") { window = equipmentWindow; } - else if (event.getId() == _("Inventory")) + else if (event.getId() == "Inventory") { window = inventoryWindow; } - else if (event.getId() == _("Skills")) + else if (event.getId() == "Skills") { window = skillDialog; } - else if (event.getId() == _("Shortcut")) +#ifdef TMWSERV_SUPPORT + else if (event.getId() == "Magic") + { + window = magicDialog; + } + else if (event.getId() == "Guilds") + { + window = guildWindow; + } + else if (event.getId() == "Buddys") + { + window = buddyWindow; + } +#endif + else if (event.getId() == "Shortcut") { window = itemShortcutWindow; } - else if (event.getId() == _("Emote")) + else if (event.getId() == "Emote") { window = emoteWindow; } - else if (event.getId() == _("Setup")) + else if (event.getId() == "Setup") { window = setupWindow; } diff --git a/src/gui/menuwindow.h b/src/gui/menuwindow.h index e8dc0b2e..c3d5673e 100644 --- a/src/gui/menuwindow.h +++ b/src/gui/menuwindow.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp index f3da52c6..93a55688 100644 --- a/src/gui/minimap.cpp +++ b/src/gui/minimap.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004-2005 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,7 +40,7 @@ Minimap::Minimap(): mMapImage(NULL), mProportion(0.5) { - setWindowName(_("MiniMap")); + setWindowName("MiniMap"); mShow = config.getValue(getWindowName() + "Show", true); setDefaultSize(5, 25, 100, 100); setResizable(true); @@ -120,8 +119,14 @@ void Minimap::draw(gcn::Graphics *graphics) if (mMapImage->getWidth() > a.width || mMapImage->getHeight() > a.height) { +#ifdef TMWSERV_SUPPORT + const Vector &p = player_node->getPosition(); + mapOriginX = (int) (((a.width) / 2) - (int) (p.x * mProportion) / 32); + mapOriginY = (int) (((a.height) / 2) - (int) (p.y * mProportion) / 32); +#else mapOriginX = (int) (((a.width) / 2) - (player_node->mX * mProportion)); mapOriginY = (int) (((a.height) / 2) - (player_node->mY * mProportion)); +#endif const int minOriginX = a.width - mMapImage->getWidth(); const int minOriginY = a.height - mMapImage->getHeight(); @@ -172,10 +177,11 @@ void Minimap::draw(gcn::Graphics *graphics) } const int offset = (int) ((dotSize - 1) * mProportion); + const Vector &pos = being->getPosition(); graphics->fillRectangle(gcn::Rectangle( - (int) (being->mX * mProportion) + mapOriginX - offset, - (int) (being->mY * mProportion) + mapOriginY - offset, + (int) (pos.x * mProportion) / 32 + mapOriginX - offset, + (int) (pos.x * mProportion) / 32 + mapOriginY - offset, dotSize, dotSize)); } diff --git a/src/gui/minimap.h b/src/gui/minimap.h index 6e88f821..3ce0aacd 100644 --- a/src/gui/minimap.h +++ b/src/gui/minimap.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004-2005 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/ministatus.cpp b/src/gui/ministatus.cpp index 18b9d714..95577e69 100644 --- a/src/gui/ministatus.cpp +++ b/src/gui/ministatus.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,7 +22,9 @@ #include "gui.h" #include "ministatus.h" #include "progressbar.h" +#include "status.h" +#include "../animatedsprite.h" #include "../configuration.h" #include "../graphics.h" #include "../localplayer.h" @@ -34,47 +35,56 @@ MiniStatusWindow::MiniStatusWindow(): Popup("MiniStatus") { mHpBar = new ProgressBar(1.0f, 100, 20, 0, 171, 34); +#ifdef EATHENA_SUPPORT mMpBar = new ProgressBar(1.0f, 100, 20, 26, 102, 230); mXpBar = new ProgressBar(1.0f, 100, 20, 143, 192, 211); +#endif mHpBar->setPosition(0, 3); +#ifdef EATHENA_SUPPORT mMpBar->setPosition(mHpBar->getWidth() + 3, 3); mXpBar->setPosition(mMpBar->getX() + mMpBar->getWidth() + 3, 3); +#endif add(mHpBar); +#ifdef EATHENA_SUPPORT add(mMpBar); add(mXpBar); +#endif +#ifdef EATHENA_SUPPORT setContentSize(mXpBar->getX() + mXpBar->getWidth(), mXpBar->getY() + mXpBar->getHeight()); +#else + setContentSize(mHpBar->getX() + mHpBar->getWidth(), + mHpBar->getY() + mHpBar->getHeight()); +#endif } -void MiniStatusWindow::update() +void MiniStatusWindow::setIcon(int index, AnimatedSprite *sprite) { - // HP Bar coloration - if (player_node->mHp < int(player_node->mMaxHp / 3)) - mHpBar->setColor(223, 32, 32); // Red - else if (player_node->mHp < int((player_node->mMaxHp / 3) * 2)) - mHpBar->setColor(230, 171, 34); // Orange - else - mHpBar->setColor(0, 171, 34); // Green + if (index >= (int) mIcons.size()) + mIcons.resize(index + 1, NULL); - float xp = (float) player_node->getXp() / player_node->mXpForNextLevel; + if (mIcons[index]) + delete mIcons[index]; - if (xp != xp) xp = 0.0f; // check for NaN - if (xp < 0.0f) xp = 0.0f; // make sure the experience isn't negative (uninitialized pointer most likely) - if (xp > 1.0f) xp = 1.0f; + mIcons[index] = sprite; +} - mHpBar->setProgress((float) player_node->mHp / player_node->mMaxHp); - mMpBar->setProgress((float) player_node->mMp / player_node->mMaxMp); - mXpBar->setProgress(xp); +void MiniStatusWindow::eraseIcon(int index) +{ + mIcons.erase(mIcons.begin() + index); +} - // Update labels - mHpBar->setText(toString(player_node->mHp)); - mMpBar->setText(toString(player_node->mMp)); +extern volatile int tick_time; - std::stringstream updatedText; - updatedText << (float) ((int) (xp * 10000.0f)) / 100.0f << "%"; +void MiniStatusWindow::update() +{ + StatusWindow::updateHPBar(mHpBar); +#ifdef EATHENA_SUPPORT + StatusWindow::updateMPBar(mMpBar); + StatusWindow::updateXPBar(mXpBar); // Displays the number of monsters to next lvl // (disabled for now but interesting idea) @@ -88,8 +98,11 @@ void MiniStatusWindow::update() << config.getValue("xpBarMonsterCounterName", "Monsters") <<" left..."; } */ +#endif - mXpBar->setText(updatedText.str()); + for (unsigned int i = 0; i < mIcons.size(); i++) + if (mIcons[i]) + mIcons[i]->update(tick_time * 10); } void MiniStatusWindow::draw(gcn::Graphics *graphics) @@ -97,3 +110,19 @@ void MiniStatusWindow::draw(gcn::Graphics *graphics) update(); drawChildren(graphics); } + +void MiniStatusWindow::drawIcons(Graphics *graphics) +{ + // Draw icons +#ifdef TMWSERV_SUPPORT + int icon_x = mHpBar->getX() + mHpBar->getWidth() + 4; +#else + int icon_x = mXpBar->getX() + mXpBar->getWidth() + 4; +#endif + for (unsigned int i = 0; i < mIcons.size(); i++) { + if (mIcons[i]) { + mIcons[i]->draw(graphics, icon_x, 3); + icon_x += 2 + mIcons[i]->getWidth(); + } + } +} diff --git a/src/gui/ministatus.h b/src/gui/ministatus.h index b3fc58fc..fd5a4e53 100644 --- a/src/gui/ministatus.h +++ b/src/gui/ministatus.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,6 +24,10 @@ #include "popup.h" +#include <vector> + +class AnimatedSprite; +class Graphics; class ProgressBar; /** @@ -45,6 +48,15 @@ class MiniStatusWindow : public Popup */ void draw(gcn::Graphics *graphics); + /** + * Sets one of the icons. + */ + void setIcon(int index, AnimatedSprite *sprite); + + void eraseIcon(int index); + + void drawIcons(Graphics *graphics); + private: /** * Updates this dialog with values from player_node. @@ -55,8 +67,12 @@ class MiniStatusWindow : public Popup * Mini Status Bars */ ProgressBar *mHpBar; +#ifdef EATHENA_SUPPORT ProgressBar *mMpBar; ProgressBar *mXpBar; +#endif + + std::vector<AnimatedSprite *> mIcons; }; #endif diff --git a/src/gui/npc_text.cpp b/src/gui/npc_text.cpp index f524f8ea..5158e966 100644 --- a/src/gui/npc_text.cpp +++ b/src/gui/npc_text.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,14 +29,26 @@ #include "../npc.h" #include "../net/messageout.h" -#include "../net/protocol.h" +#ifdef TMWSERV_SUPPORT +#include "../net/tmwserv/gameserver/player.h" +#else +#include "../net/ea/protocol.h" +#endif #include "../utils/gettext.h" -NpcTextDialog::NpcTextDialog(Network *network): - Window("NPC"), mNetwork(network) +#ifdef TMWSERV_SUPPORT +NpcTextDialog::NpcTextDialog() +#else +NpcTextDialog::NpcTextDialog(Network *network) +#endif + : Window(_("NPC")) +#ifdef EATHENA_SUPPORT + , mNetwork(network) +#endif + , mState(NPC_TEXT_STATE_WAITING) { - setWindowName(_("NPC")); + setWindowName("NPCText"); setResizable(true); setMinWidth(200); @@ -50,8 +61,7 @@ NpcTextDialog::NpcTextDialog(Network *network): mTextBox->setOpaque(false); mScrollArea = new ScrollArea(mTextBox); - mButton = new Button(_("OK"), "", this); - mButton->setActionEventId("ok"); + mButton = new Button(_("Waiting for server"), "ok", this); mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); mScrollArea->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS); @@ -62,9 +72,16 @@ NpcTextDialog::NpcTextDialog(Network *network): Layout &layout = getLayout(); layout.setRowHeight(0, Layout::AUTO_SET); + center(); loadWindowState(); } +void NpcTextDialog::clearText() +{ + NPC::isTalking = false; + setText(""); +} + void NpcTextDialog::setText(const std::string &text) { mText = text; @@ -74,41 +91,64 @@ void NpcTextDialog::setText(const std::string &text) void NpcTextDialog::addText(const std::string &text) { setText(mText + text + "\n"); + mScrollArea->setVerticalScrollAmount(mScrollArea->getVerticalMaxScroll()); } -void NpcTextDialog::clearText() +void NpcTextDialog::showNextButton() { - NPC::mTalking = false; - setText(""); + mButton->setCaption(_("Next")); + mState = NPC_TEXT_STATE_NEXT; + mButton->setEnabled(true); +} + +void NpcTextDialog::showCloseButton() +{ + mButton->setCaption(_("Close")); + mState = NPC_TEXT_STATE_CLOSE; + mButton->setEnabled(true); } void NpcTextDialog::action(const gcn::ActionEvent &event) { if (event.getId() == "ok") { - clearText(); - setVisible(false); - saveWindowState(); - - if (current_npc) + if (mState == NPC_TEXT_STATE_NEXT && current_npc) { nextDialog(); - - current_npc = 0; + addText("\n> Next\n"); + } else if (mState == NPC_TEXT_STATE_CLOSE || + (mState == NPC_TEXT_STATE_NEXT && !current_npc)) { + setText(""); + if (current_npc) nextDialog(); + setVisible(false); + current_npc = 0; + NPC::isTalking = false; + } else return; } + else return; + + mButton->setEnabled(false); + mButton->setCaption(_("Waiting for server")); + mState = NPC_TEXT_STATE_WAITING; } void NpcTextDialog::nextDialog(int npcID) { +#ifdef TMWSERV_SUPPORT + Net::GameServer::Player::talkToNPC(npcID, false); +#else MessageOut outMsg(mNetwork); outMsg.writeInt16(CMSG_NPC_NEXT_REQUEST); outMsg.writeInt32(npcID); +#endif } void NpcTextDialog::closeDialog(int npcID) { +#ifdef EATHENA_SUPPORT MessageOut outMsg(mNetwork); outMsg.writeInt16(CMSG_NPC_CLOSE); outMsg.writeInt32(npcID); +#endif } void NpcTextDialog::widgetResized(const gcn::Event &event) @@ -123,4 +163,3 @@ void NpcTextDialog::requestFocus() loadWindowState(); setVisible(true); } - diff --git a/src/gui/npc_text.h b/src/gui/npc_text.h index f01e3602..4c0c31e3 100644 --- a/src/gui/npc_text.h +++ b/src/gui/npc_text.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,7 +30,9 @@ #include "../npc.h" +#ifdef EATHENA_SUPPORT class Network; +#endif class TextBox; /** @@ -47,7 +48,11 @@ class NpcTextDialog : public Window, public gcn::ActionListener * * @see Window::Window */ +#ifdef TMWSERV_SUPPORT + NpcTextDialog(); +#else NpcTextDialog(Network *network); +#endif /** * Called when receiving actions from the widgets. @@ -74,6 +79,10 @@ class NpcTextDialog : public Window, public gcn::ActionListener */ void addText(const std::string &string); + void showNextButton(); + + void showCloseButton(); + /** * Notifies the server that the client has performed a next action. */ @@ -99,12 +108,21 @@ class NpcTextDialog : public Window, public gcn::ActionListener void widgetResized(const gcn::Event &event); private: +#ifdef EATHENA_SUPPORT Network *mNetwork; +#endif gcn::ScrollArea *mScrollArea; TextBox *mTextBox; gcn::Button *mButton; std::string mText; + + enum NPCTextState { + NPC_TEXT_STATE_WAITING, + NPC_TEXT_STATE_NEXT, + NPC_TEXT_STATE_CLOSE + }; + NPCTextState mState; }; extern NpcTextDialog *npcTextDialog; diff --git a/src/gui/npcintegerdialog.cpp b/src/gui/npcintegerdialog.cpp index 27721f0c..a7ae2748 100644 --- a/src/gui/npcintegerdialog.cpp +++ b/src/gui/npcintegerdialog.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,6 +21,7 @@ #include "button.h" #include "inttextfield.h" +#include "npc_text.h" #include "npcintegerdialog.h" #include "widgets/layout.h" @@ -29,23 +29,33 @@ #include "../npc.h" #include "../net/messageout.h" -#include "../net/protocol.h" +#ifdef EATHENA_SUPPORT +#include "../net/ea/protocol.h" +#endif #include "../utils/gettext.h" - -NpcIntegerDialog::NpcIntegerDialog(Network *network): - Window(_("NPC Number Request")), mNetwork(network) +#include "../utils/strprintf.h" + +#ifdef TMWSERV_SUPPORT +NpcIntegerDialog::NpcIntegerDialog() +#else +NpcIntegerDialog::NpcIntegerDialog(Network *network) +#endif + : Window(_("NPC Number Request")) +#ifdef EATHENA_SUPPORT + , mNetwork(network) +#endif { - mValueField = new IntTextField(); - setWindowName("NPCInput"); + setWindowName("NPCInteger"); + mValueField = new IntTextField; setDefaultSize(175, 75, ImageRect::CENTER); mDecButton = new Button("-", "decvalue", this); mIncButton = new Button("+", "incvalue", this); - okButton = new Button(_("OK"), "ok", this); - cancelButton = new Button(_("Cancel"), "cancel", this); - resetButton = new Button(_("Reset"), "reset", this); + gcn::Button *okButton = new Button(_("OK"), "ok", this); + gcn::Button *cancelButton = new Button(_("Cancel"), "cancel", this); + gcn::Button *resetButton = new Button(_("Reset"), "reset", this); mDecButton->adjustSize(); mDecButton->setWidth(mIncButton->getWidth()); @@ -61,12 +71,14 @@ NpcIntegerDialog::NpcIntegerDialog(Network *network): place(0, 0, resetButton); place(2, 0, cancelButton); place(3, 0, okButton); - //reflowLayout(175, 0); + reflowLayout(175, 0); + center(); + setDefaultSize(); loadWindowState(); } -void NpcIntegerDialog::setRange(const int min, const int max) +void NpcIntegerDialog::setRange(int min, int max) { mValueField->setRange(min, max); } @@ -88,11 +100,13 @@ void NpcIntegerDialog::action(const gcn::ActionEvent &event) if (event.getId() == "ok") { finish = true; + npcTextDialog->addText(strprintf("\n> %d\n", mValueField->getValue())); } else if (event.getId() == "cancel") { finish = true; mValueField->reset(); + npcTextDialog->addText(_("\n> Cancel\n")); } else if (event.getId() == "decvalue") { @@ -110,18 +124,24 @@ void NpcIntegerDialog::action(const gcn::ActionEvent &event) if (finish) { setVisible(false); - NPC::mTalking = false; + NPC::isTalking = false; +#ifdef EATHENA_SUPPORT MessageOut outMsg(mNetwork); outMsg.writeInt16(CMSG_NPC_INT_RESPONSE); outMsg.writeInt32(current_npc); outMsg.writeInt32(mValueField->getValue()); +#endif - current_npc = 0; mValueField->reset(); } } +void NpcIntegerDialog::setDefaultValue(int value) +{ + mValueField->setDefaultValue(value); +} + bool NpcIntegerDialog::isInputFocused() { return mValueField->isFocused(); @@ -131,3 +151,13 @@ void NpcIntegerDialog::requestFocus() { mValueField->requestFocus(); } + +void NpcIntegerDialog::setVisible(bool visible) +{ + if (visible) { + npcTextDialog->setVisible(true); + requestFocus(); + } + + Window::setVisible(visible); +} diff --git a/src/gui/npcintegerdialog.h b/src/gui/npcintegerdialog.h index 15bdee48..df74c904 100644 --- a/src/gui/npcintegerdialog.h +++ b/src/gui/npcintegerdialog.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,7 +26,9 @@ #include "window.h" +#ifdef EATHENA_SUPPORT class Network; +#endif class IntTextField; /** @@ -43,7 +44,11 @@ class NpcIntegerDialog : public Window, public gcn::ActionListener * * @see Window::Window */ +#ifdef TMWSERV_SUPPORT + NpcIntegerDialog(); +#else NpcIntegerDialog(Network *network); +#endif /** * Called when receiving actions from the widgets. @@ -66,7 +71,14 @@ class NpcIntegerDialog : public Window, public gcn::ActionListener * @param min The minimum value to allow * @param max The maximum value to allow */ - void setRange(const int min, const int max); + void setRange(int min, int max); + + /** + * Sets the default value. + * + * @param value The new default value + */ + void setDefaultValue(int value); /** * Checks whether NpcStringDialog is Focused or not. @@ -78,14 +90,15 @@ class NpcIntegerDialog : public Window, public gcn::ActionListener */ void requestFocus(); + void setVisible(bool visible); + private: +#ifdef EATHENA_SUPPORT Network *mNetwork; +#endif gcn::Button *mDecButton; gcn::Button *mIncButton; IntTextField *mValueField; - gcn::Button *okButton; - gcn::Button *cancelButton; - gcn::Button *resetButton; }; extern NpcIntegerDialog *npcIntegerDialog; diff --git a/src/gui/npclistdialog.cpp b/src/gui/npclistdialog.cpp index 505912ac..968e2514 100644 --- a/src/gui/npclistdialog.cpp +++ b/src/gui/npclistdialog.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,6 +23,7 @@ #include "button.h" #include "listbox.h" +#include "npc_text.h" #include "npclistdialog.h" #include "scrollarea.h" @@ -32,14 +32,26 @@ #include "../npc.h" #include "../net/messageout.h" -#include "../net/protocol.h" +#ifdef TMWSERV_SUPPORT +#include "../net/tmwserv/gameserver/player.h" +#else +#include "../net/ea/protocol.h" +#endif #include "../utils/gettext.h" - -NpcListDialog::NpcListDialog(Network *network): - Window("NPC"), mNetwork(network) +#include "../utils/strprintf.h" + +#ifdef TMWSERV_SUPPORT +NpcListDialog::NpcListDialog() +#else +NpcListDialog::NpcListDialog(Network *network) +#endif + : Window("NPC") +#ifdef EATHENA_SUPPORT + , mNetwork(network) +#endif { - setWindowName(_("NPC")); + setWindowName("NPCList"); setResizable(true); setMinWidth(200); @@ -50,10 +62,10 @@ NpcListDialog::NpcListDialog(Network *network): mItemList = new ListBox(this); mItemList->setWrappingEnabled(true); - scrollArea = new ScrollArea(mItemList); + gcn::ScrollArea *scrollArea = new ScrollArea(mItemList); - okButton = new Button(_("OK"), "ok", this); - cancelButton = new Button(_("Cancel"), "cancel", this); + gcn::Button *okButton = new Button(_("OK"), "ok", this); + gcn::Button *cancelButton = new Button(_("Cancel"), "cancel", this); setContentSize(260, 175); scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); @@ -65,6 +77,7 @@ NpcListDialog::NpcListDialog(Network *network): Layout &layout = getLayout(); layout.setRowHeight(0, Layout::AUTO_SET); + center(); loadWindowState(); } @@ -78,6 +91,11 @@ std::string NpcListDialog::getElementAt(int i) return mItems[i]; } +void NpcListDialog::addItem(const std::string &item) +{ + mItems.push_back(item); +} + void NpcListDialog::parseItems(const std::string &itemString) { std::istringstream iss(itemString); @@ -89,7 +107,7 @@ void NpcListDialog::parseItems(const std::string &itemString) void NpcListDialog::reset() { - NPC::mTalking = false; + NPC::isTalking = false; mItemList->setSelected(-1); mItems.clear(); } @@ -97,18 +115,23 @@ void NpcListDialog::reset() void NpcListDialog::action(const gcn::ActionEvent &event) { int choice = 0; - if (event.getId() == "ok") { // Send the selected index back to the server int selectedIndex = mItemList->getSelected(); if (selectedIndex > -1) + { choice = selectedIndex + 1; + npcTextDialog->addText(strprintf("\n> \"%s\"\n", + mItems[selectedIndex].c_str())); + } } else if (event.getId() == "cancel") { choice = 0xff; // 0xff means cancel + npcTextDialog->addText(_("\n> Cancel\n")); + npcTextDialog->showCloseButton(); } if (choice) @@ -117,13 +140,25 @@ void NpcListDialog::action(const gcn::ActionEvent &event) saveWindowState(); reset(); +#ifdef TMWSERV_SUPPORT + Net::GameServer::Player::selectFromNPC(current_npc, choice); +#else MessageOut outMsg(mNetwork); outMsg.writeInt16(CMSG_NPC_LIST_CHOICE); outMsg.writeInt32(current_npc); outMsg.writeInt8(choice); +#endif + } +} - current_npc = 0; +void NpcListDialog::setVisible(bool visible) +{ + if (visible) { + npcTextDialog->setVisible(true); + requestFocus(); } + + Window::setVisible(visible); } void NpcListDialog::requestFocus() diff --git a/src/gui/npclistdialog.h b/src/gui/npclistdialog.h index e3cf375b..6c1e02e3 100644 --- a/src/gui/npclistdialog.h +++ b/src/gui/npclistdialog.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,14 +22,16 @@ #ifndef GUI_NPCLISTDIALOG_H #define GUI_NPCLISTDIALOG_H -#include <vector> +#include "window.h" #include <guichan/actionlistener.hpp> #include <guichan/listmodel.hpp> -#include "window.h" +#include <vector> +#ifdef EATHENA_SUPPORT class Network; +#endif /** * The npc list dialog. @@ -46,7 +47,11 @@ class NpcListDialog : public Window, public gcn::ActionListener, * * @see Window::Window */ +#ifdef TMWSERV_SUPPORT + NpcListDialog(); +#else NpcListDialog(Network *network); +#endif /** * Called when receiving actions from the widgets. @@ -64,6 +69,11 @@ class NpcListDialog : public Window, public gcn::ActionListener, std::string getElementAt(int i); /** + * Adds an item to the option list. + */ + void addItem(const std::string &); + + /** * Fills the options list for an NPC dialog. * * @param itemString A string with the options separated with colons. @@ -75,6 +85,8 @@ class NpcListDialog : public Window, public gcn::ActionListener, */ void reset(); + void setVisible(bool visible); + /** * Requests the listbox to take focus for input and sets window width * to the last known setting. @@ -82,11 +94,10 @@ class NpcListDialog : public Window, public gcn::ActionListener, void requestFocus(); private: +#ifdef EATHENA_SUPPORT Network *mNetwork; +#endif gcn::ListBox *mItemList; - gcn::ScrollArea *scrollArea; - gcn::Button *okButton; - gcn::Button *cancelButton; std::vector<std::string> mItems; }; diff --git a/src/gui/npcpostdialog.cpp b/src/gui/npcpostdialog.cpp new file mode 100644 index 00000000..278bc397 --- /dev/null +++ b/src/gui/npcpostdialog.cpp @@ -0,0 +1,101 @@ +/* + * The Mana World + * Copyright (C) 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "npcpostdialog.h" +#include "textbox.h" +#include "textfield.h" +#include "button.h" +#include "scrollarea.h" +#include "chat.h" + +#include "../net/tmwserv/gameserver/player.h" +#include "../utils/gettext.h" + +#include <guichan/widgets/label.hpp> + +NpcPostDialog::NpcPostDialog(): + Window(_("NPC")) +{ + setContentSize(400, 180); + + // create text field for receiver + gcn::Label *senderText = new gcn::Label("To:"); + senderText->setPosition(5, 5); + mSender = new TextField(); + mSender->setPosition(senderText->getWidth() + 5, 5); + mSender->setWidth(65); + + // create button for sending + Button *sendButton = new Button(_("Send"), "send", this); + sendButton->setPosition(400-sendButton->getWidth(), + 170-sendButton->getHeight()); + Button *cancelButton = new Button(_("Cancel"), "cancel", this); + cancelButton->setPosition(sendButton->getX() - (cancelButton->getWidth() + 2), + sendButton->getY()); + + // create textfield for letter + mText = new TextBox(); + mText->setHeight(400 - (mSender->getHeight() + sendButton->getHeight())); + mText->setEditable(true); + + // create scroll box for letter text + ScrollArea *scrollArea = new ScrollArea(mText); + scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + scrollArea->setDimension(gcn::Rectangle( + 5, mSender->getHeight() + 5, + 380, 140 - (mSender->getHeight() + sendButton->getHeight()))); + + add(senderText); + add(mSender); + add(scrollArea); + add(sendButton); + add(cancelButton); + + setLocationRelativeTo(getParent()); +} + +void NpcPostDialog::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "send") + { + if (mSender->getText().empty() || mText->getText().empty()) + { + localChatTab->chatLog("Failed to send as sender or letter invalid"); + } + else + { + Net::GameServer::Player::sendLetter(mSender->getText(), mText->getText()); + } + setVisible(false); + clear(); + } + else if (event.getId() == "cancel") + { + setVisible(false); + clear(); + } +} + +void NpcPostDialog::clear() +{ + mSender->setText(""); + mText->setText(""); +} diff --git a/src/gui/npcpostdialog.h b/src/gui/npcpostdialog.h new file mode 100644 index 00000000..b970f5cf --- /dev/null +++ b/src/gui/npcpostdialog.h @@ -0,0 +1,57 @@ +/* + * The Mana World + * Copyright (C) 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef GUI_NPCPOSTDIALOG_H +#define GUI_NPCPOSTDIALOG_H + +#include <guichan/actionlistener.hpp> + +#include "window.h" + +class TextBox; +class TextField; + +class NpcPostDialog : public Window, public gcn::ActionListener +{ +public: + /** + * Constructor + */ + NpcPostDialog(); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + /** + * Clear the contents of the dialog + */ + void clear(); + +private: + TextBox *mText; + TextField *mSender; +}; + +extern NpcPostDialog *npcPostDialog; + +#endif diff --git a/src/gui/npcstringdialog.cpp b/src/gui/npcstringdialog.cpp index 43d0722f..c84de015 100644 --- a/src/gui/npcstringdialog.cpp +++ b/src/gui/npcstringdialog.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +20,7 @@ */ #include "button.h" +#include "npc_text.h" #include "npcstringdialog.h" #include "textfield.h" @@ -29,25 +29,38 @@ #include "../npc.h" #include "../net/messageout.h" -#include "../net/protocol.h" +#ifdef EATHENA_SUPPORT +#include "../net/ea/protocol.h" +#endif #include "../utils/gettext.h" - -NpcStringDialog::NpcStringDialog(Network *network): - Window(_("NPC Text Request")), mNetwork(network) +#include "../utils/strprintf.h" + +#ifdef TMWSERV_SUPPORT +NpcStringDialog::NpcStringDialog() +#else +NpcStringDialog::NpcStringDialog(Network *network) +#endif + : Window(_("NPC Text Request")) +#ifdef EATHENA_SUPPORT + , mNetwork(network) +#endif { - setWindowName("NPCInput"); + setWindowName("NPCString"); mValueField = new TextField(""); setDefaultSize(175, 75, ImageRect::CENTER); - okButton = new Button(_("OK"), "ok", this); - cancelButton = new Button(_("Cancel"), "cancel", this); + gcn::Button *okButton = new Button(_("OK"), "ok", this); + gcn::Button *cancelButton = new Button(_("Cancel"), "cancel", this); place(0, 0, mValueField, 3); place(1, 1, cancelButton); place(2, 1, okButton); + reflowLayout(175, 0); + center(); + setDefaultSize(); loadWindowState(); } @@ -59,27 +72,36 @@ std::string NpcStringDialog::getValue() void NpcStringDialog::setValue(const std::string &value) { mValueField->setText(value); + mDefault = value; } void NpcStringDialog::action(const gcn::ActionEvent &event) { if (event.getId() == "cancel") - mValueField->setText(""); + { + mValueField->setText(mDefault); + npcTextDialog->addText(_("\n> Cancel\n")); + } + else + { + npcTextDialog->addText(strprintf("\n> \"%s\"\n", + mValueField->getText().c_str())); + } setVisible(false); - NPC::mTalking = false; + NPC::isTalking = false; std::string text = mValueField->getText(); mValueField->setText(""); +#ifdef EATHENA_SUPPORT MessageOut outMsg(mNetwork); outMsg.writeInt16(CMSG_NPC_STR_RESPONSE); outMsg.writeInt16(text.length() + 9); outMsg.writeInt32(current_npc); outMsg.writeString(text, text.length()); outMsg.writeInt8(0); - - current_npc = 0; +#endif } bool NpcStringDialog::isInputFocused() @@ -91,3 +113,13 @@ void NpcStringDialog::requestFocus() { mValueField->requestFocus(); } + +void NpcStringDialog::setVisible(bool visible) +{ + if (visible) { + npcTextDialog->setVisible(true); + requestFocus(); + } + + Window::setVisible(visible); +} diff --git a/src/gui/npcstringdialog.h b/src/gui/npcstringdialog.h index ee620daf..94cd59b2 100644 --- a/src/gui/npcstringdialog.h +++ b/src/gui/npcstringdialog.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,11 +22,13 @@ #ifndef GUI_NPCSTRINGDIALOG_H #define GUI_NPCSTRINGDIALOG_H -#include <guichan/actionlistener.hpp> - #include "window.h" +#include <guichan/actionlistener.hpp> + +#ifdef EATHENA_SUPPORT class Network; +#endif /** * The npc integer input dialog. @@ -42,7 +43,11 @@ class NpcStringDialog : public Window, public gcn::ActionListener * * @see Window::Window */ +#ifdef TMWSERV_SUPPORT + NpcStringDialog(); +#else NpcStringDialog(Network *network); +#endif /** * Called when receiving actions from the widgets. @@ -71,11 +76,14 @@ class NpcStringDialog : public Window, public gcn::ActionListener */ void requestFocus(); + void setVisible(bool visible); + private: +#ifdef EATHENA_SUPPORT Network *mNetwork; +#endif gcn::TextField *mValueField; - gcn::Button *okButton; - gcn::Button *cancelButton; + std::string mDefault; }; extern NpcStringDialog *npcStringDialog; diff --git a/src/gui/ok_dialog.cpp b/src/gui/ok_dialog.cpp index 84fa20ea..24ffa80c 100644 --- a/src/gui/ok_dialog.cpp +++ b/src/gui/ok_dialog.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,12 +33,12 @@ OkDialog::OkDialog(const std::string &title, const std::string &msg, Window *parent): Window(title, true, parent) { - mTextBox = new TextBox(); + mTextBox = new TextBox; mTextBox->setEditable(false); mTextBox->setOpaque(false); mTextArea = new ScrollArea(mTextBox); - okButton = new Button(_("Ok"), "ok", this); + gcn::Button *okButton = new Button(_("Ok"), "ok", this); mTextArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); mTextArea->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); @@ -69,7 +68,7 @@ OkDialog::OkDialog(const std::string &title, const std::string &msg, add(mTextArea); add(okButton); - setLocationRelativeTo(getParent()); + center(); setVisible(true); okButton->requestFocus(); } diff --git a/src/gui/ok_dialog.h b/src/gui/ok_dialog.h index 6cfe0798..46dd4db0 100644 --- a/src/gui/ok_dialog.h +++ b/src/gui/ok_dialog.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,13 +19,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _OK_DIALOG_H -#define _OK_DIALOG_H - -#include <guichan/actionlistener.hpp> +#ifndef OK_DIALOG_H +#define OK_DIALOG_H #include "window.h" +#include <guichan/actionlistener.hpp> + class ScrollArea; class TextBox; @@ -56,7 +55,6 @@ class OkDialog : public Window, public gcn::ActionListener private: TextBox *mTextBox; ScrollArea *mTextArea; - gcn::Button *okButton; }; #endif diff --git a/src/gui/palette.cpp b/src/gui/palette.cpp index 2efc60be..b176fcff 100644 --- a/src/gui/palette.cpp +++ b/src/gui/palette.cpp @@ -3,7 +3,7 @@ * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> * Copyright (C) 2009 The Mana World Development Team * - * This file is part of Aethyra. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -76,8 +76,7 @@ const int Palette::GRADIENT_DELAY = 40; Palette::Palette() : mRainbowTime(tick_time), - mColVector(ColVector(TYPE_COUNT)), - mGradVector() + mColVector(ColVector(TYPE_COUNT)) { std::string indent = " "; addColor(TEXT, 0x000000, STATIC, _("Text")); @@ -346,4 +345,3 @@ void Palette::advanceGradient () mRainbowTime = tick_time; } } - diff --git a/src/gui/palette.h b/src/gui/palette.h index e894ba74..b2994351 100644 --- a/src/gui/palette.h +++ b/src/gui/palette.h @@ -3,7 +3,7 @@ * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> * Copyright (C) 2009 The Mana World Development Team * - * This file is part of Aethyra. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -124,7 +124,7 @@ class Palette : public gcn::ListModel * * @return the requested color or Palette::BLACK */ - const gcn::Color& getColor(char c, bool &valid); + const gcn::Color &getColor(char c, bool &valid); /** * Gets the color associated with the type. Sets the alpha channel @@ -135,7 +135,7 @@ class Palette : public gcn::ListModel * * @return the requested color */ - inline const gcn::Color& getColor(ColorType type, int alpha = 255) + inline const gcn::Color &getColor(ColorType type, int alpha = 255) { gcn::Color* col = &mColVector[type].color; col->a = alpha; @@ -149,8 +149,10 @@ class Palette : public gcn::ListModel * * @return the requested committed color */ - inline const gcn::Color& getCommittedColor(ColorType type) - { return mColVector[type].committedColor; } + inline const gcn::Color &getCommittedColor(ColorType type) + { + return mColVector[type].committedColor; + } /** * Gets the test color associated with the specified type. @@ -159,8 +161,10 @@ class Palette : public gcn::ListModel * * @return the requested test color */ - inline const gcn::Color& getTestColor(ColorType type) - { return mColVector[type].testColor; } + inline const gcn::Color &getTestColor(ColorType type) + { + return mColVector[type].testColor; + } /** * Sets the test color associated with the specified type. @@ -169,7 +173,9 @@ class Palette : public gcn::ListModel * @param color the color that should be tested */ inline void setTestColor(ColorType type, gcn::Color color) - { mColVector[type].testColor = color; } + { + mColVector[type].testColor = color; + } /** * Gets the GradientType associated with the specified type. @@ -179,7 +185,9 @@ class Palette : public gcn::ListModel * @return the gradient type of the color with the given index */ inline GradientType getGradientType(ColorType type) - { return mColVector[type].grad; } + { + return mColVector[type].grad; + } /** * Get the character used by the specified color. @@ -188,7 +196,10 @@ class Palette : public gcn::ListModel * * @return the color char of the color with the given index */ - inline char getColorChar(ColorType type) { return mColVector[type].ch; } + inline char getColorChar(ColorType type) + { + return mColVector[type].ch; + } /** * Sets the color for the specified type. @@ -236,7 +247,10 @@ class Palette : public gcn::ListModel /** * Commit the colors */ - inline void commit() { commit(false); } + inline void commit() + { + commit(false); + } /** * Rollback the colors @@ -331,7 +345,7 @@ class Palette : public gcn::ListModel * * @return the transformed string */ - static std::string getConfigName(const std::string& typeName); + static std::string getConfigName(const std::string &typeName); }; extern Palette *guiPalette; diff --git a/src/gui/partywindow.cpp b/src/gui/partywindow.cpp new file mode 100644 index 00000000..3f857b5c --- /dev/null +++ b/src/gui/partywindow.cpp @@ -0,0 +1,145 @@ +/* + * The Mana World + * Copyright (C) 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "partywindow.h" +#include "chat.h" + +#include "widgets/avatar.h" + +#include "../utils/gettext.h" +#include "../net/tmwserv/chatserver/party.h" + +PartyWindow::PartyWindow() : Window(_("Party")) +{ + setWindowName("Party"); + setVisible(false); + setResizable(false); + setCaption(_("Party")); + setCloseButton(true); + setMinWidth(110); + setMinHeight(200); + setDefaultSize(620, 300, 110, 200); + + loadWindowState(); +} + +PartyWindow::~PartyWindow() +{ + mPartyMembers.clear(); +} + +void PartyWindow::draw(gcn::Graphics *graphics) +{ + Window::draw(graphics); +} + +void PartyWindow::addPartyMember(const std::string &memberName) +{ + // check to see if player is already in the party + PartyList::iterator itr = mPartyMembers.begin(), + itr_end = mPartyMembers.end(); + + while (itr != itr_end) + { + if ((*itr).name == memberName) + { + // already in the party, dont add + return; + } + ++itr; + } + + // create new party member + PartyMember player; + player.name = memberName; + mPartyMembers.push_back(player); + + // add avatar of the new member to window + Avatar *avatar = new Avatar(memberName); + add(avatar, 0, (mPartyMembers.size() - 1)*14); + + // show the window + if (mPartyMembers.size() > 0) + { + setVisible(true); + } +} + +void PartyWindow::removePartyMember(const std::string &memberName) +{ + // remove the party member + PartyList::iterator itr = mPartyMembers.begin(), + itr_end = mPartyMembers.end(); + + while (itr != itr_end) + { + if ((*itr).name == memberName) + { + mPartyMembers.erase(itr); + break; + } + ++itr; + } + + // if no-one left, remove the party window + if (mPartyMembers.size() < 1) + { + setVisible(false); + } +} + +void PartyWindow::showPartyInvite(const std::string &inviter) +{ + // check there isnt already an invite showing + if (mPartyInviter != "") + { + localChatTab->chatLog("Received party request, but one already exists", + BY_SERVER); + return; + } + + // log invite + std::string msg = inviter + " has invited you to join their party"; + localChatTab->chatLog(msg, BY_SERVER); + + // show invite + acceptDialog = new ConfirmDialog("Accept Party Invite", msg, this); + acceptDialog->addActionListener(this); + + mPartyInviter = inviter; +} + +void PartyWindow::action(const gcn::ActionEvent &event) +{ + const std::string &eventId = event.getId(); + + // check if they accepted the invite + if (eventId == "yes") + { + localChatTab->chatLog("Accepted invite from " + mPartyInviter); + Net::ChatServer::Party::acceptInvite(mPartyInviter); + mPartyInviter = ""; + } + else if (eventId == "no") + { + mPartyInviter = ""; + } +} diff --git a/src/gui/partywindow.h b/src/gui/partywindow.h new file mode 100644 index 00000000..b587cc42 --- /dev/null +++ b/src/gui/partywindow.h @@ -0,0 +1,96 @@ +/* + * The Mana World + * Copyright (C) 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PARTYWINDOW_H +#define PARTYWINDOW_H + +#include "window.h" +#include "confirm_dialog.h" + +#include <string> +#include <vector> + +#include <guichan/actionevent.hpp> +#include <guichan/actionlistener.hpp> + +/** + * Party Member + * Used for storing players in the party + */ +struct PartyMember +{ + std::string name; + int vitality; +}; + +/** + * Party Window. + * + * \ingroup Interface + */ +class PartyWindow : public Window, gcn::ActionListener +{ + public: + /** + * Constructor. + */ + PartyWindow(); + + /** + * Release all the players created + */ + ~PartyWindow(); + + /** + * Draws the party window + */ + void draw(gcn::Graphics *graphics); + + /** + * Add party member + */ + void addPartyMember(const std::string &memberName); + + /** + * Remove party member + */ + void removePartyMember(const std::string &memberName); + + /** + * Show party invite + */ + void showPartyInvite(const std::string &inviter); + + /** + * Handle events + */ + void action(const gcn::ActionEvent &event); + + private: + typedef std::vector<PartyMember> PartyList; + PartyList mPartyMembers; + std::string mPartyInviter; + ConfirmDialog *acceptDialog; +}; + +extern PartyWindow *partyWindow; + +#endif diff --git a/src/gui/passwordfield.cpp b/src/gui/passwordfield.cpp index 073f5e36..fd8ebe22 100644 --- a/src/gui/passwordfield.cpp +++ b/src/gui/passwordfield.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,7 +21,7 @@ #include "passwordfield.h" -PasswordField::PasswordField(const std::string& text): +PasswordField::PasswordField(const std::string &text): TextField(text) { } diff --git a/src/gui/passwordfield.h b/src/gui/passwordfield.h index adad54fe..3b0b5dab 100644 --- a/src/gui/passwordfield.h +++ b/src/gui/passwordfield.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,8 +22,6 @@ #ifndef PASSWORDFIELD_H #define PASSWORDFIELD_H -#include <string> - #include "textfield.h" /** @@ -38,7 +35,7 @@ class PasswordField : public TextField /** * Constructor, initializes the password field with the given string. */ - PasswordField(const std::string& text = ""); + PasswordField(const std::string &text = ""); /** * Draws the password field. diff --git a/src/gui/playerbox.cpp b/src/gui/playerbox.cpp index 2a6cdb20..b7e553dc 100644 --- a/src/gui/playerbox.cpp +++ b/src/gui/playerbox.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -85,10 +84,14 @@ void PlayerBox::draw(gcn::Graphics *graphics) if (mPlayer) { // Draw character - int x, y, bs; - bs = getFrameSize(); - x = getWidth() / 2 - 16 + bs; - y = getHeight() / 2 + bs; + const int bs = getFrameSize(); +#ifdef TMWSERV_SUPPORT + const int x = getWidth() / 2 + bs; + const int y = getHeight() - bs - 8; + mPlayer->draw(static_cast<Graphics*>(graphics), x, y); +#else + const int x = getWidth() / 2 - 16 + bs; + const int y = getHeight() / 2 + bs; for (int i = 0; i < Being::VECTOREND_SPRITE; i++) { if (mPlayer->getSprite(i)) @@ -96,6 +99,7 @@ void PlayerBox::draw(gcn::Graphics *graphics) mPlayer->getSprite(i)->draw(static_cast<Graphics*>(graphics), x, y); } } +#endif } if (config.getValue("guialpha", 0.8) != mAlpha) diff --git a/src/gui/playerbox.h b/src/gui/playerbox.h index ee25520a..7c08defd 100644 --- a/src/gui/playerbox.h +++ b/src/gui/playerbox.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/popup.cpp b/src/gui/popup.cpp index f4c7d4a3..648a9d6a 100644 --- a/src/gui/popup.cpp +++ b/src/gui/popup.cpp @@ -1,9 +1,9 @@ /* - * Aethyra + * The Mana World + * Copyright (C) 2004 The Mana World Development Team * Copyright (C) 2009 Aethyra Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,7 +32,7 @@ #include "../resources/image.h" -Popup::Popup(const std::string& name, const std::string& skin): +Popup::Popup(const std::string &name, const std::string &skin): mPopupName(name), mDefaultSkinPath(skin), mMinWidth(100), diff --git a/src/gui/popup.h b/src/gui/popup.h index c68c2098..6fbe796c 100644 --- a/src/gui/popup.h +++ b/src/gui/popup.h @@ -1,9 +1,9 @@ /* - * Aethyra + * The Mana World + * Copyright (C) 2004 The Mana World Development Team * Copyright (C) 2009 Aethyra Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -52,7 +52,7 @@ class Popup : public gcn::Container * debugging purposes. * @param skin The location where the Popup's skin XML can be found. */ - Popup(const std::string& name = "", + Popup(const std::string &name = "", const std::string &skin = "graphics/gui/gui.xml"); /** @@ -97,39 +97,27 @@ class Popup : public gcn::Container */ void setMinWidth(int width); + int getMinWidth() const { return mMinWidth; } + /** * Sets the minimum height of the popup. */ void setMinHeight(int height); + int getMinHeight() const { return mMinHeight; } + /** * Sets the maximum width of the popup. */ void setMaxWidth(int width); + int getMaxWidth() const { return mMaxWidth; } + /** * Sets the minimum height of the popup. */ void setMaxHeight(int height); - /** - * Gets the minimum width of the popup. - */ - int getMinWidth() const { return mMinWidth; } - - /** - * Gets the minimum height of the popup. - */ - int getMinHeight() const { return mMinHeight; } - - /** - * Gets the maximum width of the popup. - */ - int getMaxWidth() const { return mMaxWidth; } - - /** - * Gets the minimum height of the popup. - */ int getMaxHeight() const { return mMaxHeight; } /** @@ -141,24 +129,16 @@ class Popup : public gcn::Container */ int getPadding() const { return mPadding; } - /** - * Sets the padding of the popup. The padding is the distance between the - * popup border and the content. - * - * @param padding The padding of the popup. - * @see getPadding - */ void setPadding(int padding) { mPadding = padding; } /** * Sets the name of the popup. This is only useful for debug purposes. */ - void setPopupName(const std::string &name) { mPopupName = name; } + void setPopupName(const std::string &name) + { mPopupName = name; } - /** - * Returns the name of the popup. This is only useful for debug purposes. - */ - const std::string& getPopupName() { return mPopupName; } + const std::string &getPopupName() const + { return mPopupName; } /** * Schedule this popup for deletion. It will be deleted at the start @@ -179,7 +159,7 @@ class Popup : public gcn::Container int mMaxHeight; /**< Maximum popup height */ int mPadding; /**< Holds the padding of the popup. */ - Skin* mSkin; /**< Skin in use by this popup */ + Skin *mSkin; /**< Skin in use by this popup */ }; #endif diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp index 13adf827..0b019fef 100644 --- a/src/gui/popupmenu.cpp +++ b/src/gui/popupmenu.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,30 +19,34 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <cassert> +#include "gui/popupmenu.h" + +#include "gui/browserbox.h" +#include "gui/chat.h" +#include "gui/inventorywindow.h" +#include "gui/item_amount.h" -#include "browserbox.h" -#include "chat.h" -#include "inventorywindow.h" -#include "item_amount.h" -#include "popupmenu.h" +#include "being.h" +#include "beingmanager.h" +#include "floor_item.h" +#include "graphics.h" +#include "item.h" +#include "localplayer.h" +#include "npc.h" +#include "player_relations.h" -#include "../being.h" -#include "../beingmanager.h" -#include "../floor_item.h" -#include "../graphics.h" -#include "../item.h" -#include "../localplayer.h" -#include "../npc.h" -#include "../player_relations.h" +#ifdef EATHENA_SUPPORT +#include "net/messageout.h" +#include "net/ea/protocol.h" +#endif -#include "../net/messageout.h" -#include "../net/protocol.h" +#include "resources/itemdb.h" +#include "resources/iteminfo.h" -#include "../resources/itemdb.h" +#include "utils/gettext.h" +#include "utils/strprintf.h" -#include "../utils/gettext.h" -#include "../utils/strprintf.h" +#include <cassert> extern std::string tradePartnerName; @@ -57,7 +60,7 @@ PopupMenu::PopupMenu(): setTitleBarHeight(0); setShowTitle(false); - mBrowserBox = new BrowserBox(); + mBrowserBox = new BrowserBox; mBrowserBox->setPosition(4, 4); mBrowserBox->setHighlightMode(BrowserBox::BACKGROUND); mBrowserBox->setOpaque(false); @@ -85,26 +88,28 @@ void PopupMenu::showPopup(int x, int y, Being *being) mBrowserBox->addRow("##3---"); switch (player_relations.getRelation(name)) { - case PlayerRelation::NEUTRAL: - mBrowserBox->addRow(strprintf(_("@@friend|Befriend %s@@"), name.c_str())); - - case PlayerRelation::FRIEND: - mBrowserBox->addRow(strprintf(_("@@disregard|Disregard %s@@"), name.c_str())); - mBrowserBox->addRow(strprintf(_("@@ignore|Ignore %s@@"), name.c_str())); - break; - - case PlayerRelation::DISREGARDED: - mBrowserBox->addRow(strprintf(_("@@unignore|Un-Ignore %s@@"), name.c_str())); - mBrowserBox->addRow(strprintf(_("@@ignore|Completely ignore %s@@"), name.c_str())); - break; - - case PlayerRelation::IGNORED: - mBrowserBox->addRow(strprintf(_("@@unignore|Un-Ignore %s@@"), name.c_str())); - break; + case PlayerRelation::NEUTRAL: + mBrowserBox->addRow(strprintf(_("@@friend|Befriend %s@@"), name.c_str())); + + case PlayerRelation::FRIEND: + mBrowserBox->addRow(strprintf(_("@@disregard|Disregard %s@@"), name.c_str())); + mBrowserBox->addRow(strprintf(_("@@ignore|Ignore %s@@"), name.c_str())); + break; + + case PlayerRelation::DISREGARDED: + mBrowserBox->addRow(strprintf(_("@@unignore|Un-Ignore %s@@"), name.c_str())); + mBrowserBox->addRow(strprintf(_("@@ignore|Completely ignore %s@@"), name.c_str())); + break; + + case PlayerRelation::IGNORED: + mBrowserBox->addRow(strprintf(_("@@unignore|Un-Ignore %s@@"), name.c_str())); + break; } //mBrowserBox->addRow(_("@@follow|Follow ") + name + "@@"); //mBrowserBox->addRow(_("@@buddy|Add ") + name + " to Buddy List@@"); + mBrowserBox->addRow(strprintf(_("@@guild|Invite %s@@"), name.c_str())); + mBrowserBox->addRow(strprintf(_("@@party|Invite %s to join your party@@"), name.c_str())); mBrowserBox->addRow("##3---"); mBrowserBox->addRow(strprintf(_("@@party-invite|Invite %s to party@@"), name.c_str())); @@ -145,51 +150,78 @@ void PopupMenu::showPopup(int x, int y, FloorItem *floorItem) showPopup(x, y); } -void PopupMenu::handleLink(const std::string& link) +void PopupMenu::handleLink(const std::string &link) { Being *being = beingManager->findBeing(mBeingId); // Talk To action - if (link == "talk" && being && being->getType() == Being::NPC && + if (link == "talk" && + being && + being->getType() == Being::NPC && current_npc == 0) { dynamic_cast<NPC*>(being)->talk(); } // Trade action - else if (link == "trade" && being && being->getType() == Being::PLAYER) + else if (link == "trade" && + being && + being->getType() == Being::PLAYER) { player_node->trade(being); tradePartnerName = being->getName(); } - +#ifdef EATHENA_SUPPORT // Attack action - else if (link == "attack" && being && being->getType() == Being::PLAYER) + else if (link == "attack" && + being && + being->getType() == Being::PLAYER) { player_node->attack(being, true); } - - else if (link == "unignore" && being && being->getType() == Being::PLAYER) +#endif + else if (link == "unignore" && + being && + being->getType() == Being::PLAYER) { player_relations.setRelation(being->getName(), PlayerRelation::NEUTRAL); } - else if (link == "ignore" && being && being->getType() == Being::PLAYER) + else if (link == "ignore" && + being && + being->getType() == Being::PLAYER) { player_relations.setRelation(being->getName(), PlayerRelation::IGNORED); } - else if (link == "disregard" && being && + else if (link == "disregard" && + being && being->getType() == Being::PLAYER) { player_relations.setRelation(being->getName(), PlayerRelation::DISREGARDED); } - else if (link == "friend" && being && being->getType() == Being::PLAYER) + else if (link == "friend" && + being && + being->getType() == Being::PLAYER) { player_relations.setRelation(being->getName(), PlayerRelation::FRIEND); } +#ifdef TMWSERV_SUPPORT + // Guild action + else if (link == "guild" && + being != NULL && + being->getType() == Being::PLAYER) + { + player_node->inviteToGuild(being); + } + // Add player to your party + else if (link == "party") + { + player_node->inviteToParty(being->getName()); + } +#endif /* // Follow Player action else if (link == "follow") @@ -222,6 +254,9 @@ void PopupMenu::handleLink(const std::string& link) assert(mItem); if (mItem->isEquipment()) { +#ifdef TMWSERV_SUPPORT + player_node->equipItem(mItem); +#else if (mItem->isEquipped()) { player_node->unequipItem(mItem); @@ -230,10 +265,15 @@ void PopupMenu::handleLink(const std::string& link) { player_node->equipItem(mItem); } +#endif } else { +#ifdef TMWSERV_SUPPORT + player_node->useItem(mItem->getInvIndex()); +#else player_node->useItem(mItem); +#endif } } @@ -242,17 +282,24 @@ void PopupMenu::handleLink(const std::string& link) chatWindow->addItemText(mItem->getInfo().getName()); } + else if (link == "split") + { + new ItemAmountWindow(AMOUNT_ITEM_SPLIT, inventoryWindow, mItem); + } else if (link == "drop") { new ItemAmountWindow(AMOUNT_ITEM_DROP, inventoryWindow, mItem); } - else if (link == "party-invite" && being && +#ifdef EATHENA_SUPPORT + else if (link == "party-invite" && + being && being->getType() == Being::PLAYER) { MessageOut outMsg(player_node->getNetwork()); outMsg.writeInt16(CMSG_PARTY_INVITE); outMsg.writeInt32(being->getId()); } +#endif // Unknown actions else @@ -275,15 +322,23 @@ void PopupMenu::showPopup(int x, int y, Item *item) if (item->isEquipment()) { +#ifdef TMWSERV_SUPPORT + mBrowserBox->addRow(_("@@use|Equip@@")); +#else if (item->isEquipped()) mBrowserBox->addRow(_("@@use|Unequip@@")); else mBrowserBox->addRow(_("@@use|Equip@@")); +#endif } else mBrowserBox->addRow(_("@@use|Use@@")); mBrowserBox->addRow(_("@@drop|Drop@@")); +#ifdef TMWSERV_SUPPORT + if (!item->isEquipment()) + mBrowserBox->addRow(_("@@split|Split@@")); +#endif mBrowserBox->addRow(_("@@chat|Add to Chat@@")); mBrowserBox->addRow("##3---"); mBrowserBox->addRow(_("@@cancel|Cancel@@")); diff --git a/src/gui/popupmenu.h b/src/gui/popupmenu.h index 89152751..d9fb4777 100644 --- a/src/gui/popupmenu.h +++ b/src/gui/popupmenu.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -62,7 +61,7 @@ class PopupMenu : public Window, public LinkHandler /** * Handles link action. */ - void handleLink(const std::string& link); + void handleLink(const std::string &link); private: BrowserBox* mBrowserBox; diff --git a/src/gui/progressbar.cpp b/src/gui/progressbar.cpp index 1f21df79..02ddab16 100644 --- a/src/gui/progressbar.cpp +++ b/src/gui/progressbar.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,6 +43,9 @@ ProgressBar::ProgressBar(float progress, mRed(red), mGreen(green), mBlue(blue), mRedToGo(red), mGreenToGo(green), mBlueToGo(blue) { + mProgressToGo = mProgress = 0.0f; + mSmoothProgress = mSmoothColorChange = true; + setProgress(progress); setWidth(width); setHeight(height); @@ -93,13 +95,31 @@ ProgressBar::~ProgressBar() void ProgressBar::logic() { - // Smoothly changing the color for a nicer effect. - if (mRedToGo > mRed) mRed++; - if (mRedToGo < mRed) mRed--; - if (mGreenToGo > mGreen) mGreen++; - if (mGreenToGo < mGreen) mGreen--; - if (mBlueToGo > mBlue) mBlue++; - if (mBlueToGo < mBlue) mBlue--; + if (mSmoothColorChange) + { + // Smoothly changing the color for a nicer effect. + if (mRedToGo > mRed) mRed++; + if (mRedToGo < mRed) mRed--; + if (mGreenToGo > mGreen) mGreen++; + if (mGreenToGo < mGreen) mGreen--; + if (mBlueToGo > mBlue) mBlue++; + if (mBlueToGo < mBlue) mBlue--; + } + else + { + mRed = mRedToGo; + mGreen = mGreenToGo; + mBlue = mBlueToGo; + } + + if (mSmoothProgress) + { + // Smoothly showing the progressbar changes. + if (mProgressToGo > mProgress) mProgress = mProgress + 0.005f; + if (mProgressToGo < mProgress) mProgress = mProgress - 0.005f; + } + else + mProgress = mProgressToGo; } void ProgressBar::draw(gcn::Graphics *graphics) @@ -142,9 +162,9 @@ void ProgressBar::draw(gcn::Graphics *graphics) void ProgressBar::setProgress(float progress) { - if (progress < 0.0f) mProgress = 0.0; - else if (progress > 1.0f) mProgress = 1.0; - else mProgress = progress; + if (progress < 0.0f) mProgressToGo = 0.0; + else if (progress > 1.0f) mProgressToGo = 1.0; + else mProgressToGo = progress; } void ProgressBar::setColor(Uint8 red, Uint8 green, Uint8 blue) diff --git a/src/gui/progressbar.h b/src/gui/progressbar.h index 3c88f3a3..e75b1d44 100644 --- a/src/gui/progressbar.h +++ b/src/gui/progressbar.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -103,16 +102,35 @@ class ProgressBar : public gcn::Widget const std::string &text() const { return mText; } + /** + * Set wether the progress is moved smoothly. + */ + void setSmoothProgress(bool smoothProgress) + { mSmoothProgress = smoothProgress; } + + /** + * Set wether the color changing is made smoothly. + */ + void setSmoothColorChange(bool smoothColorChange) + { mSmoothColorChange = smoothColorChange; } + + private: - float mProgress; + float mProgress, mProgressToGo; + bool mSmoothProgress; + Uint8 mRed, mGreen, mBlue; Uint8 mRedToGo, mGreenToGo, mBlueToGo; + bool mSmoothColorChange; + std::string mText; bool mUpdated; static ImageRect mBorder; static int mInstances; static float mAlpha; + + static const gcn::Color TEXT_COLOR; }; #endif diff --git a/src/gui/quitdialog.cpp b/src/gui/quitdialog.cpp new file mode 100644 index 00000000..83794ffe --- /dev/null +++ b/src/gui/quitdialog.cpp @@ -0,0 +1,135 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "quitdialog.h" +#include <iostream> +#include <string> + +#include <guichan/widgets/label.hpp> + +#include "../main.h" + +#include "button.h" +#include "radiobutton.h" + +#include "../utils/gettext.h" + +QuitDialog::QuitDialog(bool* quitGame, QuitDialog** pointerToMe): + Window(_("Quit"), true, NULL), mQuitGame(quitGame), mMyPointer(pointerToMe) +{ + + mLogoutQuit = new RadioButton(_("Quit"), "quitdialog"); + mForceQuit = new RadioButton(_("Quit"), "quitdialog"); + mSwitchAccountServer = new RadioButton(_("Switch server"), "quitdialog"); + mSwitchCharacter = new RadioButton(_("Switch character"), "quitdialog"); + mOkButton = new Button(_("Ok"), "ok", this); + mCancelButton = new Button(_("Cancel"), "cancel", this); + + setContentSize(200, 91); + + mLogoutQuit->setPosition(5, 5); + mForceQuit->setPosition(5, 5); + mSwitchAccountServer->setPosition(5, 14 + mLogoutQuit->getHeight()); + mSwitchCharacter->setPosition(5, + 23 + mLogoutQuit->getHeight() + mSwitchAccountServer->getHeight()); + mCancelButton->setPosition( + 200 - mCancelButton->getWidth() - 5, + 91 - mCancelButton->getHeight() - 5); + mOkButton->setPosition( + mCancelButton->getX() - mOkButton->getWidth() - 5, + 91 - mOkButton->getHeight() - 5); + + //All states, when we're not logged in to someone. + if (state == STATE_CHOOSE_SERVER || + state == STATE_CONNECT_ACCOUNT || + state == STATE_LOGIN || + state == STATE_LOGIN_ATTEMPT || + state == STATE_UPDATE) + { + mForceQuit->setSelected(true); + add(mForceQuit); + } + else + { + // Only added if we are connected to an accountserver or gameserver + mLogoutQuit->setSelected(true); + add(mLogoutQuit); + add(mSwitchAccountServer); + + // Only added if we are connected to a gameserver + if (state == STATE_GAME) add(mSwitchCharacter); + } + + add(mOkButton); + add(mCancelButton); + + setLocationRelativeTo(getParent()); + setVisible(true); + + mOkButton->requestFocus(); + +} + +QuitDialog::~QuitDialog() +{ + if (mMyPointer) *mMyPointer = NULL; + // Optional widgets, so delete them by hand. + delete mForceQuit; + delete mLogoutQuit; + delete mSwitchAccountServer; + delete mSwitchCharacter; +} + +void +QuitDialog::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "ok") + { + if (mForceQuit->isSelected()) + { + state = STATE_FORCE_QUIT; + } + else if (mLogoutQuit->isSelected()) + { + if ((state == STATE_GAME) && (mQuitGame)) + { + *mQuitGame = true; + } + state = STATE_EXIT; + } + else if (mSwitchAccountServer->isSelected()) + { + if ((state == STATE_GAME) && (mQuitGame)) + { + *mQuitGame = true; + } + state = STATE_SWITCH_ACCOUNTSERVER_ATTEMPT; + } + else if (mSwitchCharacter->isSelected()) + { + if (mQuitGame) *mQuitGame = true; + + state = STATE_SWITCH_CHARACTER; + } + + } + scheduleDelete(); +} diff --git a/src/gui/quitdialog.h b/src/gui/quitdialog.h new file mode 100644 index 00000000..aee671db --- /dev/null +++ b/src/gui/quitdialog.h @@ -0,0 +1,70 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef QUITDIALOG_H +#define QUITDIALOG_H + +#include <iosfwd> +#include <guichan/actionlistener.hpp> + +#include "window.h" +#include "../guichanfwd.h" +#include "../main.h" + +/** + * The quit dialog. + * + * \ingroup Interface + */ +class QuitDialog : public Window, public gcn::ActionListener { + public: + /** + * Constructor + * + * @quitGame; to be used for getting out of the while loop in Game + * @pointerToMe; will be set to NULL when the QuitDialog is destroyed + */ + QuitDialog(bool* quitGame, QuitDialog** pointerToMe); + + /** + * Destructor + */ + ~QuitDialog(); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + private: + gcn::RadioButton *mLogoutQuit; + gcn::RadioButton *mForceQuit; + gcn::RadioButton *mSwitchAccountServer; + gcn::RadioButton *mSwitchCharacter; + gcn::Button *mOkButton; + gcn::Button *mCancelButton; + + bool* mQuitGame; + QuitDialog** mMyPointer; + +}; + +#endif diff --git a/src/gui/radiobutton.cpp b/src/gui/radiobutton.cpp index c839238b..b05e37e6 100644 --- a/src/gui/radiobutton.cpp +++ b/src/gui/radiobutton.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,7 +34,7 @@ Image *RadioButton::radioChecked; Image *RadioButton::radioDisabled; Image *RadioButton::radioDisabledChecked; -RadioButton::RadioButton(const std::string& caption, const std::string& group, +RadioButton::RadioButton(const std::string &caption, const std::string &group, bool marked): gcn::RadioButton(caption, group, marked) { diff --git a/src/gui/radiobutton.h b/src/gui/radiobutton.h index cd501126..9aec3add 100644 --- a/src/gui/radiobutton.h +++ b/src/gui/radiobutton.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,7 +35,7 @@ class RadioButton : public gcn::RadioButton /* * Constructor. */ - RadioButton(const std::string& caption,const std::string& group, + RadioButton(const std::string &caption,const std::string &group, bool marked = false); /** diff --git a/src/gui/recorder.cpp b/src/gui/recorder.cpp index 9320e020..4f919bef 100644 --- a/src/gui/recorder.cpp +++ b/src/gui/recorder.cpp @@ -2,7 +2,7 @@ * A chat recorder * Copyright (C) 2008 Lloyd Bryant <lloyd_bryant@netzero.net> * - * This file is part of Aethyra. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +26,7 @@ #include "recorder.h" #include "windowcontainer.h" +#include "widgets/chattab.h" #include "widgets/layout.h" #include "../utils/stringutils.h" @@ -34,7 +35,7 @@ Recorder::Recorder(ChatWindow *chat, const std::string &title, const std::string &buttonTxt) : Window(title) { - setWindowName(_("Recorder")); + setWindowName("Recorder"); const int offsetX = 2 * getPadding() + 10; const int offsetY = getTitleBarHeight() + getPadding() + 10; @@ -66,7 +67,7 @@ void Recorder::record(const std::string &msg) } } -void Recorder::changeRecordingStatus(const std::string &msg) +void Recorder::setRecordingFile(const std::string &msg) { std::string msgCopy = msg; trim(msgCopy); @@ -82,16 +83,16 @@ void Recorder::changeRecordingStatus(const std::string &msg) * Message should go after mStream is closed so that it isn't * recorded. */ - mChat->chatLog(_("Finishing recording."), BY_SERVER); + localChatTab->chatLog(_("Finishing recording."), BY_SERVER); } else { - mChat->chatLog(_("Not currently recording."), BY_SERVER); + localChatTab->chatLog(_("Not currently recording."), BY_SERVER); } } else if (mStream.is_open()) { - mChat->chatLog(_("Already recording."), BY_SERVER); + localChatTab->chatLog(_("Already recording."), BY_SERVER); } else { @@ -99,19 +100,20 @@ void Recorder::changeRecordingStatus(const std::string &msg) * Message should go before mStream is opened so that it isn't * recorded. */ - mChat->chatLog(_("Starting to record..."), BY_SERVER); - std::string file = std::string(PHYSFS_getUserDir()) + "/.aethyra/" + msgCopy; + localChatTab->chatLog(_("Starting to record..."), BY_SERVER); + const std::string file = + std::string(PHYSFS_getUserDir()) + "/.tmw/" + msgCopy; mStream.open(file.c_str(), std::ios_base::trunc); if (mStream.is_open()) setVisible(true); else - mChat->chatLog(_("Failed to start recording."), BY_SERVER); + localChatTab->chatLog(_("Failed to start recording."), BY_SERVER); } } void Recorder::action(const gcn::ActionEvent &event) { - changeRecordingStatus(""); + setRecordingFile(""); } diff --git a/src/gui/recorder.h b/src/gui/recorder.h index 4f41ff42..39d00c2c 100644 --- a/src/gui/recorder.h +++ b/src/gui/recorder.h @@ -2,7 +2,7 @@ * A chat recorder * Copyright (C) 2008 Lloyd Bryant <lloyd_bryant@netzero.net> * - * This file is part of Aethyra. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,26 +41,26 @@ class Recorder : public Window, public gcn::ActionListener virtual ~Recorder(); - /* + /** * Outputs the message to the recorder file * * @param msg the line to write to the recorded file. */ void record(const std::string &msg); - /* - * Outputs the message to the recorder file + /** + * Sets the file being recorded to * * @param msg The file to write out to. If null, then stop recording. */ - void changeRecordingStatus(const std::string &msg); + void setRecordingFile(const std::string &msg); - /* + /** * Whether or not the recorder is in use. */ - bool isRecording() {return (bool) mStream.is_open();} + bool isRecording() { return (bool) mStream.is_open(); } - /* + /** * called when the button is pressed * * @param event is the event that is generated diff --git a/src/gui/register.cpp b/src/gui/register.cpp index 63a0d29c..5fb8b579 100644 --- a/src/gui/register.cpp +++ b/src/gui/register.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,20 +40,6 @@ #include "../utils/strprintf.h" #include "../utils/stringutils.h" -/** - * Listener used while dealing with wrong data. It is used to direct the focus - * to the field which contained wrong data when the Ok button was pressed on - * the error notice. - */ -class WrongDataNoticeListener : public gcn::ActionListener -{ - public: - void setTarget(gcn::TextField *textField); - void action(const gcn::ActionEvent &event); - private: - gcn::TextField *mTarget; -}; - void WrongDataNoticeListener::setTarget(gcn::TextField *textField) { mTarget = textField; @@ -74,15 +59,19 @@ RegisterDialog::RegisterDialog(LoginData *loginData): gcn::Label *userLabel = new Label(_("Name:")); gcn::Label *passwordLabel = new Label(_("Password:")); gcn::Label *confirmLabel = new Label(_("Confirm:")); +#ifdef EATHENA_SUPPORT gcn::Label *serverLabel = new Label(_("Server:")); gcn::Label *portLabel = new Label(_("Port:")); +#endif mUserField = new TextField(loginData->username); mPasswordField = new PasswordField(loginData->password); mConfirmField = new PasswordField; +#ifdef EATHENA_SUPPORT mServerField = new TextField(loginData->hostname); mPortField = new TextField(toString(loginData->port)); mMaleButton = new RadioButton(_("Male"), "sex", true); mFemaleButton = new RadioButton(_("Female"), "sex", false); +#endif mRegisterButton = new Button(_("Register"), "register", this); mCancelButton = new Button(_("Cancel"), "cancel", this); @@ -91,15 +80,19 @@ RegisterDialog::RegisterDialog(LoginData *loginData): place(0, 0, userLabel); place(0, 1, passwordLabel); place(0, 2, confirmLabel); +#ifdef EATHENA_SUPPORT place(1, 3, mMaleButton); place(2, 3, mFemaleButton); place(0, 4, serverLabel); place(0, 5, portLabel); +#endif place(1, 0, mUserField, 3).setPadding(2); place(1, 1, mPasswordField, 3).setPadding(2); place(1, 2, mConfirmField, 3).setPadding(2); +#ifdef EATHENA_SUPPORT place(1, 4, mServerField, 3).setPadding(2); place(1, 5, mPortField, 3).setPadding(2); +#endif place = getPlacer(0, 2); place(1, 0, mRegisterButton); place(2, 0, mCancelButton); @@ -108,8 +101,10 @@ RegisterDialog::RegisterDialog(LoginData *loginData): mUserField->addKeyListener(this); mPasswordField->addKeyListener(this); mConfirmField->addKeyListener(this); +#ifdef EATHENA_SUPPORT mServerField->addKeyListener(this); mPortField->addKeyListener(this); +#endif /* TODO: * This is a quick and dirty way to respond to the ENTER key, regardless of @@ -119,16 +114,20 @@ RegisterDialog::RegisterDialog(LoginData *loginData): mUserField->setActionEventId("register"); mPasswordField->setActionEventId("register"); mConfirmField->setActionEventId("register"); - mServerField->setActionEventId("register"); - mPortField->setActionEventId("register"); mUserField->addActionListener(this); mPasswordField->addActionListener(this); mConfirmField->addActionListener(this); + +#ifdef EATHENA_SUPPORT + mServerField->setActionEventId("register"); + mPortField->setActionEventId("register"); + mServerField->addActionListener(this); mPortField->addActionListener(this); +#endif - setLocationRelativeTo(getParent()); + center(); setVisible(true); mUserField->requestFocus(); mUserField->setCaretPosition(mUserField->getText().length()); @@ -145,7 +144,7 @@ void RegisterDialog::action(const gcn::ActionEvent &event) { if (event.getId() == "cancel") { - state = LOGIN_STATE; + state = STATE_LOGIN; } else if (event.getId() == "register" && canSubmit()) { @@ -194,6 +193,8 @@ void RegisterDialog::action(const gcn::ActionEvent &event) error = 2; } + // TODO: Check if a valid email address was given + if (error > 0) { if (error == 1) @@ -209,23 +210,30 @@ void RegisterDialog::action(const gcn::ActionEvent &event) mWrongDataNoticeListener->setTarget(this->mPasswordField); } - OkDialog *mWrongRegisterNotice = - new OkDialog(_("Error"), errorMsg); - mWrongRegisterNotice->addActionListener(mWrongDataNoticeListener); + OkDialog *dlg = new OkDialog(_("Error"), errorMsg); + dlg->addActionListener(mWrongDataNoticeListener); } else { // No errors detected, register the new user. mRegisterButton->setEnabled(false); - mLoginData->hostname = mServerField->getText(); - mLoginData->port = getUShort(mPortField->getText()); mLoginData->username = mUserField->getText(); mLoginData->password = mPasswordField->getText(); +#ifdef EATHENA_SUPPORT + mLoginData->hostname = mServerField->getText(); + mLoginData->port = getUShort(mPortField->getText()); mLoginData->username += mFemaleButton->isSelected() ? "_F" : "_M"; +#else + mLoginData->email = mEmailField->getText(); +#endif mLoginData->registerLogin = true; - state = ACCOUNT_STATE; +#ifdef TMWSERV_SUPPORT + state = STATE_REGISTER_ATTEMPT; +#else + state = STATE_ACCOUNT; +#endif } } } @@ -240,11 +248,14 @@ bool RegisterDialog::canSubmit() const return !mUserField->getText().empty() && !mPasswordField->getText().empty() && !mConfirmField->getText().empty() && +#ifdef EATHENA_SUPPORT !mServerField->getText().empty() && isUShort(mPortField->getText()) && - state == REGISTER_STATE; +#endif + state == STATE_REGISTER; } +#ifdef EATHENA_SUPPORT bool RegisterDialog::isUShort(const std::string &str) { if (str.empty()) @@ -278,3 +289,4 @@ unsigned short RegisterDialog::getUShort(const std::string &str) } return static_cast<unsigned short>(l); } +#endif diff --git a/src/gui/register.h b/src/gui/register.h index 922320db..c37305e4 100644 --- a/src/gui/register.h +++ b/src/gui/register.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,7 +31,20 @@ class LoginData; class OkDialog; -class WrongDataNoticeListener; + +/** + * Listener used while dealing with wrong data. It is used to direct the focus + * to the field which contained wrong data when the Ok button was pressed on + * the error notice. + */ +class WrongDataNoticeListener : public gcn::ActionListener +{ + public: + void setTarget(gcn::TextField *textField); + void action(const gcn::ActionEvent &event); + private: + gcn::TextField *mTarget; +}; /** * The registration dialog. @@ -73,6 +85,7 @@ class RegisterDialog : public Window, public gcn::ActionListener, */ bool canSubmit() const; +#ifdef EATHENA_SUPPORT /** * Function to decide whether string is an unsigned short or not * @@ -90,17 +103,24 @@ class RegisterDialog : public Window, public gcn::ActionListener, * @return the value str represents */ static unsigned short getUShort(const std::string &str); +#endif gcn::TextField *mUserField; gcn::TextField *mPasswordField; gcn::TextField *mConfirmField; +#ifdef EATHENA_SUPPORT gcn::TextField *mServerField; gcn::TextField *mPortField; +#else + gcn::TextField *mEmailField; +#endif gcn::Button *mRegisterButton; gcn::Button *mCancelButton; +#ifdef EATHENA_SUPPORT gcn::RadioButton *mMaleButton; gcn::RadioButton *mFemaleButton; +#endif WrongDataNoticeListener *mWrongDataNoticeListener; diff --git a/src/gui/scrollarea.cpp b/src/gui/scrollarea.cpp index 156ff054..92bb94b8 100644 --- a/src/gui/scrollarea.cpp +++ b/src/gui/scrollarea.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,18 +35,16 @@ ImageRect ScrollArea::background; ImageRect ScrollArea::vMarker; Image *ScrollArea::buttons[4][2]; -ScrollArea::ScrollArea(bool gc, bool opaque): +ScrollArea::ScrollArea(): gcn::ScrollArea(), - mOpaque(opaque), - mGC(gc) + mOpaque(true) { init(); } -ScrollArea::ScrollArea(gcn::Widget *widget, bool gc, bool opaque): +ScrollArea::ScrollArea(gcn::Widget *widget): gcn::ScrollArea(widget), - mOpaque(opaque), - mGC(gc) + mOpaque(true) { init(); } @@ -55,8 +52,7 @@ ScrollArea::ScrollArea(gcn::Widget *widget, bool gc, bool opaque): ScrollArea::~ScrollArea() { // Garbage collection - if (mGC) - delete getContent(); + delete getContent(); instances--; @@ -224,14 +220,13 @@ void ScrollArea::drawFrame(gcn::Graphics *graphics) const int h = getHeight() + bs * 2; static_cast<Graphics*>(graphics)-> - drawImageRect(0, 0, w, h, background); + drawImageRect(0, 0, w, h, background); } } void ScrollArea::setOpaque(bool opaque) { mOpaque = opaque; - setFrameSize(mOpaque ? 2 : 0); } diff --git a/src/gui/scrollarea.h b/src/gui/scrollarea.h index 080b851c..e9aa5ed2 100644 --- a/src/gui/scrollarea.h +++ b/src/gui/scrollarea.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,6 +30,10 @@ class ImageRect; /** * A scroll area. * + * Contrary to Guichan's scroll area, this scroll area takes ownership over its + * content. However, it won't delete a previously set content widget when + * setContent is called! + * * \ingroup GUI */ class ScrollArea : public gcn::ScrollArea @@ -39,12 +42,12 @@ class ScrollArea : public gcn::ScrollArea /** * Constructor. */ - ScrollArea(bool gc = true, bool opaque = true); + ScrollArea(); /** * Constructor. */ - ScrollArea(gcn::Widget *content, bool gc = true, bool opaque = true); + ScrollArea(gcn::Widget *content); /** * Destructor. @@ -107,7 +110,6 @@ class ScrollArea : public gcn::ScrollArea static Image *buttons[4][2]; bool mOpaque; - bool mGC; }; #endif diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp index 591cf97b..e7671110 100644 --- a/src/gui/sell.cpp +++ b/src/gui/sell.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,30 +19,44 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "button.h" -#include "label.h" -#include "scrollarea.h" -#include "sell.h" -#include "shop.h" -#include "shoplistbox.h" -#include "slider.h" +#include "gui/sell.h" -#include "widgets/layout.h" +#include "gui/button.h" +#include "gui/label.h" +#include "gui/scrollarea.h" +#include "gui/shop.h" +#include "gui/shoplistbox.h" +#include "gui/slider.h" -#include "../npc.h" +#include "gui/widgets/layout.h" -#include "../net/messageout.h" -#include "../net/protocol.h" +#include "npc.h" +#include "shopitem.h" +#include "units.h" -#include "../utils/gettext.h" -#include "../utils/strprintf.h" +#include "net/messageout.h" +#ifdef TMWSERV_SUPPORT +#include "net/tmwserv/gameserver/player.h" +#else +#include "net/ea/protocol.h" +#endif +#include "resources/iteminfo.h" + +#include "utils/gettext.h" +#include "utils/strprintf.h" + +#ifdef TMWSERV_SUPPORT +SellDialog::SellDialog(): + Window(_("Sell")), +#else SellDialog::SellDialog(Network *network): - Window("Sell"), + Window(_("Sell")), mNetwork(network), +#endif mMaxItems(0), mAmountItems(0) { - setWindowName(_("Sell")); + setWindowName("Sell"); setResizable(true); setCloseButton(true); setMinWidth(260); @@ -61,8 +74,8 @@ SellDialog::SellDialog(Network *network): mQuantityLabel = new Label(strprintf("%d / %d", mAmountItems, mMaxItems)); mQuantityLabel->setAlignment(gcn::Graphics::CENTER); - mMoneyLabel = new Label( - strprintf(_("Price: %d GP / Total: %d GP"), 0, 0)); + mMoneyLabel = new Label(strprintf(_("Price: %s / Total: %s"), + "", "")); mIncreaseButton = new Button("+", "+", this); mDecreaseButton = new Button("-", "-", this); @@ -103,6 +116,7 @@ SellDialog::SellDialog(Network *network): Layout &layout = getLayout(); layout.setRowHeight(0, Layout::AUTO_SET); + center(); loadWindowState(); } @@ -122,6 +136,16 @@ void SellDialog::reset() updateButtonsAndLabels(); } +#ifdef TMWSERV_SUPPORT + +void SellDialog::addItem(int item, int amount, int price) +{ + mShopItems->addItem(item, amount, price); + mShopItemList->adjustSize(); +} + +#else + void SellDialog::addItem(const Item *item, int price) { if (!item) @@ -133,6 +157,8 @@ void SellDialog::addItem(const Item *item, int price) mShopItemList->adjustSize(); } +#endif + void SellDialog::action(const gcn::ActionEvent &event) { if (event.getId() == "quit") @@ -176,10 +202,14 @@ void SellDialog::action(const gcn::ActionEvent &event) else if (event.getId() == "sell" && mAmountItems > 0 && mAmountItems <= mMaxItems) { +#ifdef TMWSERV_SUPPORT + Net::GameServer::Player::tradeWithNPC + (mShopItems->at(selectedItem)->getId(), mAmountItems); +#else // Attempt sell MessageOut outMsg(mNetwork); - ShopItem* item = mShopItems->at(selectedItem); + ShopItem *item = mShopItems->at(selectedItem); int sellCount; mPlayerMoney += mAmountItems * mShopItems->at(selectedItem)->getPrice(); @@ -194,6 +224,7 @@ void SellDialog::action(const gcn::ActionEvent &event) mAmountItems -= sellCount; outMsg.writeInt16(sellCount); } +#endif mPlayerMoney += mAmountItems * mShopItems->at(selectedItem)->getPrice(); @@ -275,9 +306,16 @@ void SellDialog::updateButtonsAndLabels() // Update the quantity and money labels mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems)); - mMoneyLabel->setCaption - (strprintf(_("Price: %d GP / Total: %d GP"), - income, mPlayerMoney + income)); + mMoneyLabel->setCaption(strprintf(_("Price: %s / Total: %s"), + Units::formatCurrency(income).c_str(), + Units::formatCurrency(mPlayerMoney + income).c_str())); +} + +void SellDialog::logic() +{ + Window::logic(); + + if (!current_npc) setVisible(false); } void SellDialog::setVisible(bool visible) diff --git a/src/gui/sell.h b/src/gui/sell.h index 930f8bc1..b6388a1f 100644 --- a/src/gui/sell.h +++ b/src/gui/sell.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,7 +30,9 @@ #include "window.h" class Item; +#ifdef EATHENA_SUPPORT class Network; +#endif class ShopItems; class ShopListBox; @@ -48,7 +49,11 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener * * @see Window::Window */ +#ifdef TMWSERV_SUPPORT + SellDialog(); +#else SellDialog(Network *network); +#endif /** * Destructor @@ -63,7 +68,11 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener /** * Adds an item to the inventory. */ +#ifdef TMWSERV_SUPPORT + void addItem(int item, int amount, int price); +#else void addItem(const Item *item, int price); +#endif /** * Called when receiving actions from the widgets. @@ -83,6 +92,11 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener void setMoney(int amount); /** + * Check for current NPC + */ + void logic(); + + /** * Sets the visibility of this window. */ void setVisible(bool visible); @@ -97,7 +111,9 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener */ void updateButtonsAndLabels(); +#ifdef EATHENA_SUPPORT Network *mNetwork; +#endif gcn::Button *mSellButton; gcn::Button *mQuitButton; gcn::Button *mAddMaxButton; diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp new file mode 100644 index 00000000..a57be06c --- /dev/null +++ b/src/gui/serverdialog.cpp @@ -0,0 +1,214 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <cstdlib> +#include <iostream> +#include <string> + +#include <guichan/widgets/label.hpp> + +#include "serverdialog.h" + +#include "button.h" +#include "listbox.h" +#include "ok_dialog.h" +#include "scrollarea.h" +#include "textfield.h" + +#include "widgets/layout.h" + +#include "../configuration.h" +#include "../log.h" +#include "../logindata.h" +#include "../main.h" + +#include "../utils/gettext.h" +#include "../utils/stringutils.h" + +const short MAX_SERVERLIST = 5; + +int ServersListModel::getNumberOfElements() +{ + return servers.size(); +} + +std::string ServersListModel::getElementAt(int elementIndex) +{ + std::string myServer = ""; + myServer = servers.at(elementIndex).serverName; + myServer += ":"; + myServer += toString(servers.at(elementIndex).port); + return myServer; +} + +void ServersListModel::addFirstElement(Server server) +{ + // Equivalent to push_front + std::vector<Server>::iterator MyIterator = servers.begin(); + servers.insert(MyIterator, 1, server); +} + +void ServersListModel::addElement(Server server) +{ + servers.push_back(server); +} + +ServerDialog::ServerDialog(LoginData *loginData): + Window(_("Choose your server")), mLoginData(loginData) +{ + gcn::Label *serverLabel = new gcn::Label(_("Server:")); + gcn::Label *portLabel = new gcn::Label(_("Port:")); + mServerNameField = new TextField(mLoginData->hostname); + mPortField = new TextField(toString(mLoginData->port)); + + // Add the most used servers from config + mMostUsedServersListModel = new ServersListModel(); + Server currentServer; + std::string currentConfig = ""; + for (int i=0; i<=MAX_SERVERLIST; i++) + { + currentServer.serverName = ""; + currentServer.port = 0; + + currentConfig = "MostUsedServerName" + toString(i); + currentServer.serverName = config.getValue(currentConfig, ""); + + currentConfig = "MostUsedServerPort" + toString(i); + currentServer.port = (short)atoi(config.getValue(currentConfig, "").c_str()); + if (!currentServer.serverName.empty() || currentServer.port != 0) + { + mMostUsedServersListModel->addElement(currentServer); + } + } + + mMostUsedServersListBox = new ListBox(NULL); + mMostUsedServersListBox->setListModel(mMostUsedServersListModel); + mMostUsedServersScrollArea = new ScrollArea(); + mMostUsedServersDropDown = new DropDown(mMostUsedServersListModel, + mMostUsedServersScrollArea, mMostUsedServersListBox); + + mOkButton = new Button(_("Ok"), "connect", this); + mCancelButton = new Button(_("Cancel"), "cancel", this); + + mServerNameField->setActionEventId("connect"); + mPortField->setActionEventId("connect"); + mMostUsedServersDropDown->setActionEventId("changeSelection"); + + mServerNameField->addActionListener(this); + mPortField->addActionListener(this); + mMostUsedServersDropDown->addActionListener(this); + + place(0, 0, serverLabel); + place(0, 1, portLabel); + place(1, 0, mServerNameField, 3).setPadding(2); + place(1, 1, mPortField, 3).setPadding(2); + place(0, 2, mMostUsedServersDropDown, 4).setPadding(2); + place(2, 3, mOkButton); + place(3, 3, mCancelButton); + reflowLayout(250, 0); + + setLocationRelativeTo(getParent()); + setVisible(true); + + if (mServerNameField->getText().empty()) { + mServerNameField->requestFocus(); + } else { + if (mPortField->getText().empty()) { + mPortField->requestFocus(); + } else { + mOkButton->requestFocus(); + } + } +} + +ServerDialog::~ServerDialog() +{ + delete mMostUsedServersListModel; + delete mMostUsedServersScrollArea; +} + +void +ServerDialog::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "ok") + { + // Give focus back to the server dialog. + mServerNameField->requestFocus(); + } + else if (event.getId() == "changeSelection") + { + // Change the textField Values according to new selection + Server myServer = mMostUsedServersListModel->getServer + (mMostUsedServersListBox->getSelected()); + mServerNameField->setText(myServer.serverName); + mPortField->setText(toString(myServer.port)); + } + else if (event.getId() == "connect") + { + // Check login + if (mServerNameField->getText().empty() || mPortField->getText().empty()) + { + OkDialog *dlg = new OkDialog(_("Error"), + _("Please type both the address and the port of a server.")); + dlg->addActionListener(this); + } + else + { + mLoginData->hostname = mServerNameField->getText(); + mLoginData->port = (short) atoi(mPortField->getText().c_str()); + mOkButton->setEnabled(false); + mCancelButton->setEnabled(false); + + // First, look if the entry is a new one. + Server currentServer; + bool newEntry = true; + for (int i = 0; i < mMostUsedServersListModel->getNumberOfElements(); i++) + { + currentServer = mMostUsedServersListModel->getServer(i); + if (currentServer.serverName == mLoginData->hostname && + currentServer.port == mLoginData->port) + newEntry = false; + } + // Then, add it to config if it's really new + currentServer.serverName = mLoginData->hostname; + currentServer.port = mLoginData->port; + if (newEntry) + mMostUsedServersListModel->addFirstElement(currentServer); + // Write the entry in config + std::string currentConfig = ""; + for (int i = 0; i < mMostUsedServersListModel->getNumberOfElements(); i++) + { + currentServer = mMostUsedServersListModel->getServer(i); + + currentConfig = "MostUsedServerName" + toString(i); + config.setValue(currentConfig, currentServer.serverName); + + currentConfig = "MostUsedServerPort" + toString(i); + config.setValue(currentConfig, toString(currentServer.port)); + } + state = STATE_CONNECT_ACCOUNT; + } + } + else if (event.getId() == "cancel") + { + state = STATE_FORCE_QUIT; + } +} diff --git a/src/gui/serverdialog.h b/src/gui/serverdialog.h new file mode 100644 index 00000000..492f5a2b --- /dev/null +++ b/src/gui/serverdialog.h @@ -0,0 +1,123 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef SERVERDIALOG_H +#define SERVERDIALOG_H + +#include <iosfwd> +#include <vector> + +#include <guichan/actionlistener.hpp> +#include <guichan/listmodel.hpp> +#include "./widgets/dropdown.h" + +#include "login.h" +#include "window.h" + +#include "../guichanfwd.h" + +#include "../net/tmwserv/network.h" + +class LoginData; + +/** + * A server structure to keep pairs of servers and ports. + */ +struct Server { + Server(): + port(0) + {} + + std::string serverName; + short port; +}; + +/** + * Server and Port List Model + */ +class ServersListModel : public gcn::ListModel +{ + public: + /** + * Used to get number of line in the list + */ + int getNumberOfElements(); + /** + * Used to get an element from the list + */ + std::string getElementAt(int elementIndex); + /** + * Used to get the corresponding Server struct + */ + Server getServer(int elementIndex) { return servers[elementIndex]; }; + /** + * Add an Element at the end of the server list + */ + void addElement(Server server); + /** + * Add an Element at the beginning of the server list + */ + void addFirstElement(Server server); + + private: + std::vector<Server> servers; +}; + +/** + * The server choice dialog. + * + * \ingroup Interface + */ +class ServerDialog : public Window, public gcn::ActionListener +{ + public: + /** + * Constructor + * + * @see Window::Window + */ + ServerDialog(LoginData *loginData); + + /** + * Destructor + */ + ~ServerDialog(); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + private: + gcn::TextField *mServerNameField; + gcn::TextField *mPortField; + gcn::Button *mOkButton; + gcn::Button *mCancelButton; + + DropDown *mMostUsedServersDropDown; + gcn::ListBox *mMostUsedServersListBox; + gcn::ScrollArea *mMostUsedServersScrollArea; + ServersListModel *mMostUsedServersListModel; + + LoginData *mLoginData; +}; + +#endif diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp index ca6b4010..72dfbce5 100644 --- a/src/gui/setup.cpp +++ b/src/gui/setup.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -51,7 +50,12 @@ extern Window *helpWindow; extern Window *debugWindow; extern Window *itemShortcutWindow; extern Window *emoteShortcutWindow; +#ifdef TMWSERV_SUPPORT +extern Window *magicDialog; +extern Window *guildWindow; +#else extern Window *storageWindow; +#endif Setup::Setup(): Window(_("Setup")) @@ -108,7 +112,7 @@ Setup::Setup(): add(panel); - setLocationRelativeTo(getParent()); + center(); setInGame(false); } @@ -141,7 +145,9 @@ void Setup::action(const gcn::ActionEvent &event) statusWindow->resetToDefaultSize(); buyDialog->resetToDefaultSize(); sellDialog->resetToDefaultSize(); +#ifdef EATHENA_SUPPORT buySellDialog->resetToDefaultSize(); +#endif inventoryWindow->resetToDefaultSize(); emoteWindow->resetToDefaultSize(); npcTextDialog->resetToDefaultSize(); @@ -154,7 +160,12 @@ void Setup::action(const gcn::ActionEvent &event) debugWindow->resetToDefaultSize(); itemShortcutWindow->resetToDefaultSize(); emoteShortcutWindow->resetToDefaultSize(); +#ifdef TMWSERV_SUPPORT + magicDialog->resetToDefaultSize(); + guildWindow->resetToDefaultSize(); +#else storageWindow->resetToDefaultSize(); +#endif } } diff --git a/src/gui/setup.h b/src/gui/setup.h index 663bdfcb..4c387d34 100644 --- a/src/gui/setup.h +++ b/src/gui/setup.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -63,7 +62,7 @@ class Setup : public Window, public gcn::ActionListener private: std::list<SetupTab*> mTabs; - gcn::Button* mResetWindows; + gcn::Button *mResetWindows; }; extern Setup* setupWindow; diff --git a/src/gui/setup_audio.cpp b/src/gui/setup_audio.cpp index 08eda848..28a80b3d 100644 --- a/src/gui/setup_audio.cpp +++ b/src/gui/setup_audio.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -43,6 +42,7 @@ Setup_Audio::Setup_Audio(): mMusicSlider(new Slider(0, 128)) { setOpaque(false); + setDimension(gcn::Rectangle(0, 0, 250, 200)); gcn::Label *sfxLabel = new Label(_("Sfx volume")); gcn::Label *musicLabel = new Label(_("Music volume")); diff --git a/src/gui/setup_audio.h b/src/gui/setup_audio.h index aad16617..9e951895 100644 --- a/src/gui/setup_audio.h +++ b/src/gui/setup_audio.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/setup_colors.cpp b/src/gui/setup_colors.cpp index 108067f5..073bbc1a 100644 --- a/src/gui/setup_colors.cpp +++ b/src/gui/setup_colors.cpp @@ -2,7 +2,7 @@ * Configurable text colors * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> * - * This file is part of Aethyra. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -57,7 +57,7 @@ Setup_Colors::Setup_Colors() : mScroll = new ScrollArea(mColorBox); mScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - mTextPreview = new TextPreview(&rawmsg); + mTextPreview = new TextPreview(rawmsg); mPreview = new BrowserBox(BrowserBox::AUTO_WRAP); mPreview->setOpaque(false); @@ -83,7 +83,7 @@ Setup_Colors::Setup_Colors() : mRedLabel = new Label(_("Red: ")); - mRedText = new TextField(); + mRedText = new TextField; mRedText->setWidth(40); mRedText->setRange(0, 255); mRedText->setNumeric(true); @@ -99,7 +99,7 @@ Setup_Colors::Setup_Colors() : mGreenLabel = new Label(_("Green: ")); - mGreenText = new TextField(); + mGreenText = new TextField; mGreenText->setWidth(40); mGreenText->setRange(0, 255); mGreenText->setNumeric(true); @@ -115,7 +115,7 @@ Setup_Colors::Setup_Colors() : mBlueLabel = new Label(_("Blue: ")); - mBlueText = new TextField(); + mBlueText = new TextField; mBlueText->setWidth(40); mBlueText->setRange(0, 255); mBlueText->setNumeric(true); diff --git a/src/gui/setup_colors.h b/src/gui/setup_colors.h index 00f77d57..52d3f727 100644 --- a/src/gui/setup_colors.h +++ b/src/gui/setup_colors.h @@ -2,7 +2,7 @@ * Configurable text colors * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> * - * This file is part of Aethyra. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/setup_joystick.cpp b/src/gui/setup_joystick.cpp index 4d80e0dd..59a882c7 100644 --- a/src/gui/setup_joystick.cpp +++ b/src/gui/setup_joystick.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/setup_joystick.h b/src/gui/setup_joystick.h index ae888206..eba8a2cc 100644 --- a/src/gui/setup_joystick.h +++ b/src/gui/setup_joystick.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/setup_keyboard.cpp b/src/gui/setup_keyboard.cpp index 0f79e3c6..aba8cf35 100644 --- a/src/gui/setup_keyboard.cpp +++ b/src/gui/setup_keyboard.cpp @@ -1,9 +1,9 @@ /* - * Aethyra - * Copyright (C) 2007 The Mana World Development Team + * Custom keyboard shortcuts configuration + * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au> + * Copyright (C) 2009 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -69,7 +69,7 @@ class KeyListModel : public gcn::ListModel }; Setup_Keyboard::Setup_Keyboard(): - mKeyListModel(new KeyListModel()), + mKeyListModel(new KeyListModel), mKeyList(new ListBox(mKeyListModel)), mKeySetting(false) { diff --git a/src/gui/setup_keyboard.h b/src/gui/setup_keyboard.h index 5fa961ae..dee12135 100644 --- a/src/gui/setup_keyboard.h +++ b/src/gui/setup_keyboard.h @@ -1,9 +1,8 @@ /* - * Aethyra - * Copyright (C) 2007 The Mana World Development Team + * Custom keyboard shortcuts configuration + * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au> * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/setup_players.cpp b/src/gui/setup_players.cpp index 05748000..1451e71e 100644 --- a/src/gui/setup_players.cpp +++ b/src/gui/setup_players.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2008 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -69,9 +68,9 @@ static const char *RELATION_NAMES[PlayerRelation::RELATIONS_NR] = class PlayerRelationListModel : public gcn::ListModel { public: - virtual ~PlayerRelationListModel(void) { } + virtual ~PlayerRelationListModel() { } - virtual int getNumberOfElements(void) + virtual int getNumberOfElements() { return PlayerRelation::RELATIONS_NR; } @@ -87,30 +86,30 @@ public: class PlayerTableModel : public TableModel { public: - PlayerTableModel(void) : + PlayerTableModel() : mPlayers(NULL) { playerRelationsUpdated(); } - virtual ~PlayerTableModel(void) + virtual ~PlayerTableModel() { freeWidgets(); if (mPlayers) delete mPlayers; } - virtual int getRows(void) + virtual int getRows() { return mPlayers->size(); } - virtual int getColumns(void) + virtual int getColumns() { return COLUMNS_NR; } - virtual int getRowHeight(void) + virtual int getRowHeight() { return ROW_HEIGHT; } @@ -123,7 +122,7 @@ public: return RELATION_CHOICE_COLUMN_WIDTH; } - virtual void playerRelationsUpdated(void) + virtual void playerRelationsUpdated() { signalBeforeUpdate(); @@ -139,10 +138,10 @@ public: std::string name = (*player_names)[r]; gcn::Widget *widget = new Label(name); mWidgets.push_back(widget); - gcn::ListModel *playerRelation = new PlayerRelationListModel(); + gcn::ListModel *playerRelation = new PlayerRelationListModel; gcn::DropDown *choicebox = new DropDown(playerRelation, - new ScrollArea(), + new ScrollArea, new ListBox(playerRelation), false); choicebox->setSelected(player_relations.getRelation(name)); @@ -167,7 +166,7 @@ public: return mWidgets[WIDGET_AT(row, column)]; } - virtual void freeWidgets(void) + virtual void freeWidgets() { if (mPlayers) delete mPlayers; @@ -198,9 +197,9 @@ protected: class IgnoreChoicesListModel : public gcn::ListModel { public: - virtual ~IgnoreChoicesListModel(void) { } + virtual ~IgnoreChoicesListModel() { } - virtual int getNumberOfElements(void) + virtual int getNumberOfElements() { return player_relations.getPlayerIgnoreStrategies()->size(); } @@ -220,7 +219,7 @@ public: Setup_Players::Setup_Players(): mPlayerTableTitleModel(new StaticTableModel(1, COLUMNS_NR)), - mPlayerTableModel(new PlayerTableModel()), + mPlayerTableModel(new PlayerTableModel), mPlayerTable(new GuiTable(mPlayerTableModel)), mPlayerTitleTable(new GuiTable(mPlayerTableTitleModel)), mPlayerScrollArea(new ScrollArea(mPlayerTable)), @@ -240,8 +239,8 @@ Setup_Players::Setup_Players(): RELATION_CHOICE_COLUMN_WIDTH); mPlayerTitleTable->setBackgroundColor(gcn::Color(0xbf, 0xbf, 0xbf)); - gcn::ListModel *ignoreChoices = new IgnoreChoicesListModel(); - mIgnoreActionChoicesBox = new DropDown(ignoreChoices, new ScrollArea(), + gcn::ListModel *ignoreChoices = new IgnoreChoicesListModel; + mIgnoreActionChoicesBox = new DropDown(ignoreChoices, new ScrollArea, new ListBox(ignoreChoices), false); for (int i = 0; i < COLUMNS_NR; i++) @@ -294,7 +293,7 @@ Setup_Players::Setup_Players(): setDimension(gcn::Rectangle(0, 0, 325, 280)); } -Setup_Players::~Setup_Players(void) +Setup_Players::~Setup_Players() { player_relations.removeListener(this); } diff --git a/src/gui/setup_players.h b/src/gui/setup_players.h index 23a994a0..72d81f71 100644 --- a/src/gui/setup_players.h +++ b/src/gui/setup_players.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2008 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp index e181f744..07f073db 100644 --- a/src/gui/setup_video.cpp +++ b/src/gui/setup_video.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -109,6 +108,7 @@ Setup_Video::Setup_Video(): mFullScreenEnabled(config.getValue("screen", false)), mOpenGLEnabled(config.getValue("opengl", false)), mCustomCursorEnabled(config.getValue("customcursor", true)), + mVisibleNamesEnabled(config.getValue("visiblenames", 1)), mParticleEffectsEnabled(config.getValue("particleeffects", true)), mNameEnabled(config.getValue("showownname", false)), mPickupChatEnabled(config.getValue("showpickupchat", true)), @@ -121,8 +121,13 @@ Setup_Video::Setup_Video(): mFsCheckBox(new CheckBox(_("Full screen"), mFullScreenEnabled)), mOpenGLCheckBox(new CheckBox(_("OpenGL"), mOpenGLEnabled)), mCustomCursorCheckBox(new CheckBox(_("Custom cursor"), mCustomCursorEnabled)), + mVisibleNamesCheckBox(new CheckBox(_("Visible names"), mVisibleNamesEnabled)), mParticleEffectsCheckBox(new CheckBox(_("Particle effects"), mParticleEffectsEnabled)), mNameCheckBox(new CheckBox(_("Show name"), mNameEnabled)), + mPickupNotifyLabel(new Label(_("Show pickup notification"))), + mPickupChatCheckBox(new CheckBox(_("in chat"), mPickupChatEnabled)), + mPickupParticleCheckBox(new CheckBox(_("as particle"), + mPickupParticleEnabled)), mSpeechSlider(new Slider(0, 3)), mSpeechLabel(new Label("")), mAlphaSlider(new Slider(0.2, 1.0)), @@ -140,11 +145,7 @@ Setup_Video::Setup_Video(): mOverlayDetailField(new Label("")), mParticleDetail(3 - (int) config.getValue("particleEmitterSkip", 1)), mParticleDetailSlider(new Slider(0, 3)), - mParticleDetailField(new Label("")), - mPickupNotifyLabel(new Label(_("Show pickup notification"))), - mPickupChatCheckBox(new CheckBox(_("in chat"), mPickupChatEnabled)), - mPickupParticleCheckBox(new CheckBox(_("as particle"), - mPickupParticleEnabled)) + mParticleDetailField(new Label("")) { setOpaque(false); @@ -176,6 +177,7 @@ Setup_Video::Setup_Video(): mModeList->setActionEventId("videomode"); mCustomCursorCheckBox->setActionEventId("customcursor"); + mVisibleNamesCheckBox->setActionEventId("visiblenames"); mParticleEffectsCheckBox->setActionEventId("particleeffects"); mPickupChatCheckBox->setActionEventId("pickupchat"); mPickupParticleCheckBox->setActionEventId("pickupparticle"); @@ -195,6 +197,7 @@ Setup_Video::Setup_Video(): mModeList->addActionListener(this); mCustomCursorCheckBox->addActionListener(this); + mVisibleNamesCheckBox->addActionListener(this); mParticleEffectsCheckBox->addActionListener(this); mPickupChatCheckBox->addActionListener(this); mPickupParticleCheckBox->addActionListener(this); @@ -275,7 +278,8 @@ Setup_Video::Setup_Video(): place(1, 0, mFsCheckBox, 2); place(3, 0, mOpenGLCheckBox, 1); place(1, 1, mCustomCursorCheckBox, 3); - place(1, 2, mNameCheckBox, 3); + place(1, 2, mVisibleNamesCheckBox, 3); + place(3, 2, mNameCheckBox, 1); place(1, 3, mParticleEffectsCheckBox, 3); place(1, 4, mPickupNotifyLabel, 3); place(1, 5, mPickupChatCheckBox, 1); @@ -320,7 +324,7 @@ void Setup_Video::apply() * See http://libsdl.org/cgi/docwiki.cgi/SDL_SetVideoMode */ -#ifdef WIN32 +#if defined(WIN32) || defined(__APPLE__) // checks for opengl usage if (!(config.getValue("opengl", false) == 1)) { @@ -338,7 +342,7 @@ void Setup_Video::apply() logger->error(error.str()); } } -#ifdef WIN32 +#if defined(WIN32) || defined(__APPLE__) } else { @@ -365,6 +369,7 @@ void Setup_Video::apply() // We sync old and new values at apply time mFullScreenEnabled = config.getValue("screen", false); mCustomCursorEnabled = config.getValue("customcursor", true); + mVisibleNamesEnabled = config.getValue("visiblenames", 1); mParticleEffectsEnabled = config.getValue("particleeffects", true); mNameEnabled = config.getValue("showownname", false); mSpeechMode = (int) config.getValue("speech", 3); @@ -400,6 +405,7 @@ void Setup_Video::cancel() mFsCheckBox->setSelected(mFullScreenEnabled); mOpenGLCheckBox->setSelected(mOpenGLEnabled); mCustomCursorCheckBox->setSelected(mCustomCursorEnabled); + mVisibleNamesCheckBox->setSelected(mVisibleNamesEnabled); mParticleEffectsCheckBox->setSelected(mParticleEffectsEnabled); mSpeechSlider->setValue(mSpeechMode); mNameCheckBox->setSelected(mNameEnabled); @@ -414,6 +420,7 @@ void Setup_Video::cancel() config.setValue("screen", mFullScreenEnabled ? true : false); config.setValue("customcursor", mCustomCursorEnabled ? true : false); + config.setValue("visiblenames", mVisibleNamesEnabled ? 1 : 0); config.setValue("particleeffects", mParticleEffectsEnabled ? true : false); config.setValue("speech", mSpeechMode); config.setValue("showownname", mNameEnabled ? true : false); @@ -450,6 +457,11 @@ void Setup_Video::action(const gcn::ActionEvent &event) config.setValue("customcursor", mCustomCursorCheckBox->isSelected() ? true : false); } + else if (event.getId() == "visiblenames") + { + config.setValue("visiblenames", + mVisibleNamesCheckBox->isSelected() ? 1 : 0); + } else if (event.getId() == "particleeffects") { config.setValue("particleeffects", diff --git a/src/gui/setup_video.h b/src/gui/setup_video.h index b491cf23..62b46646 100644 --- a/src/gui/setup_video.h +++ b/src/gui/setup_video.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -43,14 +42,13 @@ class Setup_Video : public SetupTab, public gcn::ActionListener, void keyPressed(gcn::KeyEvent &event); private: - void updateSliders(bool originalValues); - int updateSlider(gcn::Slider *slider, gcn::TextField *field, const std::string &configName); bool mFullScreenEnabled; bool mOpenGLEnabled; bool mCustomCursorEnabled; + bool mVisibleNamesEnabled; bool mParticleEffectsEnabled; bool mNameEnabled; bool mPickupChatEnabled; @@ -72,9 +70,14 @@ class Setup_Video : public SetupTab, public gcn::ActionListener, gcn::CheckBox *mFsCheckBox; gcn::CheckBox *mOpenGLCheckBox; gcn::CheckBox *mCustomCursorCheckBox; + gcn::CheckBox *mVisibleNamesCheckBox; gcn::CheckBox *mParticleEffectsCheckBox; gcn::CheckBox *mNameCheckBox; + gcn::Label *mPickupNotifyLabel; + gcn::CheckBox *mPickupChatCheckBox; + gcn::CheckBox *mPickupParticleCheckBox; + gcn::Slider *mSpeechSlider; gcn::Label *mSpeechLabel; gcn::Slider *mAlphaSlider; @@ -97,10 +100,6 @@ class Setup_Video : public SetupTab, public gcn::ActionListener, int mParticleDetail; gcn::Slider *mParticleDetailSlider; gcn::Label *mParticleDetailField; - - gcn::Label *mPickupNotifyLabel; - gcn::CheckBox *mPickupChatCheckBox; - gcn::CheckBox *mPickupParticleCheckBox; }; #endif diff --git a/src/gui/setuptab.h b/src/gui/setuptab.h index 7e1bc36f..3e0c51e2 100644 --- a/src/gui/setuptab.h +++ b/src/gui/setuptab.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/shop.cpp b/src/gui/shop.cpp index bd676bc0..4799ea42 100644 --- a/src/gui/shop.cpp +++ b/src/gui/shop.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,9 +19,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "shop.h" +#include "gui/shop.h" -#include "../utils/dtor.h" +#include "shopitem.h" + +#include "utils/dtor.h" ShopItems::ShopItems(bool mergeDuplicates) : mMergeDuplicates(mergeDuplicates) @@ -44,9 +45,15 @@ std::string ShopItems::getElementAt(int i) return mShopItems.at(i)->getDisplayName(); } +void ShopItems::addItem(int id, int amount, int price) +{ + mShopItems.push_back(new ShopItem(-1, id, amount, price)); +} + +#ifdef EATHENA_SUPPORT void ShopItems::addItem(int inventoryIndex, int id, int quantity, int price) { - ShopItem* item = 0; + ShopItem *item = 0; if (mMergeDuplicates) { item = findItem(id); @@ -62,13 +69,9 @@ void ShopItems::addItem(int inventoryIndex, int id, int quantity, int price) mShopItems.push_back(item); } } +#endif -void ShopItems::addItem(int id, int price) -{ - addItem(-1, id, 0, price); -} - -ShopItem* ShopItems::at(int i) const +ShopItem *ShopItems::at(int i) const { return mShopItems.at(i); } @@ -84,7 +87,7 @@ void ShopItems::clear() mShopItems.clear(); } -ShopItem* ShopItems::findItem(int id) +ShopItem *ShopItems::findItem(int id) { ShopItem *item; diff --git a/src/gui/shop.h b/src/gui/shop.h index 118847f9..190ef655 100644 --- a/src/gui/shop.h +++ b/src/gui/shop.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,15 +19,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _SHOP_H -#define _SHOP_H - -#include <string> -#include <vector> +#ifndef SHOP_H +#define SHOP_H #include <guichan/listmodel.hpp> -#include "../shopitem.h" +#include <string> +#include <vector> class ShopItem; @@ -45,18 +42,21 @@ class ShopItems : public gcn::ListModel { public: /** - * Constructor. Creates a new ShopItems instance. + * Constructor. * * @param mergeDuplicates lets the Shop look for duplicate entries and * merges them to one item. */ ShopItems(bool mergeDuplicates = false); + ~ShopItems(); + /** - * Destructor. + * Adds an item to the list. */ - ~ShopItems(); + void addItem(int id, int amount, int price); +#ifdef EATHENA_SUPPORT /** * Adds an item to the list (used by sell dialog). Looks for * duplicate entries, if mergeDuplicates was turned on. @@ -67,20 +67,10 @@ class ShopItems : public gcn::ListModel * @param price price of the item */ void addItem(int inventoryIndex, int id, int amount, int price); - - /** - * Adds an item to the list (used by buy dialog). Looks for - * duplicate entries, if mergeDuplicates was turned on. - * - * @param id the id of the item - * @param price price of the item - */ - void addItem(int id, int price); +#endif /** * Returns the number of items in the shop. - * - * @return the number of items in the shop */ int getNumberOfElements(); @@ -94,7 +84,7 @@ class ShopItems : public gcn::ListModel /** * Returns the item number i in the shop. */ - ShopItem* at(int i) const; + ShopItem *at(int i) const; /** * Removes an element from the shop. @@ -104,7 +94,7 @@ class ShopItems : public gcn::ListModel void erase(int i); /** - * Clear the vector. + * Clears the list of items in the shop. */ void clear(); @@ -115,13 +105,13 @@ class ShopItems : public gcn::ListModel * * @return the item found or 0 */ - ShopItem* findItem(int id); + ShopItem *findItem(int id); - /** the shop storage */ + /** The list of items in the shop. */ std::vector<ShopItem*> mShopItems; - /** Look for duplicate entries on addition */ + /** Look for duplicate entries on addition. */ bool mMergeDuplicates; }; -#endif +#endif // SHOP_H diff --git a/src/gui/shoplistbox.cpp b/src/gui/shoplistbox.cpp index 5c55069f..db39e82d 100644 --- a/src/gui/shoplistbox.cpp +++ b/src/gui/shoplistbox.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,15 +19,16 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <guichan/font.hpp> -#include <guichan/listmodel.hpp> +#include "gui/palette.h" +#include "gui/shop.h" +#include "gui/shoplistbox.h" -#include "palette.h" -#include "shop.h" -#include "shoplistbox.h" +#include "configuration.h" +#include "graphics.h" +#include "shopitem.h" -#include "../configuration.h" -#include "../graphics.h" +#include <guichan/font.hpp> +#include <guichan/listmodel.hpp> const int ITEM_ICON_SIZE = 32; diff --git a/src/gui/shoplistbox.h b/src/gui/shoplistbox.h index bed9902b..0b28b2f1 100644 --- a/src/gui/shoplistbox.h +++ b/src/gui/shoplistbox.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -89,4 +88,4 @@ class ShopListBox : public ListBox bool mPriceCheck; }; -#endif +#endif // SHOPLISTBOX_H diff --git a/src/gui/shortcutcontainer.cpp b/src/gui/shortcutcontainer.cpp index fcb33279..901095e5 100644 --- a/src/gui/shortcutcontainer.cpp +++ b/src/gui/shortcutcontainer.cpp @@ -1,9 +1,8 @@ /* - * Aethyra - * Copyright 2007 The Mana World Development Team + * The Mana World + * Copyright (C) 2007 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/shortcutcontainer.h b/src/gui/shortcutcontainer.h index 3f2e1c60..7b09fb96 100644 --- a/src/gui/shortcutcontainer.h +++ b/src/gui/shortcutcontainer.h @@ -1,9 +1,8 @@ /* - * Aethyra - * Copyright 2007 The Mana World Development Team + * The Mana World + * Copyright (C) 2007 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,8 +19,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef SHORTCUTCONTAINER_H__ -#define SHORTCUTCONTAINER_H__ +#ifndef SHORTCUTCONTAINER_H +#define SHORTCUTCONTAINER_H #include <guichan/mouselistener.hpp> #include <guichan/widget.hpp> diff --git a/src/gui/shortcutwindow.cpp b/src/gui/shortcutwindow.cpp index 8342465a..dcc7f72e 100644 --- a/src/gui/shortcutwindow.cpp +++ b/src/gui/shortcutwindow.cpp @@ -1,9 +1,8 @@ /* - * Aethyra - * Copyright 2007 The Mana World Development Team + * The Mana World + * Copyright (C) 2007 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/shortcutwindow.h b/src/gui/shortcutwindow.h index d79fffd2..eae881ba 100644 --- a/src/gui/shortcutwindow.h +++ b/src/gui/shortcutwindow.h @@ -1,9 +1,8 @@ /* - * Aethyra - * Copyright 2007 The Mana World Development Team + * The Mana World + * Copyright (C) 2007 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/skill.cpp b/src/gui/skill.cpp index 9fbae7a6..39ccbb06 100644 --- a/src/gui/skill.cpp +++ b/src/gui/skill.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -46,11 +45,14 @@ struct SkillInfo bool modifiable; }; -static const SkillInfo fakeSkillInfo = { _("???"), false }; +static const SkillInfo fakeSkillInfo = { + _("Mystery Skill"), + false +}; std::vector<SkillInfo> skill_db; -static void initSkillinfo(void); +static void initSkillinfo(); class SkillGuiTableModel : public StaticTableModel { @@ -76,12 +78,12 @@ public: return 35; } - virtual int getRowHeight(void) + virtual int getRowHeight() { return 12; } - virtual void update(void) + virtual void update() { mEntriesNr = mDialog->getSkills().size(); resize(); @@ -113,7 +115,6 @@ public: } } - private: SkillDialog *mDialog; int mEntriesNr; @@ -132,7 +133,7 @@ SkillDialog::SkillDialog(): mTable->setActionEventId("skill"); mTable->addActionListener(this); - setWindowName(_("Skills")); + setWindowName("Skills"); setCloseButton(true); setDefaultSize(255, 260, ImageRect::CENTER); @@ -155,7 +156,7 @@ SkillDialog::SkillDialog(): Layout &layout = getLayout(); layout.setRowHeight(0, Layout::AUTO_SET); - setLocationRelativeTo(getParent()); + center(); loadWindowState(); } @@ -234,7 +235,7 @@ bool SkillDialog::hasSkill(int id) void SkillDialog::addSkill(int id, int lvl, int mp) { - SKILL *tmp = new SKILL(); + SKILL *tmp = new SKILL; tmp->id = id; tmp->lv = lvl; tmp->sp = mp; @@ -255,11 +256,11 @@ void SkillDialog::setSkill(int id, int lvl, int mp) void SkillDialog::cleanList() { - for_each(mSkillList.begin(), mSkillList.end(), make_dtor(mSkillList)); + delete_all(mSkillList); mSkillList.clear(); } -static void initSkillinfo(void) +static void initSkillinfo() { SkillInfo emptySkillInfo = { "", false }; diff --git a/src/gui/skill.h b/src/gui/skill.h index bcdd515c..0600d106 100644 --- a/src/gui/skill.h +++ b/src/gui/skill.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -66,7 +65,7 @@ class SkillDialog : public Window, public gcn::ActionListener void setSkill(int id, int lv, int sp); void cleanList(); - const std::vector<SKILL*>& getSkills(void) const { return mSkillList; } + const std::vector<SKILL*>& getSkills() const { return mSkillList; } private: GuiTable *mTable; diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp new file mode 100644 index 00000000..e30299d4 --- /dev/null +++ b/src/gui/skilldialog.cpp @@ -0,0 +1,318 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <guichan/widgets/label.hpp> +#include <guichan/widgets/container.hpp> +#include <guichan/widgets/icon.hpp> + +#include "skilldialog.h" + +#include "icon.h" +#include "button.h" +#include "listbox.h" +#include "scrollarea.h" +#include "windowcontainer.h" +#include "progressbar.h" + +#include "widgets/tabbedarea.h" + +#include "../localplayer.h" + +#include "../utils/dtor.h" +#include "../utils/gettext.h" +#include "../utils/stringutils.h" + +class Skill_Tab : public GCContainer, public gcn::ActionListener +{ + public: + /** + * The type of this skill tab + */ + const std::string type; + + /** + * Constructor + */ + Skill_Tab(const std::string &type); + + /** + * Update this tab + */ + void update(); + + /** + * Called when receiving actions from widget. + */ + void action(const gcn::ActionEvent &event) {} + + private: + /** + * Update the information of a skill at + * the given index + */ + void updateSkill(int index); + + /** + * Gets the number of skills in this particular + * type of tab. + */ + int getSkillNum(); + + /** + * Get the first enumeration of this skill tab's + * skill type. + */ + int getSkillBegin(); + + /** + * Get the icon associated with the given index + */ + Icon* getIcon(int index); + + std::vector<Icon *> mSkillIcons; + std::vector<gcn::Label *> mSkillNameLabels; + std::vector<gcn::Label *> mSkillLevelLabels; + std::vector<gcn::Label *> mSkillExpLabels; + std::vector<ProgressBar *> mSkillProgress; +}; + + +SkillDialog::SkillDialog(): + Window(_("Skills")) +{ + setWindowName("Skills"); + setCloseButton(true); + setDefaultSize(windowContainer->getWidth() - 280, 30, 275, 425); + + TabbedArea *panel = new TabbedArea(); + panel->setDimension(gcn::Rectangle(5, 5, 270, 420)); + + Skill_Tab *tab; + + // Add each type of skill tab to the panel + tab = new Skill_Tab("Weapon"); + panel->addTab(_("Weapons"), tab); + mTabs.push_back(tab); + + tab = new Skill_Tab("Magic"); + panel->addTab(_("Magic"), tab); + mTabs.push_back(tab); + + tab = new Skill_Tab("Craft"); + panel->addTab(_("Crafts"), tab); + mTabs.push_back(tab); + + add(panel); + + update(); + + setLocationRelativeTo(getParent()); + loadWindowState(); +} + +SkillDialog::~SkillDialog() +{ + delete_all(mTabs); +} + +void SkillDialog::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "skill") + { + } + else if (event.getId() == "close") + { + setVisible(false); + } +} + +void SkillDialog::draw(gcn::Graphics *g) +{ + update(); + + Window::draw(g); +} + +void SkillDialog::update() +{ + for(std::list<Skill_Tab*>::const_iterator i = mTabs.begin(); + i != mTabs.end(); ++i) + { + (*i)->update(); + } +} + +Skill_Tab::Skill_Tab(const std::string &type): type(type) +{ + setOpaque(false); + setDimension(gcn::Rectangle(0, 0, 270, 420)); + int skillNum = getSkillNum(); + + mSkillIcons.resize(skillNum); + mSkillNameLabels.resize(skillNum); + mSkillLevelLabels.resize(skillNum); + mSkillExpLabels.resize(skillNum); + mSkillProgress.resize(skillNum); + + // Set the initial positions of the skill information + for (int a=0; a < skillNum; a++) + { + mSkillIcons.at(a) = getIcon(a); + mSkillIcons.at(a)->setPosition(1, a*32); + add(mSkillIcons.at(a)); + + mSkillNameLabels.at(a) = new gcn::Label(""); + mSkillNameLabels.at(a)->setPosition(35, a*32 ); + add(mSkillNameLabels.at(a)); + + mSkillProgress.at(a) = new ProgressBar(0.0f, 200, 20, 150, 150, 150); + mSkillProgress.at(a)->setPosition(35, a*32 + 13); + add(mSkillProgress.at(a)); + + mSkillExpLabels.at(a) = new gcn::Label(""); + mSkillExpLabels.at(a)->setPosition(45, a*32 + 16); + add(mSkillExpLabels.at(a)); + + mSkillLevelLabels.at(a) = new gcn::Label(""); + mSkillLevelLabels.at(a)->setPosition(165, a*32); + add(mSkillLevelLabels.at(a)); + } + + update(); + +} + +int Skill_Tab::getSkillNum() +{ + int skillNum = 0; + + if (type == "Weapon") + { + skillNum = CHAR_SKILL_WEAPON_NB; + return skillNum; + } + else if (type == "Magic") + { + skillNum = CHAR_SKILL_MAGIC_NB; + return skillNum; + } + else if (type == "Craft") + { + skillNum = CHAR_SKILL_CRAFT_NB; + return skillNum; + } + else return skillNum; +} + +int Skill_Tab::getSkillBegin() +{ + int skillBegin = 0; + + if (type == "Weapon") + { + skillBegin = CHAR_SKILL_WEAPON_BEGIN - CHAR_SKILL_BEGIN; + return skillBegin; + } + else if (type == "Magic") + { + skillBegin = CHAR_SKILL_MAGIC_BEGIN - CHAR_SKILL_BEGIN; + return skillBegin; + } + else if (type == "Craft") + { + skillBegin = CHAR_SKILL_CRAFT_BEGIN - CHAR_SKILL_BEGIN; + return skillBegin; + } + else return skillBegin; +} + +Icon* Skill_Tab::getIcon(int index) +{ + int skillBegin = getSkillBegin(); + std::string icon = LocalPlayer::getSkillInfo(index + skillBegin).icon; + return new Icon(icon); +} + +void Skill_Tab::updateSkill(int index) +{ + int skillBegin = getSkillBegin(); + + int baseLevel = player_node->getAttributeBase(index + + skillBegin + + CHAR_SKILL_BEGIN); + + int effLevel = player_node->getAttributeEffective(index + + skillBegin + + CHAR_SKILL_BEGIN); + if(baseLevel <= 0) + { + mSkillProgress.at(index)->setVisible(false); + mSkillExpLabels.at(index)->setVisible(false); + mSkillLevelLabels.at(index)->setVisible(false); + mSkillNameLabels.at(index)->setVisible(false); + mSkillIcons.at(index)->setVisible(false); + } + else + { + mSkillProgress.at(index)->setVisible(true); + mSkillExpLabels.at(index)->setVisible(true); + mSkillLevelLabels.at(index)->setVisible(true); + mSkillNameLabels.at(index)->setVisible(true); + mSkillIcons.at(index)->setVisible(true); + std::string skillLevel("Lvl: " + toString(baseLevel)); + if (effLevel < baseLevel) + { + skillLevel.append(" - " + toString(baseLevel - effLevel)); + } + else if (effLevel > baseLevel) + { + skillLevel.append(" + " + toString(effLevel - baseLevel)); + } + mSkillLevelLabels.at(index)->setCaption(skillLevel); + + std::pair<int, int> exp = player_node->getExperience(index + skillBegin); + std::string sExp (toString(exp.first) + " / " + toString(exp.second)); + + + mSkillNameLabels.at(index)->setCaption(LocalPlayer::getSkillInfo(index + skillBegin).name); + mSkillNameLabels.at(index)->adjustSize(); + mSkillLevelLabels.at(index)->adjustSize(); + mSkillExpLabels.at(index)->setCaption(sExp); + mSkillExpLabels.at(index)->adjustSize(); + mSkillExpLabels.at(index)->setAlignment(gcn::Graphics::RIGHT); + + // More intense red as exp grows + int color = 150 - (int)(150 * ((float) exp.first / exp.second)); + mSkillProgress.at(index)->setColor(244, color, color); + mSkillProgress.at(index)->setProgress((float) exp.first / exp.second); + } +} + +void Skill_Tab::update() +{ + int skillNum = getSkillNum(); + + // Update the skill information for reach skill + for (int a = 0; a < skillNum; a++) + { + updateSkill(a); + } +} diff --git a/src/gui/skilldialog.h b/src/gui/skilldialog.h new file mode 100644 index 00000000..b79be800 --- /dev/null +++ b/src/gui/skilldialog.h @@ -0,0 +1,79 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef SKILL_H +#define SKILL_H + +#include <vector> +#include <list> + +#include <guichan/listmodel.hpp> +#include <guichan/actionlistener.hpp> + +#include "window.h" +#include "gccontainer.h" + +#include "../guichanfwd.h" + +class ProgressBar; +class Icon; +class Skill_Tab; + +/** + * The skill dialog. + * + * \ingroup Interface + */ +class SkillDialog : public Window, public gcn::ActionListener +{ + public: + /** + * Constructor. + */ + SkillDialog(); + + /** + * Destructor. + */ + ~SkillDialog(); + + /** + * Called when receiving actions from widget. + */ + void action(const gcn::ActionEvent &event); + + /** + * Update the tabs in this dialog + */ + void update(); + + /** + * Draw this window. + */ + void draw(gcn::Graphics *g); + + private: + std::list<Skill_Tab*> mTabs; +}; + +extern SkillDialog *skillDialog; + +#endif diff --git a/src/gui/skin.cpp b/src/gui/skin.cpp index 10b9885a..0d62fea5 100644 --- a/src/gui/skin.cpp +++ b/src/gui/skin.cpp @@ -34,7 +34,7 @@ #include "../utils/strprintf.h" #include "../utils/xml.h" -SkinLoader* skinLoader = NULL; +SkinLoader *skinLoader = NULL; ConfigListener *SkinLoader::skinConfigListener = NULL; class SkinConfigListener : public ConfigListener @@ -46,7 +46,7 @@ class SkinConfigListener : public ConfigListener } }; -Skin::Skin(ImageRect skin, Image* close, std::string filePath, std::string name): +Skin::Skin(ImageRect skin, Image *close, std::string filePath, std::string name): instances(0), mFilePath(filePath), mName(name), @@ -88,7 +88,7 @@ int Skin::getMinHeight() const border.grid[6]->getHeight(); } -Skin* SkinLoader::load(const std::string &filename, +Skin *SkinLoader::load(const std::string &filename, const std::string &defaultPath) { std::string filePath = filename; @@ -214,9 +214,9 @@ Skin* SkinLoader::load(const std::string &filename, delete doc; // Hard-coded for now until we update the above code to look for window buttons. - Image* closeImage = resman->getImage("graphics/gui/close_button.png"); + Image *closeImage = resman->getImage("graphics/gui/close_button.png"); - Skin* skin = new Skin(border, closeImage, filename); + Skin *skin = new Skin(border, closeImage, filename); mSkins[filename] = skin; diff --git a/src/gui/slider.cpp b/src/gui/slider.cpp index a2df59a4..cc381c32 100644 --- a/src/gui/slider.cpp +++ b/src/gui/slider.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/slider.h b/src/gui/slider.h index 35d875db..56ea334a 100644 --- a/src/gui/slider.h +++ b/src/gui/slider.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/speechbubble.cpp b/src/gui/speechbubble.cpp index cd483c30..4fb3409c 100644 --- a/src/gui/speechbubble.cpp +++ b/src/gui/speechbubble.cpp @@ -1,9 +1,9 @@ /* - * Aethyra - * Copyright (C) 2008, The Legend of Mazzeroth Development Team + * Speech bubbles + * Copyright (C) 2008 The Legend of Mazzeroth Development Team + * Copyright (C) 2008 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Legend of Mazzeroth. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,18 +34,17 @@ #include "../utils/gettext.h" SpeechBubble::SpeechBubble(): - Popup("Speech", "graphics/gui/speechbubble.xml"), - mText("") + Popup("Speech", "graphics/gui/speechbubble.xml") { setContentSize(140, 46); setMinWidth(29); setMinHeight(29); - mCaption = new gcn::Label(""); + mCaption = new gcn::Label; mCaption->setFont(boldFont); mCaption->setPosition(5, 3); - mSpeechBox = new TextBox(); + mSpeechBox = new TextBox; mSpeechBox->setEditable(false); mSpeechBox->setOpaque(false); mSpeechBox->setTextColor(&guiPalette->getColor(Palette::CHAT)); diff --git a/src/gui/speechbubble.h b/src/gui/speechbubble.h index 9eb400fb..3eead884 100644 --- a/src/gui/speechbubble.h +++ b/src/gui/speechbubble.h @@ -1,9 +1,9 @@ /* - * Aethyra - * Copyright (C) 2008, The Legend of Mazzeroth Development Team + * Speech bubbles + * Copyright (C) 2008 The Legend of Mazzeroth Development Team + * Copyright (C) 2008 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Legend of Mazzeroth. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/status.cpp b/src/gui/status.cpp index 8dd32039..2f95f1c8 100644 --- a/src/gui/status.cpp +++ b/src/gui/status.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,6 +28,7 @@ #include "widgets/layout.h" #include "../localplayer.h" +#include "../units.h" #include "../utils/gettext.h" #include "../utils/strprintf.h" @@ -36,9 +36,10 @@ StatusWindow::StatusWindow(LocalPlayer *player): Window(player->getName()), - mPlayer(player) + mPlayer(player), + mCurrency(0) { - setWindowName(_("Status")); + setWindowName("Status"); setCloseButton(true); setDefaultSize(400, 345, ImageRect::CENTER); @@ -48,7 +49,8 @@ StatusWindow::StatusWindow(LocalPlayer *player): mLvlLabel = new Label(strprintf(_("Level: %d"), 0)); mJobLvlLabel = new Label(strprintf(_("Job: %d"), 0)); - mGpLabel = new Label(strprintf(_("Money: %d GP"), 0)); + mGpLabel = new Label(strprintf(_("Money: %s"), + Units::formatCurrency(mCurrency).c_str())); mHpLabel = new Label(_("HP:")); mHpBar = new ProgressBar(1.0f, 80, 15, 0, 171, 34); @@ -77,8 +79,11 @@ StatusWindow::StatusWindow(LocalPlayer *player): mStatsDefenseLabel= new Label(_("Defense:")); mStatsMagicAttackLabel = new Label(_("M.Attack:")); mStatsMagicDefenseLabel = new Label(_("M.Defense:")); + // Gettext flag for next line: xgettext:no-c-format mStatsAccuracyLabel = new Label(_("% Accuracy:")); + // Gettext flag for next line: xgettext:no-c-format mStatsEvadeLabel = new Label(_("% Evade:")); + // Gettext flag for next line: xgettext:no-c-format mStatsReflexLabel = new Label(_("% Reflex:")); mStatsAttackPoints = new Label; @@ -161,42 +166,26 @@ void StatusWindow::update() { // Status Part // ----------- - mLvlLabel->setCaption(strprintf(_("Level: %d"), mPlayer->mLevel)); + mLvlLabel->setCaption(strprintf(_("Level: %d"), mPlayer->getLevel())); mLvlLabel->adjustSize(); mJobLvlLabel->setCaption(strprintf(_("Job: %d"), mPlayer->mJobLevel)); mJobLvlLabel->adjustSize(); - mGpLabel->setCaption(strprintf(_("Money: %d GP"), mPlayer->mGp)); - mGpLabel->adjustSize(); - - mHpBar->setText(toString(mPlayer->mHp) + - "/" + toString(mPlayer->mMaxHp)); - - mMpBar->setText(toString(mPlayer->mMp) + - "/" + toString(mPlayer->mMaxMp)); + if (mCurrency != mPlayer->getMoney()) { + mCurrency = mPlayer->getMoney(); + mGpLabel->setCaption(strprintf(_("Money: %s"), + Units::formatCurrency(mCurrency).c_str())); + mGpLabel->adjustSize(); + } - mXpBar->setText(toString(mPlayer->getXp()) + - "/" + toString(mPlayer->mXpForNextLevel)); + updateHPBar(mHpBar, true); - mJobBar->setText(toString(mPlayer->mJobXp) + - "/" + toString(mPlayer->mJobXpForNextLevel)); + updateMPBar(mMpBar, true); - // HP Bar coloration - if (mPlayer->mHp < int(mPlayer->mMaxHp / 3)) - mHpBar->setColor(223, 32, 32); // Red - else if (mPlayer->mHp < int((mPlayer->mMaxHp / 3) * 2)) - mHpBar->setColor(230, 171, 34); // Orange - else - mHpBar->setColor(0, 171, 34); // Green + updateXPBar(mXpBar, false); - mHpBar->setProgress((float) mPlayer->mHp / (float) mPlayer->mMaxHp); - mMpBar->setProgress((float) mPlayer->mMp / (float) mPlayer->mMaxMp); - - mXpBar->setProgress( - (float) mPlayer->getXp() / (float) mPlayer->mXpForNextLevel); - mJobBar->setProgress( - (float) mPlayer->mJobXp / (float) mPlayer->mJobXpForNextLevel); + updateJobBar(mJobBar, false); // Stats Part // ---------- @@ -291,3 +280,84 @@ void StatusWindow::action(const gcn::ActionEvent &event) player_node->raiseAttribute(LocalPlayer::LUK); } } + +void StatusWindow::updateHPBar(ProgressBar *bar, bool showMax) +{ + if (showMax) + bar->setText(toString(player_node->getHp()) + + "/" + toString(player_node->getMaxHp())); + else + bar->setText(toString(player_node->getHp())); + + // HP Bar coloration + if (player_node->getHp() < player_node->getMaxHp() / 3) + { + bar->setColor(223, 32, 32); // Red + } + else if (player_node->getHp() < (player_node->getMaxHp() / 3) * 2) + { + bar->setColor(230, 171, 34); // Orange + } + else + { + bar->setColor(0, 171, 34); // Green + } + + bar->setProgress((float) player_node->getHp() / (float) player_node->getMaxHp()); +} + +void StatusWindow::updateMPBar(ProgressBar *bar, bool showMax) +{ + if (showMax) + bar->setText(toString(player_node->mMp) + + "/" + toString(player_node->mMaxMp)); + else + bar->setText(toString(player_node->mMp)); + + + bar->setProgress((float) player_node->mMp / (float) player_node->mMaxMp); +} + +void StatusWindow::updateXPBar(ProgressBar *bar, bool percent) +{ + if (player_node->mXpForNextLevel == 0) { + bar->setText(_("Max level")); + bar->setProgress(1.0); + } else { + if (percent) + { + float xp = (float) player_node->getXp() / + player_node->mXpForNextLevel; + bar->setText(toString((float) ((int) (xp * 10000.0f)) / 100.0f) + + "%"); + } + else + bar->setText(toString(player_node->getXp()) + + "/" + toString(player_node->mXpForNextLevel)); + + bar->setProgress((float) player_node->getXp() / + (float) player_node->mXpForNextLevel); + } +} + +void StatusWindow::updateJobBar(ProgressBar *bar, bool percent) +{ + if (player_node->mJobXpForNextLevel == 0) { + bar->setText(_("Max level")); + bar->setProgress(1.0); + } else { + if (percent) + { + float xp = (float) player_node->mJobXp / + player_node->mJobXpForNextLevel; + bar->setText(toString((float) ((int) (xp * 10000.0f)) / 100.0f) + + "%"); + } + else + bar->setText(toString(player_node->mJobXp) + + "/" + toString(player_node->mJobXpForNextLevel)); + + bar->setProgress((float) player_node->mJobXp / + (float) player_node->mJobXpForNextLevel); + } +} diff --git a/src/gui/status.h b/src/gui/status.h index 5056f631..1425fe12 100644 --- a/src/gui/status.h +++ b/src/gui/status.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -58,6 +57,11 @@ class StatusWindow : public Window, public gcn::ActionListener */ void update(); + static void updateHPBar(ProgressBar *bar, bool showMax = false); + static void updateMPBar(ProgressBar *bar, bool showMax = false); + static void updateXPBar(ProgressBar *bar, bool percent = true); + static void updateJobBar(ProgressBar *bar, bool percent = true); + private: LocalPlayer *mPlayer; @@ -66,6 +70,7 @@ class StatusWindow : public Window, public gcn::ActionListener */ gcn::Label *mLvlLabel, *mJobLvlLabel; gcn::Label *mGpLabel; + int mCurrency; gcn::Label *mHpLabel, *mMpLabel, *mXpLabel, *mJobLabel; ProgressBar *mHpBar, *mMpBar; ProgressBar *mXpBar, *mJobBar; diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp new file mode 100644 index 00000000..31b2da90 --- /dev/null +++ b/src/gui/statuswindow.cpp @@ -0,0 +1,376 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "statuswindow.h" + +#include <guichan/widgets/label.hpp> + +#include "button.h" +#include "progressbar.h" +#include "windowcontainer.h" + +#include "../localplayer.h" + +#include "../utils/strprintf.h" +#include "../utils/stringutils.h" + +StatusWindow::StatusWindow(LocalPlayer *player): + Window(player->getName()), + mPlayer(player) +{ + setWindowName("Status"); + setResizable(true); + setCloseButton(true); + setDefaultSize((windowContainer->getWidth() - 365) / 2, + (windowContainer->getHeight() - 255) / 2, 365, 275); + loadWindowState(); + + // ---------------------- + // Status Part + // ---------------------- + + mLvlLabel = new gcn::Label("Level:"); + mMoneyLabel = new gcn::Label("Money:"); + + mHpLabel = new gcn::Label("HP:"); + mHpBar = new ProgressBar(1.0f, 80, 15, 0, 171, 34); + mHpValueLabel = new gcn::Label(""); + + int y = 3; + int x = 5; + + mLvlLabel->setPosition(x, y); + x += mLvlLabel->getWidth() + 40; + mMoneyLabel->setPosition(x, y); + + y += mLvlLabel->getHeight() + 5; // Next Row + x = 5; + + mHpLabel->setPosition(x, y); + x += mHpLabel->getWidth() + 5; + mHpBar->setPosition(x, y); + x += mHpBar->getWidth() + 5; + mHpValueLabel->setPosition(x, y); + + y += mHpLabel->getHeight() + 5; // Next Row + x = 5; + + add(mLvlLabel); + add(mMoneyLabel); + add(mHpLabel); + add(mHpValueLabel); + add(mHpBar); + + // ---------------------- + // Stats Part + // ---------------------- + + // Static Labels + gcn::Label *mStatsTitleLabel = new gcn::Label("Stats"); + gcn::Label *mStatsTotalLabel = new gcn::Label("Total"); + + // Derived Stats +/* + mStatsAttackLabel = new gcn::Label("Attack:"); + mStatsDefenseLabel= new gcn::Label("Defense:"); + mStatsMagicAttackLabel = new gcn::Label("M.Attack:"); + mStatsMagicDefenseLabel = new gcn::Label("M.Defense:"); + mStatsAccuracyLabel = new gcn::Label("% Accuracy:"); + mStatsEvadeLabel = new gcn::Label("% Evade:"); + mStatsReflexLabel = new gcn::Label("% Reflex:"); + + mStatsAttackPoints = new gcn::Label(""); + mStatsDefensePoints = new gcn::Label(""); + mStatsMagicAttackPoints = new gcn::Label(""); + mStatsMagicDefensePoints = new gcn::Label(""); + mStatsAccuracyPoints = new gcn::Label("% Accuracy:"); + mStatsEvadePoints = new gcn::Label("% Evade:"); + mStatsReflexPoints = new gcn::Label("% Reflex:"); +*/ + // New labels + for (int i = 0; i < 6; i++) { + mStatsLabel[i] = new gcn::Label(); + mStatsDisplayLabel[i] = new gcn::Label(); + } + mCharacterPointsLabel = new gcn::Label(); + mCorrectionPointsLabel = new gcn::Label(); + + // Set button events Id + mStatsPlus[0] = new Button("+", "STR+", this); + mStatsPlus[1] = new Button("+", "AGI+", this); + mStatsPlus[2] = new Button("+", "DEX+", this); + mStatsPlus[3] = new Button("+", "VIT+", this); + mStatsPlus[4] = new Button("+", "INT+", this); + mStatsPlus[5] = new Button("+", "WIL+", this); + + mStatsMinus[0] = new Button("-", "STR-", this); + mStatsMinus[1] = new Button("-", "AGI-", this); + mStatsMinus[2] = new Button("-", "DEX-", this); + mStatsMinus[3] = new Button("-", "VIT-", this); + mStatsMinus[4] = new Button("-", "INT-", this); + mStatsMinus[5] = new Button("-", "WIL-", this); + + + + // Set position + mStatsTitleLabel->setPosition(mHpLabel->getX(), mHpLabel->getY() + 23 ); + mStatsTotalLabel->setPosition(110, mStatsTitleLabel->getY() + 15); + int totalLabelY = mStatsTotalLabel->getY(); + + for (int i = 0; i < 6; i++) + { + mStatsLabel[i]->setPosition(5, + mStatsTotalLabel->getY() + (i * 23) + 15); + mStatsMinus[i]->setPosition(85, totalLabelY + (i * 23) + 15); + mStatsDisplayLabel[i]->setPosition(125, + totalLabelY + (i * 23) + 15); + mStatsPlus[i]->setPosition(185, totalLabelY + (i * 23) + 15); + } + + mCharacterPointsLabel->setPosition(5, mStatsDisplayLabel[5]->getY() + 25); + mCorrectionPointsLabel->setPosition(5, mStatsDisplayLabel[5]->getY() + 35); +/* + mStatsAttackLabel->setPosition(220, mStatsLabel[0]->getY()); + mStatsDefenseLabel->setPosition(220, mStatsLabel[1]->getY()); + mStatsMagicAttackLabel->setPosition(220, mStatsLabel[2]->getY()); + mStatsMagicDefenseLabel->setPosition(220, mStatsLabel[3]->getY()); + mStatsAccuracyLabel->setPosition(220, mStatsLabel[4]->getY()); + mStatsEvadeLabel->setPosition(220, mStatsLabel[5]->getY()); + mStatsReflexLabel->setPosition(220, mStatsLabel[6]->getY()); + + mStatsAttackPoints->setPosition(310, mStatsLabel[0]->getY()); + mStatsDefensePoints->setPosition(310, mStatsLabel[1]->getY()); + mStatsMagicAttackPoints->setPosition(310, mStatsLabel[2]->getY()); + mStatsMagicDefensePoints->setPosition(310, mStatsLabel[3]->getY()); + mStatsAccuracyPoints->setPosition(310, mStatsLabel[4]->getY()); + mStatsEvadePoints->setPosition(310, mStatsLabel[5]->getY()); + mStatsReflexPoints->setPosition(310, mStatsLabel[6]->getY()); +*/ + // Assemble + add(mStatsTitleLabel); + add(mStatsTotalLabel); + for(int i = 0; i < 6; i++) + { + add(mStatsLabel[i]); + add(mStatsDisplayLabel[i]); + add(mStatsPlus[i]); + add(mStatsMinus[i]); + }/* + add(mStatsAttackLabel); + add(mStatsDefenseLabel); + add(mStatsMagicAttackLabel); + add(mStatsMagicDefenseLabel); + add(mStatsAccuracyLabel); + add(mStatsEvadeLabel); + add(mStatsReflexLabel); + + add(mStatsAttackPoints); + add(mStatsDefensePoints); + add(mStatsMagicAttackPoints); + add(mStatsMagicDefensePoints); + add(mStatsAccuracyPoints); + add(mStatsEvadePoints); + add(mStatsReflexPoints);*/ + + add(mCharacterPointsLabel); + add(mCorrectionPointsLabel); +} + +void StatusWindow::update() +{ + // Status Part + // ----------- + mLvlLabel->setCaption( "Level: " + + toString(mPlayer->getLevel()) + + " (" + + toString(mPlayer->getLevelProgress()) + + "%)"); + mLvlLabel->adjustSize(); + + mMoneyLabel->setCaption("Money: " + toString(mPlayer->getMoney()) + " GP"); + mMoneyLabel->adjustSize(); + + updateHPBar(mHpBar, true); + + // Stats Part + // ---------- + const std::string attrNames[6] = { + "Strength", + "Agility", + "Dexterity", + "Vitality", + "Intelligence", + "Willpower" + }; + int characterPoints = mPlayer->getCharacterPoints(); + int correctionPoints = mPlayer->getCorrectionPoints(); + // Update labels + for (int i = 0; i < 6; i++) + { + mStatsLabel[i]->setCaption(attrNames[i]); + mStatsDisplayLabel[i]->setCaption( + strprintf("%d / %d", + mPlayer->getAttributeEffective(CHAR_ATTR_BEGIN + i), + mPlayer->getAttributeBase(CHAR_ATTR_BEGIN + i))); + + mStatsLabel[i]->adjustSize(); + mStatsDisplayLabel[i]->adjustSize(); + + mStatsPlus[i]->setEnabled(characterPoints); + mStatsMinus[i]->setEnabled(correctionPoints); + } + mCharacterPointsLabel->setCaption("Character Points: " + + toString(characterPoints)); + mCharacterPointsLabel->adjustSize(); + + mCorrectionPointsLabel->setCaption("Correction Points: " + + toString(correctionPoints)); + mCorrectionPointsLabel->adjustSize(); +/* + // Derived Stats Points + + // Attack TODO: Count equipped Weapons and items attack bonuses + mStatsAttackPoints->setCaption( + toString(mPlayer->ATK + mPlayer->ATK_BONUS)); + mStatsAttackPoints->adjustSize(); + + // Defense TODO: Count equipped Armors and items defense bonuses + mStatsDefensePoints->setCaption( + toString(mPlayer->DEF + mPlayer->DEF_BONUS)); + mStatsDefensePoints->adjustSize(); + + // Magic Attack TODO: Count equipped items M.Attack bonuses + mStatsMagicAttackPoints->setCaption( + toString(mPlayer->MATK + mPlayer->MATK_BONUS)); + mStatsMagicAttackPoints->adjustSize(); + + // Magic Defense TODO: Count equipped items M.Defense bonuses + mStatsMagicDefensePoints->setCaption( + toString(mPlayer->MDEF + mPlayer->MDEF_BONUS)); + mStatsMagicDefensePoints->adjustSize(); + + // Accuracy % + mStatsAccuracyPoints->setCaption(toString(mPlayer->HIT)); + mStatsAccuracyPoints->adjustSize(); + + // Evasion % + mStatsEvadePoints->setCaption(toString(mPlayer->FLEE)); + mStatsEvadePoints->adjustSize(); + + // Reflex % + mStatsReflexPoints->setCaption(toString(mPlayer->DEX / 4)); // + counter + mStatsReflexPoints->adjustSize(); +*/ + // Update Second column widgets position + mMoneyLabel->setPosition(mLvlLabel->getX() + mLvlLabel->getWidth() + 20, + mLvlLabel->getY()); + +} + +void StatusWindow::draw(gcn::Graphics *g) +{ + update(); + + Window::draw(g); +} + +void StatusWindow::action(const gcn::ActionEvent &event) +{ + const std::string &eventId = event.getId(); + + // Stats Part + if (eventId == "STR+") + { + mPlayer->raiseAttribute(LocalPlayer::STR); + } + else if (eventId == "AGI+") + { + mPlayer->raiseAttribute(LocalPlayer::AGI); + } + else if (eventId == "DEX+") + { + mPlayer->raiseAttribute(LocalPlayer::DEX); + } + else if (eventId == "VIT+") + { + mPlayer->raiseAttribute(LocalPlayer::VIT); + } + else if (eventId == "INT+") + { + mPlayer->raiseAttribute(LocalPlayer::INT); + } + else if (eventId == "WIL+") + { + mPlayer->raiseAttribute(LocalPlayer::WIL); + } + + else if (eventId == "STR-") + { + mPlayer->lowerAttribute(LocalPlayer::STR); + } + else if (eventId == "AGI-") + { + mPlayer->lowerAttribute(LocalPlayer::AGI); + } + else if (eventId == "DEX-") + { + mPlayer->lowerAttribute(LocalPlayer::DEX); + } + else if (eventId == "VIT-") + { + mPlayer->lowerAttribute(LocalPlayer::VIT); + } + else if (eventId == "INT-") + { + mPlayer->lowerAttribute(LocalPlayer::INT); + } + else if (eventId == "WIL-") + { + mPlayer->lowerAttribute(LocalPlayer::WIL); + } +} + +// WARNING: Duplicated method! + +void StatusWindow::updateHPBar(ProgressBar *bar, bool showMax) +{ + if (showMax) + bar->setText(toString(player_node->getHp()) + + "/" + toString(player_node->getMaxHp())); + else + bar->setText(toString(player_node->getHp())); + + // HP Bar coloration + if (player_node->getHp() < player_node->getMaxHp() / 3) + { + bar->setColor(223, 32, 32); // Red + } + else if (player_node->getHp() < (player_node->getMaxHp() / 3) * 2) + { + bar->setColor(230, 171, 34); // Orange + } + else + { + bar->setColor(0, 171, 34); // Green + } + + bar->setProgress((float) player_node->getHp() / (float) player_node->getMaxHp()); +} diff --git a/src/gui/statuswindow.h b/src/gui/statuswindow.h new file mode 100644 index 00000000..605145d3 --- /dev/null +++ b/src/gui/statuswindow.h @@ -0,0 +1,107 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef STATUS_H +#define STATUS_H + +#include <iosfwd> + +#include <guichan/actionlistener.hpp> + +#include "window.h" + +#include "../guichanfwd.h" + +class LocalPlayer; +class ProgressBar; + + +/** + * The player status dialog. + * + * \ingroup Interface + */ +class StatusWindow : public Window, public gcn::ActionListener +{ + public: + /** + * Constructor. + */ + StatusWindow(LocalPlayer *player); + + /** + * Called when receiving actions from widget. + */ + void action(const gcn::ActionEvent &event); + + /** + * Draw this window + */ + void draw(gcn::Graphics *graphics); + + /** + * Updates this dialog with values from PLAYER_INFO *char_info + */ + void update(); + + static void updateHPBar(ProgressBar *bar, bool showMax = false); + + private: + LocalPlayer *mPlayer; + + /** + * Status Part + */ + gcn::Label *mLvlLabel, *mMoneyLabel, *mHpLabel, *mHpValueLabel; + ProgressBar *mHpBar; + + /** + * Derived Statistics captions + */ +/* + gcn::Label *mStatsAttackLabel, *mStatsDefenseLabel; + gcn::Label *mStatsMagicAttackLabel, *mStatsMagicDefenseLabel; + gcn::Label *mStatsAccuracyLabel, *mStatsEvadeLabel; + gcn::Label *mStatsReflexLabel; + + gcn::Label *mStatsAttackPoints, *mStatsDefensePoints; + gcn::Label *mStatsMagicAttackPoints, *mStatsMagicDefensePoints; + gcn::Label *mStatsAccuracyPoints, *mStatsEvadePoints; + gcn::Label *mStatsReflexPoints; +*/ + /** + * Stats captions. + */ + gcn::Label *mStatsLabel[6]; + gcn::Label *mStatsDisplayLabel[6]; + gcn::Label *mCharacterPointsLabel; + gcn::Label *mCorrectionPointsLabel; + + /** + * Stats buttons. + */ + gcn::Button *mStatsPlus[6]; + gcn::Button *mStatsMinus[6]; +}; + +extern StatusWindow *statusWindow; + +#endif diff --git a/src/gui/storagewindow.cpp b/src/gui/storagewindow.cpp index eb0cbc12..479348aa 100644 --- a/src/gui/storagewindow.cpp +++ b/src/gui/storagewindow.cpp @@ -39,10 +39,12 @@ #include "../inventory.h" #include "../item.h" #include "../localplayer.h" +#include "../units.h" #include "../net/messageout.h" -#include "../net/network.h" -#include "../net/protocol.h" +#ifdef EATHENA_SUPPORT +#include "../net/ea/protocol.h" +#endif #include "../resources/iteminfo.h" @@ -65,7 +67,7 @@ StorageWindow::StorageWindow(Network *network, int invSize): mStoreButton = new Button(_("Store"), "store", this); mRetrieveButton = new Button(_("Retrieve"), "retrieve", this); - mItems = new ItemContainer(player_node->getStorage(), 1); + mItems = new ItemContainer(player_node->getStorage(), 10, 5, 1); mItems->addSelectionListener(this); mInvenScroll = new ScrollArea(mItems); diff --git a/src/gui/storagewindow.h b/src/gui/storagewindow.h index 6a1c2cdb..cc0df2af 100644 --- a/src/gui/storagewindow.h +++ b/src/gui/storagewindow.h @@ -40,7 +40,8 @@ class TextBox; * * \ingroup Interface */ -class StorageWindow : public Window, gcn::ActionListener, gcn::SelectionListener +class StorageWindow : public Window, gcn::ActionListener, + gcn::SelectionListener { public: /** diff --git a/src/gui/table.cpp b/src/gui/table.cpp index 17d8bfbf..ec5b0480 100644 --- a/src/gui/table.cpp +++ b/src/gui/table.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2008 The Mana World Development Team * - * This file is part of Aethyra derived from original code - * from Guichan. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,7 +37,7 @@ class GuiTableActionListener : public gcn::ActionListener public: GuiTableActionListener(GuiTable *_table, gcn::Widget *_widget, int _row, int _column); - virtual ~GuiTableActionListener(void); + virtual ~GuiTableActionListener(); virtual void action(const gcn::ActionEvent& actionEvent); @@ -63,7 +62,7 @@ GuiTableActionListener::GuiTableActionListener(GuiTable *table, gcn::Widget *wid } } -GuiTableActionListener::~GuiTableActionListener(void) +GuiTableActionListener::~GuiTableActionListener() { if (mWidget) { @@ -97,13 +96,13 @@ GuiTable::GuiTable(TableModel *initial_model, gcn::Color background, addKeyListener(this); } -GuiTable::~GuiTable(void) +GuiTable::~GuiTable() { uninstallActionListeners(); delete mModel; } -TableModel* GuiTable::getModel(void) const +TableModel *GuiTable::getModel() const { return mModel; } @@ -126,7 +125,7 @@ void GuiTable::setModel(TableModel *new_model) } } -void GuiTable::recomputeDimensions(void) +void GuiTable::recomputeDimensions() { int rows_nr = mModel->getRows(); int columns_nr = mModel->getColumns(); @@ -154,12 +153,12 @@ void GuiTable::setSelected(int row, int column) mSelectedRow = row; } -int GuiTable::getSelectedRow(void) +int GuiTable::getSelectedRow() { return mSelectedRow; } -int GuiTable::getSelectedColumn(void) +int GuiTable::getSelectedColumn() { return mSelectedColumn; } @@ -169,7 +168,7 @@ void GuiTable::setLinewiseSelection(bool linewise) mLinewiseMode = linewise; } -int GuiTable::getRowHeight(void) +int GuiTable::getRowHeight() { if (mModel) return mModel->getRowHeight() + 1; // border @@ -201,7 +200,7 @@ void GuiTable::setSelectedRow(int selected) { mSelectedRow = 0; } - else if ((selected >= mModel->getRows() && !mWrappingEnabled) || + else if ((selected >= mModel->getRows() && !mWrappingEnabled) || (selected < 0 && mWrappingEnabled)) { mSelectedRow = mModel->getRows() - 1; @@ -226,7 +225,7 @@ void GuiTable::setSelectedColumn(int selected) { mSelectedColumn = 0; } - else if ((selected >= mModel->getColumns() && !mWrappingEnabled) || + else if ((selected >= mModel->getColumns() && !mWrappingEnabled) || (selected < 0 && mWrappingEnabled)) { mSelectedColumn = mModel->getColumns() - 1; @@ -240,11 +239,11 @@ void GuiTable::setSelectedColumn(int selected) void GuiTable::uninstallActionListeners(void) { - delete_all(action_listeners); - action_listeners.clear(); + delete_all(mActionListeners); + mActionListeners.clear(); } -void GuiTable::installActionListeners(void) +void GuiTable::installActionListeners() { if (!mModel) return; @@ -256,7 +255,7 @@ void GuiTable::installActionListeners(void) for (int column = 0; column < columns; ++column) { gcn::Widget *widget = mModel->getElementAt(row, column); - action_listeners.push_back(new GuiTableActionListener(this, widget, + mActionListeners.push_back(new GuiTableActionListener(this, widget, row, column)); } @@ -290,7 +289,7 @@ void GuiTable::draw(gcn::Graphics* graphics) int max_rows_nr = mModel->getRows() - first_row; // clip if neccessary: if (max_rows_nr < rows_nr) rows_nr = max_rows_nr; - + // Now determine the first and last column // Take the easy way out; these are usually bounded and all visible. int first_column = 0; @@ -338,7 +337,6 @@ void GuiTable::draw(gcn::Graphics* graphics) graphics->pushClipArea(bounds); widget->draw(graphics); graphics->popClipArea(); - } x_offset += width; @@ -369,7 +367,7 @@ void GuiTable::moveToBottom(gcn::Widget *widget) mTopWidget = NULL; } -gcn::Rectangle GuiTable::getChildrenArea(void) +gcn::Rectangle GuiTable::getChildrenArea() { return gcn::Rectangle(0, 0, getWidth(), getHeight()); } @@ -459,7 +457,7 @@ void GuiTable::mouseWheelMovedDown(gcn::MouseEvent& mouseEvent) mouseEvent.consume(); } } - + void GuiTable::mouseDragged(gcn::MouseEvent& mouseEvent) { } @@ -479,7 +477,7 @@ void GuiTable::modelUpdated(bool completed) } } -gcn::Widget* GuiTable::getWidgetAt(int x, int y) +gcn::Widget *GuiTable::getWidgetAt(int x, int y) { int row = getRowForY(y); int column = getColumnForX(x); @@ -531,12 +529,13 @@ void GuiTable::_setFocusHandler(gcn::FocusHandler* focusHandler) { gcn::Widget::_setFocusHandler(focusHandler); - if (mModel) - for (int r = 0; r < mModel->getRows(); ++r) - for (int c = 0; c < mModel->getColumns(); ++c) - { + if (mModel) { + for (int r = 0; r < mModel->getRows(); ++r) { + for (int c = 0; c < mModel->getColumns(); ++c) { gcn::Widget *w = mModel->getElementAt(r, c); if (w) w->_setFocusHandler(focusHandler); } + } + } } diff --git a/src/gui/table.h b/src/gui/table.h index a508d0e4..d73cf340 100644 --- a/src/gui/table.h +++ b/src/gui/table.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2008 The Mana World Development Team * - * This file is part of Aethyra derived from original code - * from Guichan. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,17 +46,19 @@ class GuiTable : public gcn::Widget, public gcn::KeyListener, public TableModelListener { - friend class GuiTableActionListener; // so that the action listener can call distributeActionEvent + // so that the action listener can call distributeActionEvent + friend class GuiTableActionListener; + public: GuiTable(TableModel * initial_model = NULL, gcn::Color background = 0xffffff, bool opacity = true); - virtual ~GuiTable(void); + virtual ~GuiTable(); /** * Retrieves the active table model */ - TableModel *getModel(void) const; + TableModel *getModel() const; /** * Sets the table model @@ -73,9 +74,9 @@ public: void setSelected(int row, int column); - int getSelectedRow(void); + int getSelectedRow(); - int getSelectedColumn(void); + int getSelectedColumn(); void setSelectedRow(int selected); @@ -137,25 +138,25 @@ public: virtual void mouseWheelMovedUp(gcn::MouseEvent& mouseEvent); virtual void mouseWheelMovedDown(gcn::MouseEvent& mouseEvent); - + virtual void mouseDragged(gcn::MouseEvent& mouseEvent); // Constraints inherited from TableModelListener virtual void modelUpdated(bool); protected: + /** Frees all action listeners on inner widgets. */ + virtual void uninstallActionListeners(); + /** Installs all action listeners on inner widgets. */ + virtual void installActionListeners(); - virtual void uninstallActionListeners(void); // frees all action listeners on inner widgets - virtual void installActionListeners(void); // installs all action listeners on inner widgets - - virtual int getRowHeight(void); + virtual int getRowHeight(); virtual int getColumnWidth(int i); - -private: +private: int getRowForY(int y); // -1 on error int getColumnForX(int x); // -1 on error - void recomputeDimensions(void); + void recomputeDimensions(); bool mLinewiseMode; bool mWrappingEnabled; bool mOpaque; @@ -172,11 +173,14 @@ private: int mSelectedRow; int mSelectedColumn; - int mPopFramesNr; // Number of frames to skip upwards when drawing the selected widget + /** Number of frames to skip upwards when drawing the selected widget. */ + int mPopFramesNr; - gcn::Widget *mTopWidget; // If someone moves a fresh widget to the top, we must display it + /** If someone moves a fresh widget to the top, we must display it. */ + gcn::Widget *mTopWidget; - std::vector<GuiTableActionListener *> action_listeners; // Vector for compactness; used as a list in practice. + /** Vector for compactness; used as a list in practice. */ + std::vector<GuiTableActionListener *> mActionListeners; }; diff --git a/src/gui/table_model.cpp b/src/gui/table_model.cpp index 8998961e..4fa13bae 100644 --- a/src/gui/table_model.cpp +++ b/src/gui/table_model.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2008 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,13 +35,13 @@ void TableModel::removeListener(TableModelListener *listener) listeners.erase(listener); } -void TableModel::signalBeforeUpdate(void) +void TableModel::signalBeforeUpdate() { for (std::set<TableModelListener *>::const_iterator it = listeners.begin(); it != listeners.end(); it++) (*it)->modelUpdated(false); } -void TableModel::signalAfterUpdate(void) +void TableModel::signalAfterUpdate() { for (std::set<TableModelListener *>::const_iterator it = listeners.begin(); it != listeners.end(); it++) (*it)->modelUpdated(true); @@ -61,12 +60,12 @@ StaticTableModel::StaticTableModel(int row, int column) : mWidths.resize(column, 1); } -StaticTableModel::~StaticTableModel(void) +StaticTableModel::~StaticTableModel() { delete_all(mTableModel); } -void StaticTableModel::resize(void) +void StaticTableModel::resize() { mRows = getRows(); mColumns = getColumns(); @@ -98,7 +97,7 @@ void StaticTableModel::set(int row, int column, gcn::Widget *widget) signalAfterUpdate(); } -gcn::Widget* StaticTableModel::getElementAt(int row, int column) +gcn::Widget *StaticTableModel::getElementAt(int row, int column) { return mTableModel[WIDGET_AT(row, column)]; } @@ -120,7 +119,7 @@ void StaticTableModel::fixRowHeight(int height) mHeight = -height; } -int StaticTableModel::getRowHeight(void) +int StaticTableModel::getRowHeight() { return abs(mHeight); } @@ -133,12 +132,12 @@ int StaticTableModel::getColumnWidth(int column) return abs(mWidths[column]); } -int StaticTableModel::getRows(void) +int StaticTableModel::getRows() { return mRows; } -int StaticTableModel::getColumns(void) +int StaticTableModel::getColumns() { return mColumns; } diff --git a/src/gui/table_model.h b/src/gui/table_model.h index 6edd7d65..9ca36120 100644 --- a/src/gui/table_model.h +++ b/src/gui/table_model.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2008 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,8 +29,9 @@ class TableModelListener { public: /** - * Must be invoked by the TableModel whenever a global change is about to occur or - * has occurred (e.g., when a row or column is being removed or added). + * Must be invoked by the TableModel whenever a global change is about to + * occur or has occurred (e.g., when a row or column is being removed or + * added). * * This method is triggered twice, once before and once after the update. * @@ -46,22 +46,22 @@ public: class TableModel { public: - virtual ~TableModel(void) { } + virtual ~TableModel() { } /** * Determines the number of rows (lines) in the table */ - virtual int getRows(void) = 0; + virtual int getRows() = 0; /** * Determines the number of columns in each row */ - virtual int getColumns(void) = 0; + virtual int getColumns() = 0; /** * Determines the height for each row */ - virtual int getRowHeight(void) = 0; + virtual int getRowHeight() = 0; /** * Determines the width of each individual column @@ -81,12 +81,12 @@ protected: /** * Tells all listeners that the table is about to see an update */ - virtual void signalBeforeUpdate(void); + virtual void signalBeforeUpdate(); /** * Tells all listeners that the table has seen an update */ - virtual void signalAfterUpdate(void); + virtual void signalAfterUpdate(); private: std::set<TableModelListener *> listeners; @@ -97,7 +97,7 @@ class StaticTableModel : public TableModel { public: StaticTableModel(int width, int height); - virtual ~StaticTableModel(void); + virtual ~StaticTableModel(); /** * Inserts a widget into the table model. @@ -107,7 +107,8 @@ public: virtual void set(int row, int column, gcn::Widget *widget); /** - * Fixes the column width for a given column; this overrides dynamic width inference. + * Fixes the column width for a given column; this overrides dynamic width + * inference. * * Semantics are undefined for width 0. */ @@ -123,17 +124,16 @@ public: /** * Resizes the table model */ - virtual void resize(void); + virtual void resize(); - virtual int getRows(void); - virtual int getColumns(void); - virtual int getRowHeight(void); - virtual int getWidth(void); - virtual int getHeight(void); + virtual int getRows(); + virtual int getColumns(); + virtual int getRowHeight(); + virtual int getWidth(); + virtual int getHeight(); virtual int getColumnWidth(int index); virtual gcn::Widget *getElementAt(int row, int column); - protected: int mRows, mColumns; int mHeight; diff --git a/src/gui/textbox.cpp b/src/gui/textbox.cpp index 51a8efc6..10f727e3 100644 --- a/src/gui/textbox.cpp +++ b/src/gui/textbox.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/textbox.h b/src/gui/textbox.h index 20f4ebe2..5884e11c 100644 --- a/src/gui/textbox.h +++ b/src/gui/textbox.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/textdialog.cpp b/src/gui/textdialog.cpp new file mode 100644 index 00000000..8c65d64b --- /dev/null +++ b/src/gui/textdialog.cpp @@ -0,0 +1,91 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "textdialog.h" +#include "button.h" + +#include "../utils/gettext.h" + +#include <guichan/widgets/label.hpp> +#include <guichan/widgets/textfield.hpp> + +TextDialog::TextDialog(const std::string &title, const std::string &msg, + Window *parent): + Window(title, true, parent), + mTextField(new TextField) +{ + gcn::Label *textLabel = new gcn::Label(msg); + mOkButton = new Button(_("OK"), "OK", this); + gcn::Button *cancelButton = new Button(_("Cancel"), "CANCEL", this); + + int w = textLabel->getWidth() + 20; + int inWidth = mOkButton->getWidth() + cancelButton->getWidth() + 5; + int h = textLabel->getHeight() + 25 + mOkButton->getHeight() + mTextField->getHeight(); + + if (w < inWidth + 10) + w = inWidth + 10; + + setContentSize(w, h); + textLabel->setPosition(10, 10); + mTextField->setWidth(85); + mTextField->setPosition(10,20 + textLabel->getHeight()); + mOkButton->setPosition((w - inWidth) / 2, + h - 5 - cancelButton->getHeight()); + cancelButton->setPosition(mOkButton->getX() + mOkButton->getWidth() + 5, + h - 5 - cancelButton->getHeight()); + + add(textLabel); + add(mTextField); + add(mOkButton); + add(cancelButton); + + if (getParent()) { + setLocationRelativeTo(getParent()); + getParent()->moveToTop(this); + } + setVisible(true); + mTextField->requestFocus(); +} + +void TextDialog::action(const gcn::ActionEvent &event) +{ + // Proxy button events to our listeners + ActionListenerIterator i; + for (i = mActionListeners.begin(); i != mActionListeners.end(); ++i) + { + (*i)->action(event); + } + + if (event.getId() == "CANCEL" || event.getId() == "OK") + { + scheduleDelete(); + } +} + +const std::string &TextDialog::getText() const +{ + return mTextField->getText(); +} + +void TextDialog::setOKButtonActionId(const std::string &name) +{ + mOkButton->setActionEventId(name); +} diff --git a/src/gui/textdialog.h b/src/gui/textdialog.h new file mode 100644 index 00000000..3dc9259c --- /dev/null +++ b/src/gui/textdialog.h @@ -0,0 +1,66 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef GUI_GUILD_DIALOG_H +#define GUI_GUILD_DIALOG_H + +#include <guichan/actionlistener.hpp> +#include "textfield.h" + +#include "window.h" + +/** +* An option dialog. + * + * \ingroup GUI + */ +class TextDialog : public Window, public gcn::ActionListener +{ +public: + /** + * Constructor. + * + * @see Window::Window + */ + TextDialog(const std::string &title, const std::string &msg, + Window *parent = NULL); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + /** + * Get the text in the textfield + */ + const std::string &getText() const; + + /** + * Set the OK button action id + */ + void setOKButtonActionId(const std::string &name); + +private: + TextField *mTextField; + gcn::Button *mOkButton; +}; + +#endif diff --git a/src/gui/textfield.cpp b/src/gui/textfield.cpp index 257ddaa1..42279fc4 100644 --- a/src/gui/textfield.cpp +++ b/src/gui/textfield.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,7 +39,7 @@ int TextField::instances = 0; float TextField::mAlpha = config.getValue("guialpha", 0.8); ImageRect TextField::skin; -TextField::TextField(const std::string& text): +TextField::TextField(const std::string &text): gcn::TextField(text), mNumeric(false), mListener(0) diff --git a/src/gui/textfield.h b/src/gui/textfield.h index b82912c0..070d86ae 100644 --- a/src/gui/textfield.h +++ b/src/gui/textfield.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,12 +38,13 @@ class TextFieldListener * * \ingroup GUI */ -class TextField : public gcn::TextField { +class TextField : public gcn::TextField +{ public: /** * Constructor, initializes the text field with the given string. */ - TextField(const std::string& text = ""); + TextField(const std::string &text = ""); /** * Destructor. diff --git a/src/gui/textrenderer.h b/src/gui/textrenderer.h index c0f5a0e9..712c1312 100644 --- a/src/gui/textrenderer.h +++ b/src/gui/textrenderer.h @@ -2,7 +2,7 @@ * Text Renderer * Copyright (C) 2009 The Mana World Development Team * - * This file is part of Aethyra based on code from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,17 +35,22 @@ class TextRenderer /** * Renders a specified text. */ - static inline void renderText(gcn::Graphics *graphics, const std::string& - text, int x, int y, gcn::Graphics::Alignment align, - const gcn::Color color, gcn::Font *font, bool outline = false, - bool shadow = false, int alpha = 255) + static inline void renderText(gcn::Graphics *graphics, + const std::string &text, + int x, int y, + gcn::Graphics::Alignment align, + const gcn::Color &color, + gcn::Font *font, + bool outline = false, + bool shadow = false, int alpha = 255) { graphics->setFont(font); // Text shadow if (shadow) { - graphics->setColor(guiPalette->getColor(Palette::SHADOW, alpha / 2)); + graphics->setColor(guiPalette->getColor(Palette::SHADOW, + alpha / 2)); if (outline) { graphics->drawText(text, x + 2, y + 2, align); diff --git a/src/gui/trade.cpp b/src/gui/trade.cpp index 82ac4647..2d80d12d 100644 --- a/src/gui/trade.cpp +++ b/src/gui/trade.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,24 +38,39 @@ #include "../inventory.h" #include "../item.h" #include "../localplayer.h" +#include "../units.h" +#ifdef TMWSERV_SUPPORT +#include "../net/tmwserv/gameserver/player.h" +#else #include "../net/messageout.h" -#include "../net/protocol.h" +#include "../net/ea/protocol.h" +#endif #include "../utils/gettext.h" -#include "../utils/strprintf.h" #include "../utils/stringutils.h" +#include "../utils/strprintf.h" +#ifdef TMWSERV_SUPPORT +TradeWindow::TradeWindow(): +#else TradeWindow::TradeWindow(Network *network): - Window("Trade"), +#endif + Window(_("Trade: You")), +#ifdef EATHENA_SUPPORT mNetwork(network), mMyInventory(new Inventory(INVENTORY_SIZE, 2)), mPartnerInventory(new Inventory(INVENTORY_SIZE, 2)) +#else + mMyInventory(new Inventory(INVENTORY_SIZE)), + mPartnerInventory(new Inventory(INVENTORY_SIZE)), + mStatus(PREPARING) +#endif { - setWindowName(_("Trade")); - setDefaultSize(342, 209, ImageRect::CENTER); + setWindowName("Trade"); setResizable(true); setCloseButton(true); + setDefaultSize(342, 209, ImageRect::CENTER); setMinWidth(342); setMinHeight(209); @@ -65,36 +79,58 @@ TradeWindow::TradeWindow(Network *network): getFont()->getWidth(_("Trade")) ? _("OK") : _("Trade"); - mAddButton = new Button(_("Add"), "add", this); + Button *addButton = new Button(_("Add"), "add", this); +#ifdef EATHENA_SUPPORT mOkButton = new Button(longestName, "ok", this); - - mMyItemContainer = new ItemContainer(mMyInventory.get(), 2); - mMyItemContainer->setWidth(160); +#else + Button *cancelButton = new Button(_("Cancel"), "cancel", this); +#endif + mTradeButton = new Button(_("Propose trade"), "trade", this); + mTradeButton->setWidth(8 + std::max( + mTradeButton->getFont()->getWidth(_("Propose trade")), + mTradeButton->getFont()->getWidth(_("Confirm trade")))); + +#ifdef TMWSERV_SUPPORT + mMyItemContainer = new ItemContainer(mMyInventory.get(), 4, 3, 0); +#else + mMyItemContainer = new ItemContainer(mMyInventory.get(), 4, 3, 2); +#endif mMyItemContainer->addSelectionListener(this); - mMyScroll = new ScrollArea(mMyItemContainer); + ScrollArea *myScroll = new ScrollArea(mMyItemContainer); - mPartnerItemContainer = new ItemContainer(mPartnerInventory.get(), 2); - mPartnerItemContainer->setWidth(160); +#ifdef TMWSERV_SUPPORT + mPartnerItemContainer = new ItemContainer(mPartnerInventory.get(), 4, 3, 0); +#else + mPartnerItemContainer = new ItemContainer(mPartnerInventory.get(), 4, 3, 2); +#endif mPartnerItemContainer->addSelectionListener(this); - mPartnerScroll = new ScrollArea(mPartnerItemContainer); + ScrollArea *partnerScroll = new ScrollArea(mPartnerItemContainer); + + mMoneyLabel = new Label(strprintf(_("You get %s."), "")); + gcn::Label *mMoneyLabel2 = new Label(_("You give:")); - mMoneyLabel = new Label(strprintf(_("You get %d GP."), 0)); - mMoneyLabel2 = new Label(_("You give:")); mMoneyField = new TextField; - mMoneyField->setWidth(50); + mMoneyField->setWidth(40); + Button *moneyChange = new Button(_("Change"), "money", this); place(1, 0, mMoneyLabel); - place(0, 1, mMyScroll).setPadding(3); - place(1, 1, mPartnerScroll).setPadding(3); + place(0, 1, myScroll).setPadding(3); + place(1, 1, partnerScroll).setPadding(3); ContainerPlacer place; place = getPlacer(0, 0); place(0, 0, mMoneyLabel2); place(1, 0, mMoneyField); + place(2, 0, moneyChange).setHAlign(LayoutCell::LEFT); place = getPlacer(0, 2); - place(6, 0, mAddButton); - place(7, 0, mOkButton); + place(0, 0, addButton); +#ifdef EATHENA_SUPPORT + place(1, 0, mOkButton); +#else + place(2, 0, mTradeButton); + place(3, 0, cancelButton); +#endif Layout &layout = getLayout(); layout.extend(0, 2, 2, 1); layout.setRowHeight(1, Layout::AUTO_SET); @@ -102,7 +138,9 @@ TradeWindow::TradeWindow(Network *network): layout.setColWidth(0, Layout::AUTO_SET); layout.setColWidth(1, Layout::AUTO_SET); +#ifdef EATHENA_SUPPORT mOkButton->setCaption(_("OK")); +#endif loadWindowState(); } @@ -111,34 +149,37 @@ TradeWindow::~TradeWindow() { } -void TradeWindow::addMoney(int amount) +void TradeWindow::setMoney(int amount) { - mMoneyLabel->setCaption(strprintf(_("You get %d GP."), amount)); + mMoneyLabel->setCaption(strprintf(_("You get %s."), + Units::formatCurrency(amount).c_str())); mMoneyLabel->adjustSize(); +#ifdef TMWSERV_SUPPORT + setStatus(PREPARING); +#endif +} + +#ifdef TMWSERV_SUPPORT +void TradeWindow::addItem(int id, bool own, int quantity) +{ + (own ? mMyInventory : mPartnerInventory)->addItem(id, quantity); + setStatus(PREPARING); } +#endif +#ifdef EATHENA_SUPPORT void TradeWindow::addItem(int id, bool own, int quantity, bool equipment) { if (own) { - mMyItemContainer->setWidth(mMyScroll->getWidth()); mMyInventory->addItem(id, quantity, equipment); } else { - mPartnerItemContainer->setWidth(mPartnerScroll->getWidth()); mPartnerInventory->addItem(id, quantity, equipment); } } -void TradeWindow::removeItem(int id, bool own) -{ - if (own) - mMyInventory->removeItem(id); - else - mPartnerInventory->removeItem(id); -} - void TradeWindow::changeQuantity(int index, bool own, int quantity) { if (own) @@ -154,21 +195,36 @@ void TradeWindow::increaseQuantity(int index, bool own, int quantity) else mPartnerInventory->getItem(index)->increaseQuantity(quantity); } +#endif void TradeWindow::reset() { mMyInventory->clear(); mPartnerInventory->clear(); +#ifdef EATHENA_SUPPORT mOkButton->setCaption(_("OK")); mOkButton->setActionEventId("ok"); mOkButton->setEnabled(true); mOkOther = false; mOkMe = false; - mMoneyLabel->setCaption(strprintf(_("You get %d GP."), 0)); +#endif + mMoneyLabel->setCaption(strprintf(_("You get %s."), "")); mMoneyField->setEnabled(true); mMoneyField->setText(""); +#ifdef TMWSERV_SUPPORT + setStatus(PREPARING); +#endif } +#ifdef TMWSERV_SUPPORT + +void TradeWindow::receivedOk() +{ + setStatus(ACCEPTING); +} + +#else + void TradeWindow::receivedOk(bool own) { if (own) @@ -191,8 +247,15 @@ void TradeWindow::receivedOk(bool own) } } +#endif + void TradeWindow::tradeItem(Item *item, int quantity) { +#ifdef TMWSERV_SUPPORT + Net::GameServer::Player::tradeItem(item->getInvIndex(), quantity); + addItem(item->getId(), true, quantity); + item->increaseQuantity(-quantity); +#else // TODO: Our newer version of eAthena doesn't register this following // function. Detect the actual server version, and re-enable this // for that version only. @@ -201,6 +264,7 @@ void TradeWindow::tradeItem(Item *item, int quantity) outMsg.writeInt16(CMSG_TRADE_ITEM_ADD_REQUEST); outMsg.writeInt16(item->getInvIndex()); outMsg.writeInt32(quantity); +#endif } void TradeWindow::valueChanged(const gcn::SelectionEvent &event) @@ -217,6 +281,18 @@ void TradeWindow::valueChanged(const gcn::SelectionEvent &event) mMyItemContainer->selectNone(); } +#ifdef TMWSERV_SUPPORT +void TradeWindow::setStatus(Status s) +{ + if (s == mStatus) return; + mStatus = s; + + mTradeButton->setCaption + (s == PREPARING ? _("Propose trade") : _("Confirm trade")); + mTradeButton->setEnabled(s != PROPOSING); +} +#endif + void TradeWindow::action(const gcn::ActionEvent &event) { Item *item = inventoryWindow->getSelectedItem(); @@ -233,7 +309,7 @@ void TradeWindow::action(const gcn::ActionEvent &event) if (mMyInventory->contains(item)) { - chatWindow->chatLog(_("Failed adding item. You can not " + localChatTab->chatLog(_("Failed adding item. You can not " "overlap one kind of item on the window."), BY_SERVER); return; @@ -248,12 +324,24 @@ void TradeWindow::action(const gcn::ActionEvent &event) // Choose amount of items to trade new ItemAmountWindow(AMOUNT_TRADE_ADD, this, item); } + +#ifdef TMWSERV_SUPPORT + setStatus(PREPARING); +#endif } else if (event.getId() == "cancel") { + setVisible(false); + reset(); + player_node->setTrading(false); +#ifdef TMWSERV_SUPPORT + Net::GameServer::Player::acceptTrade(false); +#else MessageOut outMsg(mNetwork); outMsg.writeInt16(CMSG_TRADE_CANCEL_REQUEST); +#endif } +#ifdef EATHENA_SUPPORT else if (event.getId() == "ok") { std::stringstream tempMoney(mMoneyField->getText()); @@ -275,15 +363,34 @@ void TradeWindow::action(const gcn::ActionEvent &event) MessageOut outMsg(mNetwork); outMsg.writeInt16(CMSG_TRADE_ADD_COMPLETE); } +#endif else if (event.getId() == "trade") { +#ifdef TMWSERV_SUPPORT + Net::GameServer::Player::acceptTrade(true); + setStatus(PROPOSING); +#else MessageOut outMsg(mNetwork); outMsg.writeInt16(CMSG_TRADE_OK); +#endif + } +#ifdef TMWSERV_SUPPORT + else if (event.getId() == "money") + { + int v = atoi(mMoneyField->getText().c_str()); + Net::GameServer::Player::tradeMoney(v); + mMoneyField->setText(strprintf("%d", v)); + setStatus(PREPARING); } +#endif } void TradeWindow::close() { +#ifdef TMWSERV_SUPPORT + Net::GameServer::Player::acceptTrade(false); +#else MessageOut outMsg(mNetwork); outMsg.writeInt16(CMSG_TRADE_CANCEL_REQUEST); +#endif } diff --git a/src/gui/trade.h b/src/gui/trade.h index 76ba5a4c..4c215ba6 100644 --- a/src/gui/trade.h +++ b/src/gui/trade.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,7 +34,9 @@ class Inventory; class Item; class ItemContainer; +#ifdef EATHENA_SUPPORT class Network; +#endif class ScrollArea; /** @@ -49,7 +50,11 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener /** * Constructor. */ +#ifdef TMWSERV_SUPPORT + TradeWindow(); +#else TradeWindow(Network *network); +#endif /** * Destructor. @@ -57,24 +62,25 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener ~TradeWindow(); /** - * Add money to the trade window. + * Displays expected money in the trade window. */ - void addMoney(int quantity); + void setMoney(int quantity); /** * Add an item to the trade window. */ - void addItem(int id, bool own, int quantity, bool equipment); + void addItem(int id, bool own, int quantity); /** - * Remove a item from the trade window. + * Reset both item containers */ - void removeItem(int id, bool own); + void reset(); +#ifdef EATHENA_SUPPORT /** - * Reset both item containers + * Add an item to the trade window. */ - void reset(); + void addItem(int id, bool own, int quantity, bool equipment); /** * Change quantity of an item. @@ -85,11 +91,16 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener * Increase quantity of an item. */ void increaseQuantity(int index, bool own, int quantity); +#endif /** * Player received ok message from server */ +#ifdef TMWSERV_SUPPORT + void receivedOk(); +#else void receivedOk(bool own); +#endif /** * Send trade packet. @@ -114,7 +125,23 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener void close(); private: +#ifdef TMWSERV_SUPPORT + enum Status + { + PREPARING, /**< Players are adding items. */ + PROPOSING, /**< Local player is proposing a trade. */ + ACCEPTING /**< Distant player is proposing a trade. */ + }; + + /** + * Sets the current status of the trade. + */ + void setStatus(Status); +#endif + +#ifdef EATHENA_SUPPORT Network *mNetwork; +#endif typedef const std::auto_ptr<Inventory> InventoryPtr; InventoryPtr mMyInventory; @@ -124,11 +151,18 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener ItemContainer *mPartnerItemContainer; gcn::Label *mMoneyLabel; - gcn::Label *mMoneyLabel2; - gcn::Button *mAddButton, *mOkButton; - ScrollArea *mMyScroll, *mPartnerScroll; + gcn::Button *mTradeButton; +#ifdef EATHENA_SUPPORT + gcn::Button *mAddButton; + gcn::Button *mOkButton; +#endif gcn::TextField *mMoneyField; + +#ifdef TMWSERV_SUPPORT + Status mStatus; +#else bool mOkOther, mOkMe; +#endif }; extern TradeWindow *tradeWindow; diff --git a/src/gui/truetypefont.cpp b/src/gui/truetypefont.cpp index e50fb457..b4b839e9 100644 --- a/src/gui/truetypefont.cpp +++ b/src/gui/truetypefont.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,8 +43,7 @@ class TextChunk bool operator==(const TextChunk &chunk) const { - return ( - chunk.text == text && chunk.color == color); + return (chunk.text == text && chunk.color == color); } void generate(TTF_Font *font) @@ -134,12 +132,12 @@ void TrueTypeFont::drawString(gcn::Graphics *graphics, bool found = false; - for (CacheIterator i = cache.begin(); i != cache.end(); i++) + for (CacheIterator i = mCache.begin(); i != mCache.end(); ++i) { if (chunk == (*i)) { // Raise priority: move it to front - cache.splice(cache.begin(), cache, i); + mCache.splice(mCache.begin(), mCache, i); found = true; break; } @@ -148,19 +146,19 @@ void TrueTypeFont::drawString(gcn::Graphics *graphics, // Surface not found if (!found) { - if (cache.size() >= CACHE_SIZE) + if (mCache.size() >= CACHE_SIZE) { - cache.pop_back(); + mCache.pop_back(); } - cache.push_front(chunk); - cache.front().generate(mFont); + mCache.push_front(chunk); + mCache.front().generate(mFont); } - cache.front().img->setAlpha(alpha); - g->drawImage(cache.front().img, x, y); + mCache.front().img->setAlpha(alpha); + g->drawImage(mCache.front().img, x, y); } -int TrueTypeFont::getWidth(const std::string& text) const +int TrueTypeFont::getWidth(const std::string &text) const { int w, h; TTF_SizeUTF8(mFont, text.c_str(), &w, &h); diff --git a/src/gui/truetypefont.h b/src/gui/truetypefont.h index 085aa226..cbe64368 100644 --- a/src/gui/truetypefont.h +++ b/src/gui/truetypefont.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,8 +26,8 @@ #include <string> #include <guichan/font.hpp> -#ifndef __APPLE__ -#include <SDL/SDL_ttf.h> +#ifdef __APPLE__ +#include <SDL_ttf/SDL_ttf.h> #else #include <SDL_ttf.h> #endif @@ -56,20 +55,22 @@ class TrueTypeFont : public gcn::Font */ ~TrueTypeFont(); - virtual int getWidth(const std::string& text) const; + virtual int getWidth(const std::string &text) const; virtual int getHeight() const; /** * @see Font::drawString */ - void drawString(gcn::Graphics* graphics, const std::string& text, int x, int y); + void drawString(gcn::Graphics *graphics, + const std::string &text, + int x, int y); private: TTF_Font *mFont; // Word surfaces cache - std::list<TextChunk> cache; + std::list<TextChunk> mCache; }; #endif diff --git a/src/gui/unregisterdialog.cpp b/src/gui/unregisterdialog.cpp new file mode 100644 index 00000000..7906afc1 --- /dev/null +++ b/src/gui/unregisterdialog.cpp @@ -0,0 +1,141 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "unregisterdialog.h" + +#include <string> +#include <sstream> + +#include <guichan/widgets/label.hpp> + +#include "../main.h" +#include "../log.h" +#include "../logindata.h" + +#include "button.h" +#include "checkbox.h" +#include "register.h" +#include "passwordfield.h" +#include "textfield.h" +#include "ok_dialog.h" + +#include "../utils/gettext.h" +#include "../utils/strprintf.h" + +UnRegisterDialog::UnRegisterDialog(Window *parent, LoginData *loginData): + Window("Unregister", true, parent), + mWrongDataNoticeListener(new WrongDataNoticeListener()), + mLoginData(loginData) +{ + gcn::Label *userLabel = new gcn::Label(strprintf(_("Name: %s"), mLoginData->username.c_str())); + gcn::Label *passwordLabel = new gcn::Label(_("Password:")); + mPasswordField = new PasswordField(mLoginData->password); + mUnRegisterButton = new Button(_("Unregister"), "unregister", this); + mCancelButton = new Button(_("Cancel"), "cancel", this); + + const int width = 210; + const int height = 80; + setContentSize(width, height); + + userLabel->setPosition(5, 5); + userLabel->setWidth(width - 5); + mPasswordField->setPosition( + 68, userLabel->getY() + userLabel->getHeight() + 7); + mPasswordField->setWidth(130); + + passwordLabel->setPosition(5, mPasswordField->getY() + 1); + + mCancelButton->setPosition( + width - 5 - mCancelButton->getWidth(), + height - 5 - mCancelButton->getHeight()); + mUnRegisterButton->setPosition( + mCancelButton->getX() - 5 - mUnRegisterButton->getWidth(), + mCancelButton->getY()); + + add(userLabel); + add(passwordLabel); + add(mPasswordField); + add(mUnRegisterButton); + add(mCancelButton); + + setLocationRelativeTo(getParent()); + setVisible(true); + mPasswordField->requestFocus(); + mPasswordField->setActionEventId("cancel"); +} + +UnRegisterDialog::~UnRegisterDialog() +{ + delete mWrongDataNoticeListener; +} + +void +UnRegisterDialog::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "cancel") + { + scheduleDelete(); + } + else if (event.getId() == "unregister") + { + const std::string username = mLoginData->username.c_str(); + const std::string password = mPasswordField->getText(); + logger->log("UnregisterDialog::unregistered, Username is %s", + username.c_str()); + + std::stringstream errorMsg; + bool error = false; + + // Check password + if (password.length() < LEN_MIN_PASSWORD) + { + // Pass too short + errorMsg << "The password needs to be at least " + << LEN_MIN_PASSWORD + << " characters long."; + error = true; + } + else if (password.length() > LEN_MAX_PASSWORD - 1 ) + { + // Pass too long + errorMsg << "The password needs to be less than " + << LEN_MAX_PASSWORD + << " characters long."; + error = true; + } + + if (error) + { + mWrongDataNoticeListener->setTarget(this->mPasswordField); + + OkDialog *dlg = new OkDialog("Error", errorMsg.str()); + dlg->addActionListener(mWrongDataNoticeListener); + } + else + { + // No errors detected, unregister the new user. + mUnRegisterButton->setEnabled(false); + mLoginData->password = password; + state = STATE_UNREGISTER_ATTEMPT; + scheduleDelete(); + } + } +} diff --git a/src/gui/unregisterdialog.h b/src/gui/unregisterdialog.h new file mode 100644 index 00000000..1e3cc88f --- /dev/null +++ b/src/gui/unregisterdialog.h @@ -0,0 +1,70 @@ +/* + * The Mana World + * Copyright (C) 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef UNREGISTERDIALOG_H +#define UNREGISTERDIALOG_H + +#include <iosfwd> +#include <guichan/actionlistener.hpp> + +#include "window.h" +#include "../guichanfwd.h" + +class LoginData; +class OkDialog; +class WrongDataNoticeListener; + +/** + * The Unregister dialog. + * + * \ingroup Interface + */ +class UnRegisterDialog : public Window, public gcn::ActionListener { + public: + /** + * Constructor + * + * @see Window::Window + */ + UnRegisterDialog(Window *parent,LoginData *loginData); + + /** + * Destructor + */ + ~UnRegisterDialog(); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + private: + gcn::TextField *mPasswordField; + + gcn::Button *mUnRegisterButton; + gcn::Button *mCancelButton; + + WrongDataNoticeListener *mWrongDataNoticeListener; + + LoginData *mLoginData; +}; + +#endif diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp index 927d6eaf..8c903c28 100644 --- a/src/gui/updatewindow.cpp +++ b/src/gui/updatewindow.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -106,7 +105,7 @@ UpdaterWindow::UpdaterWindow(const std::string &updateHost, { mCurlError[0] = 0; - mBrowserBox = new BrowserBox(); + mBrowserBox = new BrowserBox; mScrollArea = new ScrollArea(mBrowserBox); mLabel = new Label(_("Connecting...")); mProgressBar = new ProgressBar(0.0, 310, 20, 168, 116, 31); @@ -130,7 +129,7 @@ UpdaterWindow::UpdaterWindow(const std::string &updateHost, Layout &layout = getLayout(); layout.setRowHeight(0, Layout::AUTO_SET); - setLocationRelativeTo(getParent()); + center(); setVisible(true); mCancelButton->requestFocus(); @@ -184,7 +183,7 @@ void UpdaterWindow::action(const gcn::ActionEvent &event) } else if (event.getId() == "play") { - state = LOADDATA_STATE; + state = STATE_LOADDATA; } } @@ -231,7 +230,7 @@ int UpdaterWindow::updateProgress(void *ptr, uw->mCurrentFile + " (" + toString((int) (progress * 100)) + "%)"); uw->setProgress(progress); - if (state != UPDATE_STATE || uw->mDownloadStatus == UPDATE_ERROR) + if (state != STATE_UPDATE || uw->mDownloadStatus == UPDATE_ERROR) { // If the action was canceled return an error code to stop the mThread return -1; @@ -359,7 +358,7 @@ int UpdaterWindow::downloadThread(void *ptr) // Remove the corrupted file ::remove(outFilename.c_str()); logger->log( - _("Checksum for file %s failed: (%lx/%lx)"), + "Checksum for file %s failed: (%lx/%lx)", uw->mCurrentFile.c_str(), adler, uw->mCurrentChecksum); attempts++; diff --git a/src/gui/updatewindow.h b/src/gui/updatewindow.h index 234a6f57..ace398b4 100644 --- a/src/gui/updatewindow.h +++ b/src/gui/updatewindow.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,6 +31,8 @@ #include "../utils/mutex.h" +#include "../utils/mutex.h" + class BrowserBox; class Button; class ProgressBar; diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp index 56274573..c840e456 100644 --- a/src/gui/viewport.cpp +++ b/src/gui/viewport.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,12 +19,14 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "ministatus.h" #include "popupmenu.h" #include "viewport.h" #include "../beingmanager.h" #include "../configuration.h" #include "../flooritemmanager.h" +#include "../game.h" #include "../graphics.h" #include "../keyboardconfig.h" #include "../localplayer.h" @@ -50,8 +51,13 @@ Viewport::Viewport(): mTileViewX(0), mTileViewY(0), mShowDebugPath(false), + mVisibleNames(false), mPlayerFollowMouse(false), +#ifdef TMWSERV_SUPPORT + mLocalWalkTime(-1) +#else mWalkTime(0) +#endif { setOpaque(false); addMouseListener(this); @@ -60,16 +66,20 @@ Viewport::Viewport(): mScrollRadius = (int) config.getValue("ScrollRadius", 0); mScrollCenterOffsetX = (int) config.getValue("ScrollCenterOffsetX", 0); mScrollCenterOffsetY = (int) config.getValue("ScrollCenterOffsetY", 0); + mVisibleNames = config.getValue("visiblenames", 1); config.addListener("ScrollLaziness", this); config.addListener("ScrollRadius", this); + config.addListener("visiblenames", this); - mPopupMenu = new PopupMenu(); + mPopupMenu = new PopupMenu; } Viewport::~Viewport() { delete mPopupMenu; + + config.removeListener("visiblenames", this); } void Viewport::setMap(Map *map) @@ -77,6 +87,8 @@ void Viewport::setMap(Map *map) mMap = map; } +extern MiniStatusWindow *miniStatusWindow; + void Viewport::draw(gcn::Graphics *gcnGraphics) { static int lastTick = tick_time; @@ -97,6 +109,14 @@ void Viewport::draw(gcn::Graphics *gcnGraphics) } // Calculate viewpoint +#ifdef TMWSERV_SUPPORT + int midTileX = (graphics->getWidth() + mScrollCenterOffsetX) / 2; + int midTileY = (graphics->getHeight() + mScrollCenterOffsetX) / 2; + + const Vector &playerPos = player_node->getPosition(); + const int player_x = (int) playerPos.x - midTileX; + const int player_y = (int) playerPos.y - midTileY; +#else int midTileX = (graphics->getWidth() + mScrollCenterOffsetX) / 32 / 2; int midTileY = (graphics->getHeight() + mScrollCenterOffsetY) / 32 / 2; @@ -104,6 +124,7 @@ void Viewport::draw(gcn::Graphics *gcnGraphics) player_node->getXOffset(); int player_y = (player_node->mY - midTileY) * 32 + player_node->getYOffset(); +#endif if (mScrollLaziness < 1) mScrollLaziness = 1; // Avoids division by zero @@ -146,8 +167,10 @@ void Viewport::draw(gcn::Graphics *gcnGraphics) }; // Don't move camera so that the end of the map is on screen - int viewXmax = (mMap->getWidth() * 32) - graphics->getWidth(); - int viewYmax = (mMap->getHeight() * 32) - graphics->getHeight(); + const int viewXmax = + mMap->getWidth() * mMap->getTileWidth() - graphics->getWidth(); + const int viewYmax = + mMap->getHeight() * mMap->getTileHeight() - graphics->getHeight(); if (mMap) { if (mPixelViewX < 0) @@ -168,30 +191,13 @@ void Viewport::draw(gcn::Graphics *gcnGraphics) { mMap->draw(graphics, (int) mPixelViewX, (int) mPixelViewY); - // Find a path from the player to the mouse, and draw it. This is for - // debug purposes. - if (mShowDebugPath) - { - // Get the current mouse position - SDL_GetMouseState(&mMouseX, &mMouseY); - - int mouseTileX = mMouseX / 32 + mTileViewX; - int mouseTileY = mMouseY / 32 + mTileViewY; - - Path debugPath = mMap->findPath(player_node->mX, player_node->mY, - mouseTileX, mouseTileY); - - graphics->setColor(gcn::Color(255, 0, 0)); - for (PathIterator i = debugPath.begin(); i != debugPath.end(); i++) - { - int squareX = i->x * 32 - (int) mPixelViewX + 12; - int squareY = i->y * 32 - (int) mPixelViewY + 12; - - graphics->fillRectangle(gcn::Rectangle(squareX, squareY, 8, 8)); - graphics->drawText(toString(mMap->getMetaTile(i->x, i->y)->Gcost), - squareX + 4, squareY + 12, - gcn::Graphics::CENTER); - } + if (mShowDebugPath) { + mMap->drawCollision(graphics, + (int) mPixelViewX, + (int) mPixelViewY); +#if 0 + drawDebugPath(graphics); +#endif } } @@ -215,6 +221,9 @@ void Viewport::draw(gcn::Graphics *gcnGraphics) (*i)->drawEmotion(graphics, (int) mPixelViewX, (int) mPixelViewY); } + if (miniStatusWindow) + miniStatusWindow->drawIcons(graphics); + // Draw contained widgets WindowContainer::draw(gcnGraphics); } @@ -229,11 +238,51 @@ void Viewport::logic() Uint8 button = SDL_GetMouseState(&mMouseX, &mMouseY); if (mPlayerFollowMouse && button & SDL_BUTTON(1) && +#ifdef TMWSERV_SUPPORT + get_elapsed_time(mLocalWalkTime) >= walkingMouseDelay) + { + mLocalWalkTime = tick_time; + player_node->setDestination(mMouseX + (int) mPixelViewX, + mMouseY + (int) mPixelViewY); +#else mWalkTime != player_node->mWalkTime) { player_node->setDestination(mMouseX / 32 + mTileViewX, mMouseY / 32 + mTileViewY); mWalkTime = player_node->mWalkTime; +#endif + } +} + +void Viewport::drawDebugPath(Graphics *graphics) +{ + // Get the current mouse position + SDL_GetMouseState(&mMouseX, &mMouseY); + + const int mouseTileX = (mMouseX + (int) mPixelViewX) / 32; + const int mouseTileY = (mMouseY + (int) mPixelViewY) / 32; + const Vector &playerPos = player_node->getPosition(); + + Path debugPath = mMap->findPath( + (int) playerPos.x / 32, + (int) playerPos.y / 32, + mouseTileX, mouseTileY, 0xFF); + + drawPath(graphics, debugPath); +} + +void Viewport::drawPath(Graphics *graphics, const Path &path) +{ + graphics->setColor(gcn::Color(255, 0, 0)); + for (Path::const_iterator i = path.begin(); i != path.end(); ++i) + { + int squareX = i->x * 32 - (int) mPixelViewX + 12; + int squareY = i->y * 32 - (int) mPixelViewY + 12; + + graphics->fillRectangle(gcn::Rectangle(squareX, squareY, 8, 8)); + graphics->drawText( + toString(mMap->getMetaTile(i->x, i->y)->Gcost), + squareX + 4, squareY + 12, gcn::Graphics::CENTER); } } @@ -249,10 +298,10 @@ void Viewport::mousePressed(gcn::MouseEvent &event) mPlayerFollowMouse = false; - const int tilex = event.getX() / 32 + mTileViewX; - const int tiley = event.getY() / 32 + mTileViewY; - const int x = (int)((float) event.getX() + mPixelViewX); - const int y = (int)((float) event.getY() + mPixelViewY); + const int pixelx = event.getX() + (int) mPixelViewX; + const int pixely = event.getY() + (int) mPixelViewY; + const int tilex = pixelx / mMap->getTileWidth(); + const int tiley = pixely / mMap->getTileHeight(); // Right click might open a popup if (event.getButton() == gcn::MouseEvent::RIGHT) @@ -260,7 +309,7 @@ void Viewport::mousePressed(gcn::MouseEvent &event) Being *being; FloorItem *floorItem; - if ((being = beingManager->findBeingByPixel(x, y)) && + if ((being = beingManager->findBeingByPixel(pixelx, pixely)) && being != player_node) { mPopupMenu->showPopup(event.getX(), event.getY(), being); @@ -284,12 +333,13 @@ void Viewport::mousePressed(gcn::MouseEvent &event) // Left click can cause different actions if (event.getButton() == gcn::MouseEvent::LEFT) { - Being *being; FloorItem *item; +#ifdef EATHENA_SUPPORT + Being *being; // Interact with some being // if ((being = beingManager->findBeing(tilex, tiley))) - if ((being = beingManager->findBeingByPixel(x, y))) + if ((being = beingManager->findBeingByPixel(pixelx, pixely))) { switch (being->getType()) { @@ -320,22 +370,38 @@ void Viewport::mousePressed(gcn::MouseEvent &event) } } // Pick up some item - else if ((item = floorItemManager->findByCoordinates(tilex, tiley))) + else +#endif + if ((item = floorItemManager->findByCoordinates(tilex, tiley))) { player_node->pickUp(item); } // Just walk around else { +#ifdef TMWSERV_SUPPORT + // FIXME: REALLY UGLY! + Uint8 *keys = SDL_GetKeyState(NULL); + if (!(keys[SDLK_LSHIFT] || keys[SDLK_RSHIFT]) && + get_elapsed_time(mLocalWalkTime) >= walkingMouseDelay) + { + mLocalWalkTime = tick_time; + player_node->setDestination(event.getX() + (int) mPixelViewX, + event.getY() + (int) mPixelViewY); + } +#else player_node->stopAttack(); player_node->setDestination(tilex, tiley); +#endif mPlayerFollowMouse = true; } } else if (event.getButton() == gcn::MouseEvent::MIDDLE) { // Find the being nearest to the clicked position - Being *target = beingManager->findBeingByPixel(x, y); + Being *target = beingManager->findNearestLivingBeing( + tilex, tiley, + 20, Being::MONSTER); if (target) player_node->setTarget(target); @@ -347,12 +413,22 @@ void Viewport::mouseDragged(gcn::MouseEvent &event) if (!mMap || !player_node) return; +#ifdef TMWSERV_SUPPORT + if (mPlayerFollowMouse + && get_elapsed_time(mLocalWalkTime) >= walkingMouseDelay) + { + mLocalWalkTime = tick_time; + player_node->setDestination(event.getX() + (int) mPixelViewX, + event.getY() + (int) mPixelViewY); + } +#else if (mPlayerFollowMouse && mWalkTime == player_node->mWalkTime) { int destX = event.getX() / 32 + mTileViewX; int destY = event.getY() / 32 + mTileViewY; player_node->setDestination(destX, destY); } +#endif } void Viewport::mouseReleased(gcn::MouseEvent &event) @@ -369,4 +445,20 @@ void Viewport::optionChanged(const std::string &name) { mScrollLaziness = (int) config.getValue("ScrollLaziness", 32); mScrollRadius = (int) config.getValue("ScrollRadius", 32); + + if (name == "visiblenames") { + mVisibleNames = config.getValue("visiblenames", 1); + } +} + +void Viewport::mouseMoved(gcn::MouseEvent &event) +{ + // Check if we are on the map + if (!mMap || !player_node) + return; + + const int tilex = (event.getX() + (int) mPixelViewX) / 32; + const int tiley = (event.getY() + (int) mPixelViewY) / 32; + + mSelectedBeing = beingManager->findBeing(tilex, tiley); } diff --git a/src/gui/viewport.h b/src/gui/viewport.h index 12fdb187..c051e5a2 100644 --- a/src/gui/viewport.h +++ b/src/gui/viewport.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,6 +29,7 @@ #include "../configlistener.h" #include "../position.h" +class Being; class FloorItem; class Graphics; class ImageSet; @@ -37,6 +37,9 @@ class Item; class Map; class PopupMenu; +/** Delay between two mouse calls when dragging mouse and move the player */ +const int walkingMouseDelay = 500; + /** * The viewport on the map. Displays the current map and handles mouse input * and the popup menu. @@ -95,6 +98,11 @@ class Viewport : public WindowContainer, public gcn::MouseListener, void mouseReleased(gcn::MouseEvent &event); /** + * Handles mouse move on map. + */ + void mouseMoved(gcn::MouseEvent &event); + + /** * Shows a popup for an item. * TODO Find some way to get rid of Item here */ @@ -131,6 +139,17 @@ class Viewport : public WindowContainer, public gcn::MouseListener, void scrollBy(float x, float y) { mPixelViewX += x; mPixelViewY += y; } private: + /** + * Finds a path from the player to the mouse, and draws it. This is for + * debug purposes. + */ + void drawDebugPath(Graphics *graphics); + + /** + * Draws the given path. + */ + void drawPath(Graphics *graphics, const Path &path); + Map *mMap; /**< The current map. */ int mScrollRadius; @@ -144,11 +163,17 @@ class Viewport : public WindowContainer, public gcn::MouseListener, int mTileViewX; /**< Current viewpoint in tiles. */ int mTileViewY; /**< Current viewpoint in tiles. */ bool mShowDebugPath; /**< Show a path from player to pointer. */ + bool mVisibleNames; /**< Show target names. */ bool mPlayerFollowMouse; +#ifdef TMWSERV_SUPPORT + int mLocalWalkTime; /**< Timestamp before the next walk can be sent. */ +#else int mWalkTime; +#endif PopupMenu *mPopupMenu; /**< Popup menu. */ + Being *mSelectedBeing; /**< Current selected being. */ }; extern Viewport *viewport; /**< The viewport */ diff --git a/src/gui/widgets/avatar.cpp b/src/gui/widgets/avatar.cpp new file mode 100644 index 00000000..a36c0302 --- /dev/null +++ b/src/gui/widgets/avatar.cpp @@ -0,0 +1,55 @@ +/* + * The Mana World + * Copyright (C) 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "gui/widgets/avatar.h" + +#include "gui/icon.h" + +#include "resources/image.h" +#include "resources/resourcemanager.h" + +#include <guichan/widgets/label.hpp> + +Avatar::Avatar(const std::string &name): + mName(name) +{ + setSize(110, 12); + mLabel = new gcn::Label(name); + mLabel->setSize(85, 12); + mLabel->setPosition(25, 0); + ResourceManager *resman = ResourceManager::getInstance(); + mStatusOffline = resman->getImage("graphics/gui/circle-gray.png"); + mStatusOnline = resman->getImage("graphics/gui/circle-green.png"); + mStatus = new Icon(mStatusOffline); + mStatus->setSize(25, 12); + mStatus->setPosition(0, 0); +} + +void Avatar::setOnline(bool online) +{ + mStatus->setImage(online ? mStatusOnline : mStatusOffline); +} + +void Avatar::draw(gcn::Graphics *g) +{ + mLabel->draw(g); + mStatus->draw(g); +} diff --git a/src/gui/widgets/avatar.h b/src/gui/widgets/avatar.h new file mode 100644 index 00000000..16972104 --- /dev/null +++ b/src/gui/widgets/avatar.h @@ -0,0 +1,61 @@ +/* + * The Mana World + * Copyright (C) 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef AVATAR_H +#define AVATAR_H + +#include "guichanfwd.h" + +#include <guichan/widget.hpp> + +#include <string> + +class Image; +class Icon; + +class Avatar : public gcn::Widget +{ +public: + /** + * Constructor. + * @param name Character name + */ + Avatar(const std::string &name); + + /** + * Set the avatar online status. + */ + void setOnline(bool online); + + /** + * Draws the avatar. + */ + void draw(gcn::Graphics *g); + +private: + std::string mName; + Icon *mStatus; + Image *mStatusOnline; + Image *mStatusOffline; + gcn::Label *mLabel; +}; + +#endif // AVATAR_H diff --git a/src/gui/widgets/channeltab.cpp b/src/gui/widgets/channeltab.cpp new file mode 100644 index 00000000..f8c92a6e --- /dev/null +++ b/src/gui/widgets/channeltab.cpp @@ -0,0 +1,70 @@ +/* + * The Mana World + * Copyright (C) 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <guichan/widgets/label.hpp> + +#include "channeltab.h" + +#include "../browserbox.h" +#include "../chatinput.h" +#include "../itemlinkhandler.h" +#include "../recorder.h" +#include "../scrollarea.h" + +#include "../../beingmanager.h" +#include "../../commandhandler.h" +#include "../../channel.h" +#include "../../configuration.h" +#include "../../game.h" +#include "../../localplayer.h" + +#ifdef TMWSERV_SUPPORT +#include "../../net/tmwserv/chatserver/chatserver.h" +#include "../../net/tmwserv/gameserver/player.h" +#else +#include "../../party.h" +#include "../../net/messageout.h" +#include "../../net/ea/protocol.h" +#endif + +#include "../../resources/iteminfo.h" +#include "../../resources/itemdb.h" + +#include "../../utils/dtor.h" +#include "../../utils/gettext.h" +#include "../../utils/strprintf.h" +#include "../../utils/stringutils.h" + +ChannelTab::ChannelTab(Channel *channel) : ChatTab(channel->getName()), + mChannel(channel) +{ + channel->setTab(this); +} + +ChannelTab::~ChannelTab() +{ +} + +void ChannelTab::sendChat(std::string &msg) { +#ifdef TMSERV_SUPPORT + Net::ChatServer::chat(getId(), msg); +#endif +} diff --git a/src/gui/widgets/channeltab.h b/src/gui/widgets/channeltab.h new file mode 100644 index 00000000..91b4f7c6 --- /dev/null +++ b/src/gui/widgets/channeltab.h @@ -0,0 +1,57 @@ +/* + * The Mana World + * Copyright (C) 2009 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef CHANNELTAB_H +#define CHANNELTAB_H + +#include "chattab.h" + +class Channel; + +/** + * A tab for a chat channel. + */ +class ChannelTab : public ChatTab +{ + public: + + Channel *getChannel() { return mChannel; } + + protected: + friend class Channel; + + /** + * Constructor. + */ + ChannelTab(Channel *channel); + + /** + * Destructor. + */ + ~ChannelTab(); + + void sendChat(std::string &msg); + + private: + Channel *mChannel; +}; + +#endif // CHANNELTAB_H diff --git a/src/gui/widgets/chattab.cpp b/src/gui/widgets/chattab.cpp new file mode 100644 index 00000000..120d4e21 --- /dev/null +++ b/src/gui/widgets/chattab.cpp @@ -0,0 +1,324 @@ +/* + * The Mana World + * Copyright (C) 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <guichan/widgets/label.hpp> + +#include "chattab.h" +#include "layouthelper.h" + +#include "../browserbox.h" +#include "../chatinput.h" +#include "../itemlinkhandler.h" +#include "../recorder.h" +#include "../scrollarea.h" + +#include "../../commandhandler.h" +#include "../../configuration.h" +#include "../../localplayer.h" + +#ifdef TMWSERV_SUPPORT +#include "../../net/tmwserv/chatserver/chatserver.h" +#include "../../net/tmwserv/gameserver/player.h" +#else +#include "../../net/messageout.h" +#include "../../net/ea/protocol.h" +#endif + +#include "../../resources/iteminfo.h" +#include "../../resources/itemdb.h" + +#include "../../utils/strprintf.h" +#include "../../utils/stringutils.h" + +ChatTab::ChatTab(const std::string &name) : Tab() +{ + setCaption(name); + + mTextOutput = new BrowserBox; + mTextOutput->setOpaque(false); + mTextOutput->setMaxRow((int) config.getValue("ChatLogLength", 0)); + mTextOutput->setLinkHandler(chatWindow->mItemLinkHandler); + + mScrollArea = new ScrollArea(mTextOutput); + mScrollArea->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER, + gcn::ScrollArea::SHOW_ALWAYS); + mScrollArea->setScrollAmount(0, 1); + mScrollArea->setOpaque(false); + + chatWindow->addTab(this); +} + +ChatTab::~ChatTab() +{ + chatWindow->removeTab(this); + delete mTextOutput; + delete mScrollArea; +} + +void ChatTab::chatLog(const char* line, int own, bool ignoreRecord) +{ + chatLog(std::string(line), own, ignoreRecord); +} + +void ChatTab::chatLog(std::string line, int own, bool ignoreRecord) +{ + // Trim whitespace + trim(line); + + if (line.empty()) + return; + + CHATLOG tmp; + tmp.own = own; + tmp.nick = ""; + tmp.text = line; + + std::string::size_type pos = line.find(" : "); + if (pos != std::string::npos) + { + tmp.nick = line.substr(0, pos); + tmp.text = line.substr(pos + 3); + } + else + { + // Fix the owner of welcome message. + if (line.substr(0, 7) == "Welcome") + { + own = BY_SERVER; + } + } + + // *implements actions in a backwards compatible way* + if (own == BY_PLAYER && + tmp.text.at(0) == '*' && + tmp.text.at(tmp.text.length()-1) == '*') + { + tmp.text[0] = ' '; + tmp.text.erase(tmp.text.length() - 1); + own = ACT_IS; + } + + std::string lineColor = "##C"; + switch (own) + { + case BY_GM: + if (tmp.nick.empty()) + { + tmp.nick = std::string(_("Global announcement:")); + tmp.nick += " "; + lineColor = "##G"; + } + else + { + tmp.nick = strprintf(_("Global announcement from %s:"), + tmp.nick.c_str()); + tmp.nick += " "; + lineColor = "##1"; // Equiv. to BrowserBox::RED + } + break; + case BY_PLAYER: + tmp.nick += CAT_NORMAL; + lineColor = "##Y"; + break; + case BY_OTHER: + tmp.nick += CAT_NORMAL; + lineColor = "##C"; + break; + case BY_SERVER: + tmp.nick = _("Server:"); + tmp.nick += " "; + tmp.text = line; + lineColor = "##S"; + break; + case BY_CHANNEL: + tmp.nick = ""; + // TODO: Use a predefined color + lineColor = "##2"; // Equiv. to BrowserBox::GREEN + break; +#ifdef EATHENA_SUPPORT + case BY_PARTY: + tmp.nick += CAT_NORMAL; + lineColor = "##P"; + break; +#endif + case ACT_WHISPER: + tmp.nick = strprintf(_("%s whispers:"), tmp.nick.c_str()); + tmp.nick += " "; + lineColor = "##W"; + break; + case ACT_IS: + tmp.nick += CAT_IS; + lineColor = "##I"; + break; + case BY_LOGGER: + tmp.nick = ""; + tmp.text = line; + lineColor = "##L"; + break; + } + + if (tmp.nick == ": ") + { + tmp.nick = ""; + lineColor = "##S"; + } + +#ifdef EATHENA_SUPPORT + if (tmp.nick.empty() && tmp.text.substr(0, 17) == "Visible GM status") + { + player_node->setGM(); + } +#endif + + // Get the current system time + time_t t; + time(&t); + + // Format the time string properly + std::stringstream timeStr; + timeStr << "[" << ((((t / 60) / 60) % 24 < 10) ? "0" : "") + << (int) (((t / 60) / 60) % 24) + << ":" << (((t / 60) % 60 < 10) ? "0" : "") + << (int) ((t / 60) % 60) + << "] "; + + line = lineColor + timeStr.str() + tmp.nick + tmp.text; + + // We look if the Vertical Scroll Bar is set at the max before + // adding a row, otherwise the max will always be a row higher + // at comparison. + if (mScrollArea->getVerticalScrollAmount() >= mScrollArea->getVerticalMaxScroll()) + { + mTextOutput->addRow(line); + mScrollArea->setVerticalScrollAmount(mScrollArea->getVerticalMaxScroll()); + } + else + { + mTextOutput->addRow(line); + } + + mScrollArea->logic(); + chatWindow->mRecorder->record(line.substr(3)); +} + +void ChatTab::chatLog(std::string &nick, std::string &msg) +{ + chatLog(nick + ": " + msg, nick == player_node->getName() ? BY_PLAYER : BY_OTHER, false); +} + +void ChatTab::chatSend(std::string &msg) +{ + trim(msg); + + if (msg.empty()) return; + +#ifdef EATHENA_SUPPORT + // Send party message + if (msg.at(0) == chatWindow->mPartyPrefix) + { + msg.erase(0, 1); + std::size_t length = msg.length() + 1; + + if (length == 0) + { + chatLog(_("Trying to send a blank party message."), BY_SERVER, true); + return; + } + MessageOut outMsg(chatWindow->mNetwork); + + outMsg.writeInt16(CMSG_PARTY_MESSAGE); + outMsg.writeInt16(length + 4); + outMsg.writeString(msg, length); + return; + } +#endif + + // Check for item link + std::string::size_type start = msg.find('['); + while (start != std::string::npos && msg[start+1] != '@') + { + std::string::size_type end = msg.find(']', start); + if (start+1 != end && end != std::string::npos) + { + // Catch multiple embeds and ignore them + // so it doesn't crash the client. + while ((msg.find('[', start + 1) != std::string::npos) && + (msg.find('[', start + 1) < end)) + { + start = msg.find('[', start + 1); + } + + std::string temp = msg.substr(start + 1, end - start - 1); + + toLower(trim(temp)); + + const ItemInfo itemInfo = ItemDB::get(temp); + if (itemInfo.getName() != _("Unknown item")) + { + msg.insert(end, "@@"); + msg.insert(start+1, "|"); + msg.insert(start+1, toString(itemInfo.getId())); + msg.insert(start+1, "@@"); + } + } + start = msg.find('[', start + 1); + } + + + // Prepare ordinary message + if (msg[0] != '/') + { + sendChat(msg); + } + else + { + commandHandler->handleCommand(std::string(msg, 1)); + } +} + +void ChatTab::scroll(int amount) +{ + int range = mScrollArea->getHeight() / 8 * amount; + gcn::Rectangle scr; + scr.y = mScrollArea->getVerticalScrollAmount() + range; + scr.height = abs(range); + mTextOutput->showPart(scr); +} + +void ChatTab::clearText() +{ + mTextOutput->clearRows(); +} + +void ChatTab::sendChat(std::string &msg) { +#ifdef TMWSERV_SUPPORT + Net::GameServer::Player::say(msg); +#else + msg = player_node->getName() + " : " + msg; + + MessageOut outMsg(chatWindow->mNetwork); + outMsg.writeInt16(CMSG_CHAT_MESSAGE); + // Added + 1 in order to let eAthena parse admin commands correctly + outMsg.writeInt16(msg.length() + 4 + 1); + outMsg.writeString(msg, msg.length() + 1); + return; +#endif +} diff --git a/src/gui/widgets/chattab.h b/src/gui/widgets/chattab.h new file mode 100644 index 00000000..a478abeb --- /dev/null +++ b/src/gui/widgets/chattab.h @@ -0,0 +1,118 @@ +/* + * The Mana World + * Copyright (C) 2009 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef CHATTAB_H +#define CHATTAB_H + +#include <guichan/widgets/container.hpp> + +#include "tab.h" + +#include "../chat.h" + +class BrowserBox; +class Recorder; +class ScrollArea; + +enum +{ + BY_GM, +#ifdef EATHENA_SUPPORT + BY_PARTY, +#endif + BY_PLAYER, + BY_OTHER, + BY_SERVER, + BY_CHANNEL, + ACT_WHISPER, // getting whispered at + ACT_IS, // equivalent to "/me" on IRC + BY_LOGGER +}; + +/** + * A tab for the chat window. This is special to ease chat handling. + */ +class ChatTab : public Tab +{ + public: + /** + * Constructor. + */ + ChatTab(const std::string &name); + + /** + * Destructor. + */ + ~ChatTab(); + + /** + * Adds a line of text to our message list. Parameters: + * + * @param line Text message. + * @param own Type of message (usually the owner-type). + * @param channelName which channel to send the message to. + * @param ignoreRecord should this not be recorded? + */ + void chatLog(std::string line, int own = BY_SERVER, bool ignoreRecord = false); + void chatLog(const char* line, int own = BY_SERVER, bool ignoreRecord = false); + + /** + * Adds the text to the message list + * + * @param msg The message text which is to be sent. + * + */ + void chatLog(std::string &nick, std::string &msg); + + /** + * Determines whether the message is a command or message, then + * sends the given message to the game server to be said, or to the + * command handler + * + * @param msg The message text which is to be sent. + * + */ + void chatSend(std::string &msg); + + /** + * Scrolls the chat window + * + * @param amount direction and amount to scroll. Negative numbers scroll + * up, positive numbers scroll down. The absolute amount indicates the + * amount of 1/8ths of chat window real estate that should be scrolled. + */ + void scroll(int amount); + + void clearText(); + + protected: + friend class ChatWindow; + + virtual void sendChat(std::string &msg); + + ScrollArea *mScrollArea; + BrowserBox *mTextOutput; + //Recorder *mRecorder; +}; + +extern ChatTab *localChatTab; + +#endif // CHATTAB_H diff --git a/src/gui/widgets/dropdown.cpp b/src/gui/widgets/dropdown.cpp index 21fee368..21378772 100644 --- a/src/gui/widgets/dropdown.cpp +++ b/src/gui/widgets/dropdown.cpp @@ -1,9 +1,8 @@ /* - * Aethyra - * Copyright (C) 2008 The Mana World Development Team + * The Mana World + * Copyright (C) 2006 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,28 +19,28 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <algorithm> +#include "gui/widgets/dropdown.h" -#include "dropdown.h" +#include "gui/listbox.h" +#include "gui/palette.h" +#include "gui/scrollarea.h" -#include "../listbox.h" -#include "../palette.h" -#include "../scrollarea.h" +#include "configuration.h" +#include "graphics.h" -#include "../../configuration.h" -#include "../../graphics.h" +#include "resources/image.h" +#include "resources/resourcemanager.h" -#include "../../resources/image.h" -#include "../../resources/resourcemanager.h" +#include "utils/dtor.h" -#include "../../utils/dtor.h" +#include <algorithm> int DropDown::instances = 0; Image *DropDown::buttons[2][2]; ImageRect DropDown::skin; float DropDown::mAlpha = config.getValue("guialpha", 0.8); -DropDown::DropDown(gcn::ListModel *listModel, gcn::ScrollArea *scrollArea, +DropDown::DropDown(gcn::ListModel *listModel, gcn::ScrollArea *scrollArea, gcn::ListBox *listBox, bool opacity): gcn::DropDown::DropDown(listModel, scrollArea, listBox), mOpaque(opacity) diff --git a/src/gui/widgets/dropdown.h b/src/gui/widgets/dropdown.h index 191740d9..601d55c8 100644 --- a/src/gui/widgets/dropdown.h +++ b/src/gui/widgets/dropdown.h @@ -1,9 +1,8 @@ /* - * Aethyra - * Copyright (C) 2008 The Mana World Development Team + * The Mana World + * Copyright (C) 2006 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,15 +27,15 @@ class Image; class ImageRect; - /** - * A drop down box from which you can select different values. It is one of - * the most complicated Widgets you will find in Guichan. For drawing the - * DroppedDown box it uses one ScrollArea and one ListBox. It also uses an - * internal FocusHandler to handle the focus of the internal ScollArea and - * ListBox. DropDown uses a ListModel to handle the list. To be able to use - * DropDown you must give DropDown an implemented ListModel which represents - * your list. - */ +/** + * A drop down box from which you can select different values. It is one of + * the most complicated Widgets you will find in Guichan. For drawing the + * DroppedDown box it uses one ScrollArea and one ListBox. It also uses an + * internal FocusHandler to handle the focus of the internal ScollArea and + * ListBox. DropDown uses a ListModel to handle the list. To be able to use + * DropDown you must give DropDown an implemented ListModel which represents + * your list. + */ class DropDown : public gcn::DropDown { public: @@ -58,9 +57,9 @@ class DropDown : public gcn::DropDown */ ~DropDown(); - void draw(gcn::Graphics* graphics); + void draw(gcn::Graphics *graphics); - void drawFrame(gcn::Graphics* graphics); + void drawFrame(gcn::Graphics *graphics); /** * Sets the widget to be opaque, that is sets the widget to display its @@ -68,7 +67,7 @@ class DropDown : public gcn::DropDown * * @param opaque True if the widget should be opaque, false otherwise. */ - void setOpaque(bool opaque) {mOpaque = opaque;} + void setOpaque(bool opaque) { mOpaque = opaque; } /** * Checks if the widget is opaque, that is if the widget area displays @@ -76,7 +75,7 @@ class DropDown : public gcn::DropDown * * @return True if the widget is opaque, false otherwise. */ - bool isOpaque() const {return mOpaque;} + bool isOpaque() const { return mOpaque; } protected: diff --git a/src/gui/widgets/layout.cpp b/src/gui/widgets/layout.cpp index 7fab91d7..9ca82fa3 100644 --- a/src/gui/widgets/layout.cpp +++ b/src/gui/widgets/layout.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2007 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,9 +19,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <cassert> +#include "gui/widgets/layout.h" -#include "layout.h" +#include <cassert> ContainerPlacer ContainerPlacer::at(int x, int y) { diff --git a/src/gui/widgets/layout.h b/src/gui/widgets/layout.h index 04b75ca5..b9359e91 100644 --- a/src/gui/widgets/layout.h +++ b/src/gui/widgets/layout.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2007 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,10 +22,10 @@ #ifndef WIDGET_LAYOUT_H #define WIDGET_LAYOUT_H -#include <vector> - #include <guichan/widgets/container.hpp> +#include <vector> + class LayoutCell; /** diff --git a/src/gui/widgets/layouthelper.cpp b/src/gui/widgets/layouthelper.cpp index ed002f99..820d2d82 100644 --- a/src/gui/widgets/layouthelper.cpp +++ b/src/gui/widgets/layouthelper.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2009 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "layouthelper.h" +#include "gui/widgets/layouthelper.h" LayoutHelper::LayoutHelper(gcn::Container *container): mContainer(container) diff --git a/src/gui/widgets/layouthelper.h b/src/gui/widgets/layouthelper.h index 1125d209..ddcc6b26 100644 --- a/src/gui/widgets/layouthelper.h +++ b/src/gui/widgets/layouthelper.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2009 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,7 +22,7 @@ #ifndef LAYOUTHELPER_H #define LAYOUTHELPER_H -#include "layout.h" +#include "gui/widgets/layout.h" #include <guichan/widgetlistener.hpp> diff --git a/src/gui/widgets/resizegrip.cpp b/src/gui/widgets/resizegrip.cpp index 3dbf6d1a..1bb33e15 100644 --- a/src/gui/widgets/resizegrip.cpp +++ b/src/gui/widgets/resizegrip.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,15 +19,15 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <guichan/graphics.hpp> +#include "gui/widgets/resizegrip.h" -#include "resizegrip.h" +#include "configuration.h" +#include "graphics.h" -#include "../../configuration.h" -#include "../../graphics.h" +#include "resources/image.h" +#include "resources/resourcemanager.h" -#include "../../resources/image.h" -#include "../../resources/resourcemanager.h" +#include <guichan/graphics.hpp> Image *ResizeGrip::gripImage = 0; int ResizeGrip::mInstances = 0; diff --git a/src/gui/widgets/resizegrip.h b/src/gui/widgets/resizegrip.h index 83af24da..40a40a0f 100644 --- a/src/gui/widgets/resizegrip.h +++ b/src/gui/widgets/resizegrip.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/widgets/tab.cpp b/src/gui/widgets/tab.cpp index 942ad3ef..af31822e 100644 --- a/src/gui/widgets/tab.cpp +++ b/src/gui/widgets/tab.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2008 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,20 +19,21 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <guichan/widgets/label.hpp> +#include "gui/widgets/tab.h" + +#include "gui/widgets/tabbedarea.h" -#include "tab.h" -#include "tabbedarea.h" +#include "gui/palette.h" -#include "../palette.h" +#include "configuration.h" +#include "graphics.h" -#include "../../configuration.h" -#include "../../graphics.h" +#include "resources/image.h" +#include "resources/resourcemanager.h" -#include "../../resources/image.h" -#include "../../resources/resourcemanager.h" +#include "utils/dtor.h" -#include "../../utils/dtor.h" +#include <guichan/widgets/label.hpp> int Tab::mInstances = 0; float Tab::mAlpha = config.getValue("guialpha", 0.8); diff --git a/src/gui/widgets/tab.h b/src/gui/widgets/tab.h index 4b331d66..3af4e2bf 100644 --- a/src/gui/widgets/tab.h +++ b/src/gui/widgets/tab.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2008 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp index 2c454b69..8e93d394 100644 --- a/src/gui/widgets/tabbedarea.cpp +++ b/src/gui/widgets/tabbedarea.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2008 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,8 +19,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "tabbedarea.h" -#include "tab.h" +#include "gui/widgets/tabbedarea.h" +#include "gui/widgets/tab.h" #include <guichan/widgets/container.hpp> @@ -72,7 +71,7 @@ gcn::Widget* TabbedArea::getWidget(const std::string &name) void TabbedArea::addTab(const std::string &caption, gcn::Widget *widget) { - Tab* tab = new Tab(); + Tab* tab = new Tab; tab->setCaption(caption); mTabsToDelete.push_back(tab); diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h index 863ff79e..dffbd36b 100644 --- a/src/gui/widgets/tabbedarea.h +++ b/src/gui/widgets/tabbedarea.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2008 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,6 +23,7 @@ #define TABBEDAREA_H #include <guichan/widget.hpp> +#include <guichan/widgets/container.hpp> #include <guichan/widgets/tabbedarea.hpp> #include <string> @@ -85,9 +85,10 @@ class TabbedArea : public gcn::TabbedArea */ void logic(); + int getContainerHeight() { return mWidgetContainer->getHeight(); } + private: typedef std::vector< std::pair<gcn::Tab*, gcn::Widget*> > TabContainer; }; #endif - diff --git a/src/gui/widgets/textpreview.cpp b/src/gui/widgets/textpreview.cpp index 5408eebe..d0bba285 100644 --- a/src/gui/widgets/textpreview.cpp +++ b/src/gui/widgets/textpreview.cpp @@ -2,7 +2,7 @@ * The Mana World * Copyright (C) 2006 The Mana World Development Team * - * This file is part of Aethyra based on code from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,22 +19,22 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <typeinfo> +#include "gui/widgets/textpreview.h" -#include "textpreview.h" +#include "gui/gui.h" +#include "gui/palette.h" +#include "gui/textrenderer.h" +#include "gui/truetypefont.h" -#include "../gui.h" -#include "../palette.h" -#include "../textrenderer.h" -#include "../truetypefont.h" +#include "configuration.h" -#include "../../configuration.h" +#include <typeinfo> float TextPreview::mAlpha = config.getValue("guialpha", 0.8); -TextPreview::TextPreview(const std::string* text) +TextPreview::TextPreview(const std::string &text): + mText(text) { - mText = text; mTextAlpha = false; mFont = gui->getFont(); mTextColor = &guiPalette->getColor(Palette::TEXT); @@ -65,7 +65,7 @@ void TextPreview::draw(gcn::Graphics* graphics) if (mTextBGColor && typeid(*mFont) == typeid(TrueTypeFont)) { TrueTypeFont *font = static_cast<TrueTypeFont*>(mFont); - int x = font->getWidth(*mText) + 1 + 2 * ((mOutline || mShadow) ? 1 :0); + int x = font->getWidth(mText) + 1 + 2 * ((mOutline || mShadow) ? 1 :0); int y = font->getHeight() + 1 + 2 * ((mOutline || mShadow) ? 1 : 0); graphics->setColor(gcn::Color((int) mTextBGColor->r, (int) mTextBGColor->g, @@ -74,7 +74,7 @@ void TextPreview::draw(gcn::Graphics* graphics) graphics->fillRectangle(gcn::Rectangle(1, 1, x, y)); } - TextRenderer::renderText(graphics, *mText, 2, 2, gcn::Graphics::LEFT, + TextRenderer::renderText(graphics, mText, 2, 2, gcn::Graphics::LEFT, gcn::Color(mTextColor->r, mTextColor->g, mTextColor->b, alpha), mFont, mOutline, mShadow, alpha); diff --git a/src/gui/widgets/textpreview.h b/src/gui/widgets/textpreview.h index 8e116262..0ca343bf 100644 --- a/src/gui/widgets/textpreview.h +++ b/src/gui/widgets/textpreview.h @@ -2,7 +2,7 @@ * The Mana World * Copyright (C) 2006 The Mana World Development Team * - * This file is part of Aethyra based on code from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,14 +32,14 @@ class TextPreview : public gcn::Widget { public: - TextPreview(const std::string* text); + TextPreview(const std::string &text); /** * Sets the color the text is printed in. * * @param color the color to set */ - inline void setTextColor(const gcn::Color* color) + inline void setTextColor(const gcn::Color *color) { mTextColor = color; } @@ -49,7 +49,7 @@ class TextPreview : public gcn::Widget * * @param alpha whether to use alpha values for the text or not */ - inline void useTextAlpha(bool alpha) + inline void useTextAlpha(bool alpha) { mTextAlpha = alpha; } @@ -60,7 +60,7 @@ class TextPreview : public gcn::Widget * * @param color the color to set */ - inline void setTextBGColor(const gcn::Color* color) + inline void setTextBGColor(const gcn::Color *color) { mTextBGColor = color; } @@ -70,7 +70,7 @@ class TextPreview : public gcn::Widget * * @param color the color to set */ - inline void setBGColor(const gcn::Color* color) + inline void setBGColor(const gcn::Color *color) { mBGColor = color; } @@ -124,14 +124,14 @@ class TextPreview : public gcn::Widget * Gets opacity for this widget (whether or not the background color * is shown below the widget) */ - bool isOpaque() { return mOpaque; } + bool isOpaque() const { return mOpaque; } private: gcn::Font *mFont; - const std::string* mText; - const gcn::Color* mTextColor; - const gcn::Color* mBGColor; - const gcn::Color* mTextBGColor; + std::string mText; + const gcn::Color *mTextColor; + const gcn::Color *mBGColor; + const gcn::Color *mTextBGColor; static float mAlpha; bool mTextAlpha; bool mOpaque; diff --git a/src/gui/widgets/whispertab.cpp b/src/gui/widgets/whispertab.cpp new file mode 100644 index 00000000..ba469c00 --- /dev/null +++ b/src/gui/widgets/whispertab.cpp @@ -0,0 +1,78 @@ +/* + * The Mana World + * Copyright (C) 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <guichan/widgets/label.hpp> + +#include "whispertab.h" + +#include "../../beingmanager.h" +#include "../../commandhandler.h" +#include "../../channel.h" +#include "../../configuration.h" +#include "../../game.h" +#include "../../localplayer.h" + +#ifdef TMWSERV_SUPPORT +#include "../../net/tmwserv/chatserver/chatserver.h" +#include "../../net/tmwserv/gameserver/player.h" +#else +#include "../../party.h" +#include "../../net/messageout.h" +#include "../../net/ea/protocol.h" +#endif + +#include "../../resources/iteminfo.h" +#include "../../resources/itemdb.h" + +#include "../../utils/dtor.h" +#include "../../utils/gettext.h" +#include "../../utils/strprintf.h" +#include "../../utils/stringutils.h" + +WhisperTab::WhisperTab(const std::string &nick) : + ChatTab(nick), + mNick(nick) +{ +} + +WhisperTab::~WhisperTab() +{ +} + +void WhisperTab::sendChat(std::string &msg) { + if (msg.length() == 0) { + chatLog(_("Cannot send empty chat!"), BY_SERVER, false); + return; + } + +#ifdef TMWSERV_SUPPORT + Net::ChatServer::privMsg(mNick, msg); +#else + MessageOut outMsg(chatWindow->mNetwork); + outMsg.writeInt16(CMSG_CHAT_WHISPER); + outMsg.writeInt16(msg.length() + 28); + outMsg.writeString(mNick, 24); + outMsg.writeString(msg, msg.length()); +#endif + + chatLog(strprintf(_("%s: %s"), player_node->getName().c_str(), + msg.c_str()), BY_PLAYER, false); +} diff --git a/src/gui/widgets/whispertab.h b/src/gui/widgets/whispertab.h new file mode 100644 index 00000000..e3ebf0f3 --- /dev/null +++ b/src/gui/widgets/whispertab.h @@ -0,0 +1,55 @@ +/* + * The Mana World + * Copyright (C) 2009 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef WHISPERTAB_H +#define WHISPERTAB_H + +#include "chattab.h" + +class Channel; + +/** + * A tab for whispers from a single player. + */ +class WhisperTab : public ChatTab +{ + public: + const std::string &getNick() const { return mNick; } + + protected: + friend class ChatWindow; + + /** + * Constructor. + * + * @param nick the name of the player this tab is whispering to + */ + WhisperTab(const std::string &nick); + + ~WhisperTab(); + + void sendChat(std::string &msg); + + private: + std::string mNick; +}; + +#endif // CHANNELTAB_H diff --git a/src/gui/window.cpp b/src/gui/window.cpp index 476dcd7e..3bc03fb8 100644 --- a/src/gui/window.cpp +++ b/src/gui/window.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,7 +38,7 @@ int Window::instances = 0; int Window::mouseResize = 0; -Window::Window(const std::string& caption, bool modal, Window *parent, const std::string& skin): +Window::Window(const std::string &caption, bool modal, Window *parent, const std::string &skin): gcn::Window(caption), mGrip(0), mParent(parent), @@ -248,7 +247,7 @@ void Window::setResizable(bool r) if (r) { - mGrip = new ResizeGrip(); + mGrip = new ResizeGrip; mGrip->setX(getWidth() - mGrip->getWidth() - getChildrenArea().x); mGrip->setY(getHeight() - mGrip->getHeight() - getChildrenArea().y); add(mGrip); @@ -282,7 +281,7 @@ void Window::setCloseButton(bool flag) mCloseButton = flag; } -bool Window::isResizable() +bool Window::isResizable() const { return mGrip; } @@ -546,6 +545,14 @@ void Window::setDefaultSize(int defaultX, int defaultY, mDefaultHeight = defaultHeight; } +void Window::setDefaultSize() +{ + mDefaultX = getX(); + mDefaultY = getY(); + mDefaultWidth = getWidth(); + mDefaultHeight = getHeight(); +} + void Window::setDefaultSize(int defaultWidth, int defaultHeight, ImageRect::ImagePosition position, int offsetX, int offsetY) @@ -666,3 +673,7 @@ void Window::reflowLayout(int w, int h) setContentSize(w, h); } +void Window::center() +{ + setLocationRelativeTo(getParent()); +} diff --git a/src/gui/window.h b/src/gui/window.h index 8907ead4..c41a4221 100644 --- a/src/gui/window.h +++ b/src/gui/window.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,7 +29,6 @@ #include "../graphics.h" #include "../guichanfwd.h" -class GCContainer; class ContainerPlacer; class Layout; class LayoutCell; @@ -111,46 +109,34 @@ class Window : public gcn::Window, gcn::WidgetListener /** * Returns whether the window can be resized. */ - bool isResizable(); + bool isResizable() const; /** * Sets the minimum width of the window. */ void setMinWidth(int width); + int getMinWidth() const { return mMinWinWidth; } + /** * Sets the minimum height of the window. */ void setMinHeight(int height); + int getMinHeight() const { return mMinWinHeight; } + /** * Sets the maximum width of the window. */ void setMaxWidth(int width); + int getMaxWidth() const { return mMaxWinWidth; } + /** * Sets the minimum height of the window. */ void setMaxHeight(int height); - /** - * Gets the minimum width of the window. - */ - int getMinWidth() const { return mMinWinWidth; } - - /** - * Gets the minimum height of the window. - */ - int getMinHeight() const { return mMinWinHeight; } - - /** - * Gets the maximum width of the window. - */ - int getMaxWidth() const { return mMaxWinWidth; } - - /** - * Gets the minimum height of the window. - */ int getMaxHeight() const { return mMaxWinHeight; } /** @@ -226,7 +212,7 @@ class Window : public gcn::Window, gcn::WidgetListener /** * Returns the name of the window. This is not the window title. */ - const std::string& getWindowName() { return mWindowName; } + const std::string &getWindowName() const { return mWindowName; } /** * Reads the position (and the size for resizable windows) in the @@ -251,6 +237,11 @@ class Window : public gcn::Window, gcn::WidgetListener int defaultWidth, int defaultHeight); /** + * Set the default win pos and size tot he current ones. + */ + void setDefaultSize(); + + /** * Set the default win pos and size. * (which can be different of the actual ones.) * This version of setDefaultSize sets the window's position based @@ -292,6 +283,11 @@ class Window : public gcn::Window, gcn::WidgetListener ContainerPlacer getPlacer(int x, int y); /** + * Positions the window in the center of it's parent. + */ + void center(); + + /** * Overrideable functionality for when the window is to close. This * allows for class implementations to clean up or do certain actions * on window close they couldn't do otherwise. @@ -321,7 +317,6 @@ class Window : public gcn::Window, gcn::WidgetListener */ int getResizeHandles(gcn::MouseEvent &event); - GCContainer *mChrome; /**< Contained container */ ResizeGrip *mGrip; /**< Resize grip */ Window *mParent; /**< The parent window */ Layout *mLayout; /**< Layout handler */ diff --git a/src/gui/windowcontainer.cpp b/src/gui/windowcontainer.cpp index ad86a253..eda739b9 100644 --- a/src/gui/windowcontainer.cpp +++ b/src/gui/windowcontainer.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/gui/windowcontainer.h b/src/gui/windowcontainer.h index 23b221cf..bc918184 100644 --- a/src/gui/windowcontainer.h +++ b/src/gui/windowcontainer.h @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * This file is part of The Mana World. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by |