From 25d77892d72d455f8a89372687db45aefbc61cec Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Mon, 30 Sep 2013 14:03:48 +0300 Subject: move windows classes to windows directory. --- src/gui/windows/charcreatedialog.cpp | 698 +++++++++++++++++++++++++++++++++++ 1 file changed, 698 insertions(+) create mode 100644 src/gui/windows/charcreatedialog.cpp (limited to 'src/gui/windows/charcreatedialog.cpp') diff --git a/src/gui/windows/charcreatedialog.cpp b/src/gui/windows/charcreatedialog.cpp new file mode 100644 index 000000000..53f1a5bce --- /dev/null +++ b/src/gui/windows/charcreatedialog.cpp @@ -0,0 +1,698 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "gui/windows/charcreatedialog.h" + +#include "main.h" + +#include "input/keydata.h" +#include "input/keyevent.h" + +#include "gui/windows/okdialog.h" + +#include "gui/widgets/button.h" +#include "gui/widgets/label.h" +#include "gui/widgets/playerbox.h" +#include "gui/widgets/radiobutton.h" +#include "gui/widgets/slider.h" +#include "gui/widgets/textfield.h" + +#include "net/net.h" + +#include "resources/chardb.h" +#include "resources/colordb.h" +#include "resources/itemdb.h" +#include "resources/iteminfo.h" + +#include "utils/gettext.h" + +#include "debug.h" + +extern int serverVersion; + +static const Being::Action actions[] = +{ + Being::STAND, Being::SIT, Being::MOVE, Being::ATTACK, Being::DEAD +}; + +static const uint8_t directions[] = +{ + Being::DOWN, Being::RIGHT, Being::UP, Being::LEFT +}; + +CharCreateDialog::CharCreateDialog(CharSelectDialog *const parent, + const int slot) : + // TRANSLATORS: char create dialog name + Window(_("New Character"), true, parent, "charcreate.xml"), + gcn::ActionListener(), + gcn::KeyListener(), + mCharSelectDialog(parent), + mNameField(new TextField(this, "")), + // TRANSLATORS: char create dialog label + mNameLabel(new Label(this, _("Name:"))), + // TRANSLATORS: This is a narrow symbol used to denote 'next'. + // You may change this symbol if your language uses another. + // TRANSLATORS: char create dialog button + mNextHairColorButton(new Button(this, _(">"), "nextcolor", this)), + // TRANSLATORS: This is a narrow symbol used to denote 'previous'. + // You may change this symbol if your language uses another. + // TRANSLATORS: char create dialog button + mPrevHairColorButton(new Button(this, _("<"), "prevcolor", this)), + // TRANSLATORS: char create dialog label + mHairColorLabel(new Label(this, _("Hair color:"))), + mHairColorNameLabel(new Label(this, "")), + // TRANSLATORS: char create dialog button + mNextHairStyleButton(new Button(this, _(">"), "nextstyle", this)), + // TRANSLATORS: char create dialog button + mPrevHairStyleButton(new Button(this, _("<"), "prevstyle", this)), + // TRANSLATORS: char create dialog label + mHairStyleLabel(new Label(this, _("Hair style:"))), + mHairStyleNameLabel(new Label(this, "")), + mNextRaceButton(nullptr), + mPrevRaceButton(nullptr), + mRaceLabel(nullptr), + mRaceNameLabel(nullptr), + mNextLookButton(nullptr), + mPrevLookButton(nullptr), + mLookLabel(nullptr), + mLookNameLabel(nullptr), + // TRANSLATORS: char create dialog button + mActionButton(new Button(this, _("^"), "action", this)), + // TRANSLATORS: char create dialog button + mRotateButton(new Button(this, _(">"), "rotate", this)), + // TRANSLATORS: char create dialog button + mMale(new RadioButton(this, _("Male"), "gender")), + // TRANSLATORS: char create dialog button + mFemale(new RadioButton(this, _("Female"), "gender")), + // TRANSLATORS: char create dialog button + mOther(new RadioButton(this, _("Other"), "gender")), + mAttributeSlider(), + mAttributeLabel(), + mAttributeValue(), + mAttributesLeft(new Label(this, + // TRANSLATORS: char create dialog label + strprintf(_("Please distribute %d points"), 99))), + mMaxPoints(0), + mUsedPoints(0), + // TRANSLATORS: char create dialog button + mCreateButton(new Button(this, _("Create"), "create", this)), + // TRANSLATORS: char create dialog button + mCancelButton(new Button(this, _("Cancel"), "cancel", this)), + mRace(0), + mLook(0), + mMinLook(CharDB::getMinLook()), + mMaxLook(CharDB::getMaxLook()), + mPlayer(new Being(0, ActorSprite::PLAYER, static_cast(mRace), + nullptr)), + mPlayerBox(new PlayerBox(mPlayer, "charcreate_playerbox.xml", + "charcreate_selectedplayerbox.xml")), + mHairStyle(0), + mHairColor(0), + mSlot(slot), + maxHairColor(CharDB::getMaxHairColor()), + minHairColor(CharDB::getMinHairColor()), + maxHairStyle(CharDB::getMaxHairStyle()), + minHairStyle(CharDB::getMinHairStyle()), + mAction(0), + mDirection(0) +{ + setStickyButtonLock(true); + setSticky(true); + setWindowName("NewCharacter"); + + mPlayer->setGender(GENDER_MALE); + const std::vector &items = CharDB::getDefaultItems(); + int i = 1; + for (std::vector::const_iterator it = items.begin(), + it_end = items.end(); + it != it_end; ++ it, i ++) + { + mPlayer->setSprite(i, *it); + } + + if (!maxHairColor) + maxHairColor = ColorDB::getHairSize(); + if (!maxHairStyle) + maxHairStyle = mPlayer->getNumOfHairstyles(); + + if (maxHairStyle) + mHairStyle = (rand() % maxHairStyle) + minHairStyle; + else + mHairStyle = 0; + if (maxHairColor) + mHairColor = (rand() % maxHairColor) + minHairColor; + else + mHairColor = 0; + + mNameField->setMaximum(24); + + if (serverVersion >= 2) + { + // TRANSLATORS: char create dialog button + mNextRaceButton = new Button(this, _(">"), "nextrace", this); + // TRANSLATORS: char create dialog button + mPrevRaceButton = new Button(this, _("<"), "prevrace", this); + // TRANSLATORS: char create dialog label + mRaceLabel = new Label(this, _("Race:")); + mRaceNameLabel = new Label(this, ""); + } + if (serverVersion >= 9 && mMinLook < mMaxLook) + { + // TRANSLATORS: char create dialog button + mNextLookButton = new Button(this, _(">"), "nextlook", this); + // TRANSLATORS: char create dialog button + mPrevLookButton = new Button(this, _("<"), "prevlook", this); + // TRANSLATORS: char create dialog label + mLookLabel = new Label(this, _("Look:")); + mLookNameLabel = new Label(this, ""); + } + + // Default to a Male character + mMale->setSelected(true); + + mMale->setActionEventId("gender"); + mFemale->setActionEventId("gender"); + mOther->setActionEventId("gender"); + + mMale->addActionListener(this); + mFemale->addActionListener(this); + mOther->addActionListener(this); + + mPlayerBox->setWidth(74); + + mNameField->setActionEventId("create"); + mNameField->addActionListener(this); + + const int w = 480; + const int h = 350; + + setContentSize(w, h); + mPlayerBox->setDimension(gcn::Rectangle(360, 0, 110, 90)); + mActionButton->setPosition(385, 100); + mRotateButton->setPosition(415, 100); + + mNameLabel->setPosition(5, 2); + mNameField->setDimension( + gcn::Rectangle(60, 2, 300, mNameField->getHeight())); + + const int leftX = 120; + const int rightX = 300; + const int labelX = 5; + const int nameX = 145; + int y = 30; + mPrevHairColorButton->setPosition(leftX, y); + mNextHairColorButton->setPosition(rightX, y); + y += 5; + mHairColorLabel->setPosition(labelX, y); + mHairColorNameLabel->setPosition(nameX, y); + y += 24; + mPrevHairStyleButton->setPosition(leftX, y); + mNextHairStyleButton->setPosition(rightX, y); + y += 5; + mHairStyleLabel->setPosition(labelX, y); + mHairStyleNameLabel->setPosition(nameX, y); + + if (serverVersion >= 9 && mMinLook < mMaxLook) + { + y += 24; + mPrevLookButton->setPosition(leftX, y); + mNextLookButton->setPosition(rightX, y); + y += 5; + mLookLabel->setPosition(labelX, y); + mLookNameLabel->setPosition(nameX, y); // 93 + } + if (serverVersion >= 2) + { + y += 24; + mPrevRaceButton->setPosition(leftX, y); + mNextRaceButton->setPosition(rightX, y); + y += 5; + mRaceLabel->setPosition(labelX, y); + mRaceNameLabel->setPosition(nameX, y); + } + + updateSliders(); + setButtonsPosition(w, h); + + mMale->setPosition(30, 120); + mFemale->setPosition(100, 120); + mOther->setPosition(170, 120); + + add(mPlayerBox); + add(mNameField); + add(mNameLabel); + add(mNextHairColorButton); + add(mPrevHairColorButton); + add(mHairColorLabel); + add(mHairColorNameLabel); + add(mNextHairStyleButton); + add(mPrevHairStyleButton); + add(mHairStyleLabel); + add(mHairStyleNameLabel); + add(mActionButton); + add(mRotateButton); + + if (serverVersion >= 9 && mMinLook < mMaxLook) + { + add(mNextLookButton); + add(mPrevLookButton); + add(mLookLabel); + add(mLookNameLabel); + } + + if (serverVersion >= 2) + { + add(mNextRaceButton); + add(mPrevRaceButton); + add(mRaceLabel); + add(mRaceNameLabel); + } + + add(mAttributesLeft); + add(mCreateButton); + add(mCancelButton); + + add(mMale); + add(mFemale); + add(mOther); + + center(); + setVisible(true); + mNameField->requestFocus(); + + updateHair(); + if (serverVersion >= 2) + updateRace(); + if (serverVersion >= 9 && mMinLook < mMaxLook) + updateLook(); + updatePlayer(); + + addKeyListener(this); +} + +CharCreateDialog::~CharCreateDialog() +{ + delete mPlayer; + mPlayer = nullptr; + + if (Net::getCharServerHandler()) + Net::getCharServerHandler()->setCharCreateDialog(nullptr); +} + +void CharCreateDialog::action(const gcn::ActionEvent &event) +{ + const std::string id = event.getId(); + if (id == "create") + { + if ( +#ifdef MANASERV_SUPPORT + Net::getNetworkType() == ServerInfo::MANASERV || +#endif + getName().length() >= 4) + { + // Attempt to create the character + mCreateButton->setEnabled(false); + + std::vector atts; + for (size_t i = 0, sz = mAttributeSlider.size(); i < sz; i++) + { + atts.push_back(static_cast( + mAttributeSlider[i]->getValue())); + } + +#ifdef MANASERV_SUPPORT + int characterSlot = mSlot; + // On Manaserv, the slots start at 1, so we offset them. + if (Net::getNetworkType() == ServerInfo::MANASERV) + ++characterSlot; +#else + const int characterSlot = mSlot; +#endif + + Net::getCharServerHandler()->newCharacter(getName(), characterSlot, + mFemale->isSelected(), mHairStyle, mHairColor, + static_cast(mRace), mLook, atts); + } + else + { + // TRANSLATORS: char creation error + new OkDialog(_("Error"), + // TRANSLATORS: char creation error + _("Your name needs to be at least 4 characters."), + DIALOG_ERROR, true, this); + } + } + else if (id == "cancel") + { + scheduleDelete(); + } + else if (id == "nextcolor") + { + mHairColor ++; + updateHair(); + } + else if (id == "prevcolor") + { + mHairColor --; + updateHair(); + } + else if (id == "nextstyle") + { + mHairStyle ++; + updateHair(); + } + else if (id == "prevstyle") + { + mHairStyle --; + updateHair(); + } + else if (id == "nextrace") + { + mRace ++; + updateRace(); + } + else if (id == "prevrace") + { + mRace --; + updateRace(); + } + else if (id == "nextlook") + { + mLook ++; + updateLook(); + } + else if (id == "prevlook") + { + mLook --; + updateLook(); + } + else if (id == "statslider") + { + updateSliders(); + } + else if (id == "gender") + { + if (mMale->isSelected()) + mPlayer->setGender(GENDER_MALE); + else + mPlayer->setGender(GENDER_FEMALE); + } + else if (id == "action") + { + mAction ++; + if (mAction >= 5) + mAction = 0; + updatePlayer(); + } + else if (id == "rotate") + { + mDirection ++; + if (mDirection >= 4) + mDirection = 0; + updatePlayer(); + } +} + +std::string CharCreateDialog::getName() const +{ + std::string name = mNameField->getText(); + trim(name); + return name; +} + +void CharCreateDialog::updateSliders() +{ + for (size_t i = 0, sz = mAttributeSlider.size(); i < sz; i++) + { + // Update captions + mAttributeValue[i]->setCaption( + toString(static_cast(mAttributeSlider[i]->getValue()))); + mAttributeValue[i]->adjustSize(); + } + + // Update distributed points + const int pointsLeft = mMaxPoints - getDistributedPoints(); + if (pointsLeft == 0) + { + // TRANSLATORS: char create dialog label + mAttributesLeft->setCaption(_("Character stats OK")); + mCreateButton->setEnabled(true); + } + else + { + mCreateButton->setEnabled(false); + if (pointsLeft > 0) + { + mAttributesLeft->setCaption( + // TRANSLATORS: char create dialog label + strprintf(_("Please distribute %d points"), pointsLeft)); + } + else + { + mAttributesLeft->setCaption( + // TRANSLATORS: char create dialog label + strprintf(_("Please remove %d points"), -pointsLeft)); + } + } + + mAttributesLeft->adjustSize(); +} + +void CharCreateDialog::unlock() +{ + mCreateButton->setEnabled(true); +} + +int CharCreateDialog::getDistributedPoints() const +{ + int points = 0; + + for (size_t i = 0, sz = mAttributeSlider.size(); i < sz; i++) + points += static_cast(mAttributeSlider[i]->getValue()); + return points; +} + +void CharCreateDialog::setAttributes(const StringVect &labels, + const int available, + const int min, const int max) +{ + mMaxPoints = available; + + for (unsigned i = 0; i < mAttributeLabel.size(); i++) + { + remove(mAttributeLabel[i]); + delete mAttributeLabel[i]; + mAttributeLabel[i] = nullptr; + remove(mAttributeSlider[i]); + delete mAttributeSlider[i]; + mAttributeSlider[i] = nullptr; + remove(mAttributeValue[i]); + delete mAttributeValue[i]; + mAttributeValue[i] = nullptr; + } + + mAttributeLabel.resize(labels.size()); + mAttributeSlider.resize(labels.size()); + mAttributeValue.resize(labels.size()); + + const int w = 480; + const int h = 350; + const int y = 118 + 29; + + for (unsigned i = 0, sz = static_cast(labels.size()); + i < sz; i++) + { + mAttributeLabel[i] = new Label(this, labels[i]); + mAttributeLabel[i]->setWidth(70); + mAttributeLabel[i]->setPosition(5, y + i * 24); + mAttributeLabel[i]->adjustSize(); + add(mAttributeLabel[i]); + + mAttributeSlider[i] = new Slider(min, max); + mAttributeSlider[i]->setDimension(gcn::Rectangle(140, y + i * 24, + 150, 12)); + mAttributeSlider[i]->setActionEventId("statslider"); + mAttributeSlider[i]->addActionListener(this); + add(mAttributeSlider[i]); + + mAttributeValue[i] = new Label(this, toString(min)); + mAttributeValue[i]->setPosition(295, y + i * 24); + add(mAttributeValue[i]); + } + + updateSliders(); + setButtonsPosition(w, h); +} + +void CharCreateDialog::setFixedGender(const bool fixed, const Gender gender) +{ + if (gender == GENDER_FEMALE) + { + mFemale->setSelected(true); + mMale->setSelected(false); + mOther->setSelected(false); + } + else if (gender == GENDER_MALE) + { + mFemale->setSelected(false); + mMale->setSelected(true); + mOther->setSelected(false); + } + else + { + mFemale->setSelected(false); + mMale->setSelected(false); + mOther->setSelected(true); + } + + mPlayer->setGender(gender); + + if (fixed) + { + mMale->setVisible(false); + mFemale->setVisible(false); + mOther->setVisible(false); + } +} + +void CharCreateDialog::updateHair() +{ + if (mHairStyle <= 0) + mHairStyle = Being::getNumOfHairstyles() - 1; + else + mHairStyle %= Being::getNumOfHairstyles(); + if (mHairStyle < static_cast(minHairStyle) + || mHairStyle > static_cast(maxHairStyle)) + { + mHairStyle = minHairStyle; + } + const ItemInfo &item = ItemDB::get(-mHairStyle); + mHairStyleNameLabel->setCaption(item.getName()); + mHairStyleNameLabel->adjustSize(); + + if (ColorDB::getHairSize()) + mHairColor %= ColorDB::getHairSize(); + else + mHairColor = 0; + if (mHairColor < 0) + mHairColor += ColorDB::getHairSize(); + if (mHairColor < static_cast(minHairColor) + || mHairColor > static_cast(maxHairColor)) + { + mHairColor = minHairColor; + } + mHairColorNameLabel->setCaption(ColorDB::getHairColorName(mHairColor)); + mHairColorNameLabel->adjustSize(); + + mPlayer->setSprite(Net::getCharServerHandler()->hairSprite(), + mHairStyle * -1, item.getDyeColorsString(mHairColor)); +} + +void CharCreateDialog::updateRace() +{ + if (mRace < 0) + mRace = Being::getNumOfRaces() - 1; + else if (mRace >= Being::getNumOfRaces()) + mRace = 0; + + updateLook(); +} + +void CharCreateDialog::updateLook() +{ + const ItemInfo &item = ItemDB::get(-100 - mRace); + const int sz = item.getColorsSize(); + if (sz > 0 && serverVersion >= 9) + { + if (mLook < 0) + mLook = sz - 1; + if (mLook > mMaxLook) + mLook = mMinLook; + if (mLook >= sz) + mLook = mMinLook; + } + else + { + mLook = 0; + } + mPlayer->setSubtype(static_cast(mRace), mLook); + if (mRaceNameLabel) + { + mRaceNameLabel->setCaption(item.getName()); + mRaceNameLabel->adjustSize(); + } + if (mLookNameLabel) + { + mLookNameLabel->setCaption(item.getColorName(mLook)); + mLookNameLabel->adjustSize(); + } +} + +void CharCreateDialog::logic() +{ + if (mPlayer) + mPlayer->logic(); +} + +void CharCreateDialog::updatePlayer() +{ + if (mPlayer) + { + mPlayer->setDirection(directions[mDirection]); + mPlayer->setAction(actions[mAction]); + } +} + +void CharCreateDialog::keyPressed(gcn::KeyEvent &keyEvent) +{ + const int actionId = static_cast(&keyEvent)->getActionId(); + switch (actionId) + { + case Input::KEY_GUI_CANCEL: + keyEvent.consume(); + action(gcn::ActionEvent(mCancelButton, + mCancelButton->getActionEventId())); + break; + + default: + break; + } +} + +void CharCreateDialog::setButtonsPosition(const int w, const int h) +{ + if (mainGraphics->getHeight() < 480) + { + mCreateButton->setPosition(340, 150); + mCancelButton->setPosition(340, 160 + mCreateButton->getHeight()); + } + else + { + mCancelButton->setPosition( + w / 2, + h - 5 - mCancelButton->getHeight()); + mCreateButton->setPosition( + mCancelButton->getX() - 5 - mCreateButton->getWidth(), + h - 5 - mCancelButton->getHeight()); + } + mAttributesLeft->setPosition(15, 260 + 29); +} -- cgit v1.2.3-70-g09d2