diff options
author | Andrei Karas <akaras@inbox.ru> | 2013-09-30 14:03:48 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2013-09-30 14:03:48 +0300 |
commit | 25d77892d72d455f8a89372687db45aefbc61cec (patch) | |
tree | de03cb1af09eebf6db853a6585b953884bcca3b2 /src/gui/windows/statuswindow.cpp | |
parent | 05c22dd1a69fe90da67188c74a6995ee3747e937 (diff) | |
download | plus-25d77892d72d455f8a89372687db45aefbc61cec.tar.gz plus-25d77892d72d455f8a89372687db45aefbc61cec.tar.bz2 plus-25d77892d72d455f8a89372687db45aefbc61cec.tar.xz plus-25d77892d72d455f8a89372687db45aefbc61cec.zip |
move windows classes to windows directory.
Diffstat (limited to 'src/gui/windows/statuswindow.cpp')
-rw-r--r-- | src/gui/windows/statuswindow.cpp | 888 |
1 files changed, 888 insertions, 0 deletions
diff --git a/src/gui/windows/statuswindow.cpp b/src/gui/windows/statuswindow.cpp new file mode 100644 index 000000000..bbc4558b0 --- /dev/null +++ b/src/gui/windows/statuswindow.cpp @@ -0,0 +1,888 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ + +#include "gui/windows/statuswindow.h" + +#include "configuration.h" +#include "equipment.h" +#include "inventory.h" +#include "item.h" +#include "units.h" + +#include "gui/windows/chatwindow.h" + +#include "being/localplayer.h" +#include "being/playerinfo.h" + +#include "gui/viewport.h" + +#include "gui/windows/equipmentwindow.h" +#include "gui/windows/setup.h" + +#include "gui/widgets/button.h" +#include "gui/widgets/label.h" +#include "gui/widgets/layouthelper.h" +#include "gui/widgets/progressbar.h" +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/vertcontainer.h" + +#include "net/net.h" +#include "net/playerhandler.h" +#include "net/gamehandler.h" + +#include "utils/gettext.h" + +#include <SDL_timer.h> + +#include "debug.h" + +class AttrDisplay : public Container +{ + public: + enum Type + { + DERIVED = 0, + CHANGEABLE, + UNKNOWN + }; + + A_DELETE_COPY(AttrDisplay) + + virtual ~AttrDisplay(); + + virtual std::string update(); + + virtual Type getType() const + { return UNKNOWN; } + + std::string getValue() const + { + if (!mValue) + return "-"; + else + return mValue->getCaption(); + } + + const std::string &getShortName() const + { return mShortName; } + + protected: + AttrDisplay(const Widget2 *const widget, + const int id, const std::string &name, + const std::string &shortName); + + const int mId; + const std::string mName; + const std::string mShortName; + + LayoutHelper *mLayout; + Label *mLabel; + Label *mValue; +}; + +class DerDisplay final : public AttrDisplay +{ + public: + DerDisplay(const Widget2 *const widget, + const int id, const std::string &name, + const std::string &shortName); + + A_DELETE_COPY(DerDisplay) + + Type getType() const override + { return DERIVED; } +}; + +class ChangeDisplay final : public AttrDisplay, gcn::ActionListener +{ + public: + ChangeDisplay(const Widget2 *const widget, + const int id, const std::string &name, + const std::string &shortName); + + A_DELETE_COPY(ChangeDisplay) + + std::string update() override; + + Type getType() const override + { return CHANGEABLE; } + + void setPointsNeeded(int needed); + + void action(const gcn::ActionEvent &event) override; + + private: + int mNeeded; + + Label *mPoints; + Button *mDec; + Button *mInc; +}; + +StatusWindow::StatusWindow() : + Window(player_node ? player_node->getName() : + "?", false, nullptr, "status.xml"), + gcn::ActionListener(), + // TRANSLATORS: status window label + mLvlLabel(new Label(this, strprintf(_("Level: %d"), 0))), + // TRANSLATORS: status window label + mMoneyLabel(new Label(this, strprintf(_("Money: %s"), ""))), + // TRANSLATORS: status window label + mHpLabel(new Label(this, _("HP:"))), + mMpLabel(nullptr), + // TRANSLATORS: status window label + mXpLabel(new Label(this, _("Exp:"))), + mHpBar(nullptr), + mMpBar(nullptr), + mXpBar(nullptr), + mJobLvlLabel(nullptr), + mJobLabel(nullptr), + mJobBar(nullptr), + mAttrCont(new VertContainer(this, 32)), + mAttrScroll(new ScrollArea(mAttrCont, false)), + mDAttrCont(new VertContainer(this, 32)), + mDAttrScroll(new ScrollArea(mDAttrCont, false)), + mCharacterPointsLabel(new Label(this, "C")), + mCorrectionPointsLabel(nullptr), + // TRANSLATORS: status window button + mCopyButton(new Button(this, _("Copy to chat"), "copy", this)), + mAttrs() +{ + listen(CHANNEL_ATTRIBUTES); + + setWindowName("Status"); + if (setupWindow) + setupWindow->registerWindowForReset(this); + setResizable(true); + setCloseButton(true); + setSaveVisible(true); + setStickyButtonLock(true); + setDefaultSize((windowContainer->getWidth() - 480) / 2, + (windowContainer->getHeight() - 500) / 2, 480, 500); + + if (player_node && !player_node->getRaceName().empty()) + { + setCaption(strprintf("%s (%s)", player_node->getName().c_str(), + player_node->getRaceName().c_str())); + } + + int max = PlayerInfo::getAttribute(PlayerInfo::MAX_HP); + if (!max) + max = 1; + + mHpBar = new ProgressBar(this, static_cast<float>(PlayerInfo::getAttribute( + PlayerInfo::HP)) / static_cast<float>(max), 80, 0, Theme::PROG_HP); + + max = PlayerInfo::getAttribute(PlayerInfo::EXP_NEEDED); + mXpBar = new ProgressBar(this, max ? + static_cast<float>(PlayerInfo::getAttribute(PlayerInfo::EXP)) + / static_cast<float>(max): + static_cast<float>(0), 80, 0, Theme::PROG_EXP); + + const bool magicBar = Net::getGameHandler()->canUseMagicBar(); + const int job = Net::getPlayerHandler()->getJobLocation() + && serverConfig.getValueBool("showJob", true); + + if (magicBar) + { + max = PlayerInfo::getAttribute(PlayerInfo::MAX_MP); + // TRANSLATORS: status window label + mMpLabel = new Label(this, _("MP:")); + mMpBar = new ProgressBar(this, max ? static_cast<float>( + PlayerInfo::getAttribute(PlayerInfo::MAX_MP)) + / static_cast<float>(max) : static_cast<float>(0), + 80, 0, Net::getPlayerHandler()->canUseMagic() ? + Theme::PROG_MP : Theme::PROG_NO_MP); + } + else + { + mMpLabel = nullptr; + mMpBar = nullptr; + } + + place(0, 0, mLvlLabel, 3); + place(0, 1, mHpLabel).setPadding(3); + place(1, 1, mHpBar, 4); + place(5, 1, mXpLabel).setPadding(3); + place(6, 1, mXpBar, 5); + if (magicBar) + { + place(0, 2, mMpLabel).setPadding(3); + // 5, 2 and 6, 2 Job Progress Bar + if (job) + place(1, 2, mMpBar, 4); + else + place(1, 2, mMpBar, 10); + } + + if (job) + { + // TRANSLATORS: status window label + mJobLvlLabel = new Label(this, strprintf(_("Job: %d"), 0)); + // TRANSLATORS: status window label + mJobLabel = new Label(this, _("Job:")); + mJobBar = new ProgressBar(this, 0.0F, 80, 0, Theme::PROG_JOB); + + place(3, 0, mJobLvlLabel, 3); + place(5, 2, mJobLabel).setPadding(3); + place(6, 2, mJobBar, 5); + place(6, 0, mMoneyLabel, 3); + } + else + { + mJobLvlLabel = nullptr; + mJobLabel = nullptr; + mJobBar = nullptr; + place(3, 0, mMoneyLabel, 3); + } + + // ---------------------- + // Stats Part + // ---------------------- + + mAttrScroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER); + mAttrScroll->setVerticalScrollPolicy(ScrollArea::SHOW_AUTO); + place(0, 3, mAttrScroll, 5, 3); + + mDAttrScroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER); + mDAttrScroll->setVerticalScrollPolicy(ScrollArea::SHOW_AUTO); + place(6, 3, mDAttrScroll, 5, 3); + + getLayout().setRowHeight(3, Layout::AUTO_SET); + + place(0, 6, mCharacterPointsLabel, 5); + place(0, 5, mCopyButton); + + if (Net::getPlayerHandler()->canCorrectAttributes()) + { + mCorrectionPointsLabel = new Label(this, "C"); + place(0, 7, mCorrectionPointsLabel, 5); + } + + loadWindowState(); + enableVisibleSound(true); + + // Update bars + updateHPBar(mHpBar, true); + if (magicBar) + updateMPBar(mMpBar, true); + updateXPBar(mXpBar, false); + + // TRANSLATORS: status window label + mMoneyLabel->setCaption(strprintf(_("Money: %s"), Units::formatCurrency( + PlayerInfo::getAttribute(PlayerInfo::MONEY)).c_str())); + mMoneyLabel->adjustSize(); + // TRANSLATORS: status window label + mCharacterPointsLabel->setCaption(strprintf(_("Character points: %d"), + PlayerInfo::getAttribute(PlayerInfo::CHAR_POINTS))); + mCharacterPointsLabel->adjustSize(); + + if (player_node && player_node->isGM()) + { + // TRANSLATORS: status window label + mLvlLabel->setCaption(strprintf(_("Level: %d (GM %d)"), + PlayerInfo::getAttribute(PlayerInfo::LEVEL), + player_node->getGMLevel())); + } + else + { + // TRANSLATORS: status window label + mLvlLabel->setCaption(strprintf(_("Level: %d"), + PlayerInfo::getAttribute(PlayerInfo::LEVEL))); + } + mLvlLabel->adjustSize(); +} + +void StatusWindow::processEvent(const Channels channel A_UNUSED, + const DepricatedEvent &event) +{ + static bool blocked = false; + if (blocked) + return; + + const DepricatedEvents &eventName = event.getName(); + if (eventName == EVENT_UPDATEATTRIBUTE) + { + switch (event.getInt("id")) + { + case PlayerInfo::HP: + case PlayerInfo::MAX_HP: + updateHPBar(mHpBar, true); + break; + + case PlayerInfo::MP: + case PlayerInfo::MAX_MP: + updateMPBar(mMpBar, true); + break; + + case PlayerInfo::EXP: + case PlayerInfo::EXP_NEEDED: + updateXPBar(mXpBar, false); + break; + + case PlayerInfo::MONEY: + // TRANSLATORS: status window label + mMoneyLabel->setCaption(strprintf(_("Money: %s"), + Units::formatCurrency(event.getInt("newValue")).c_str())); + mMoneyLabel->adjustSize(); + break; + + case PlayerInfo::CHAR_POINTS: + mCharacterPointsLabel->setCaption(strprintf( + // TRANSLATORS: status window label + _("Character points: %d"), event.getInt("newValue"))); + + mCharacterPointsLabel->adjustSize(); + // Update all attributes + for (Attrs::const_iterator it = mAttrs.begin(); + it != mAttrs.end(); ++it) + { + if (it->second) + it->second->update(); + } + break; + + case PlayerInfo::CORR_POINTS: + mCorrectionPointsLabel->setCaption(strprintf( + // TRANSLATORS: status window label + _("Correction points: %d"), event.getInt("newValue"))); + mCorrectionPointsLabel->adjustSize(); + // Update all attributes + for (Attrs::const_iterator it = mAttrs.begin(); + it != mAttrs.end(); ++it) + { + if (it->second) + it->second->update(); + } + break; + + case PlayerInfo::LEVEL: + // TRANSLATORS: status window label + mLvlLabel->setCaption(strprintf(_("Level: %d"), + event.getInt("newValue"))); + mLvlLabel->adjustSize(); + break; + + default: + break; + } + } + else if (eventName == EVENT_UPDATESTAT) + { + const int id = event.getInt("id"); + if (id == Net::getPlayerHandler()->getJobLocation()) + { + if (mJobLvlLabel) + { + int lvl = PlayerInfo::getStatBase(id); + const int oldExp = event.getInt("oldValue1"); + const std::pair<int, int> exp + = PlayerInfo::getStatExperience(id); + + if (!lvl) + { + // possible server broken and don't send job level, + // then we fixing it :) + if (exp.second < 20000) + { + lvl = 0; + } + else + { + lvl = (exp.second - 20000) / 150; + blocked = true; + PlayerInfo::setStatBase(id, lvl); + blocked = false; + } + } + + if (exp.first < oldExp && exp.second >= 20000) + { // possible job level up. but server broken and don't send + // new job exp limit, we fixing it + lvl ++; + blocked = true; + PlayerInfo::setStatExperience( + id, exp.first, 20000 + lvl * 150); + PlayerInfo::setStatBase(id, lvl); + blocked = false; + } + + // TRANSLATORS: status window label + mJobLvlLabel->setCaption(strprintf(_("Job: %d"), lvl)); + mJobLvlLabel->adjustSize(); + + updateProgressBar(mJobBar, id, false); + } + } + else + { + updateMPBar(mMpBar, true); + const Attrs::const_iterator it = mAttrs.find(id); + if (it != mAttrs.end() && it->second) + it->second->update(); + } + } +} + +void StatusWindow::setPointsNeeded(const int id, const int needed) +{ + const Attrs::const_iterator it = mAttrs.find(id); + + if (it != mAttrs.end()) + { + AttrDisplay *const disp = it->second; + if (disp && disp->getType() == AttrDisplay::CHANGEABLE) + static_cast<ChangeDisplay*>(disp)->setPointsNeeded(needed); + } +} + +void StatusWindow::addAttribute(const int id, const std::string &name, + const std::string &shortName, + const bool modifiable, + const std::string &description A_UNUSED) +{ + AttrDisplay *disp; + + if (modifiable) + { + disp = new ChangeDisplay(this, id, name, shortName); + mAttrCont->add1(disp); + } + else + { + disp = new DerDisplay(this, id, name, shortName); + mDAttrCont->add1(disp); + } + mAttrs[id] = disp; +} + +void StatusWindow::clearAttributes() +{ + mAttrCont->clear(); + mDAttrCont->clear(); + FOR_EACH (Attrs::iterator, it, mAttrs) + delete (*it).second; + mAttrs.clear(); +} + +void StatusWindow::updateHPBar(ProgressBar *const bar, const bool showMax) +{ + if (!bar) + return; + + const int hp = PlayerInfo::getAttribute(PlayerInfo::HP); + const int maxHp = PlayerInfo::getAttribute(PlayerInfo::MAX_HP); + if (showMax) + bar->setText(toString(hp).append("/").append(toString(maxHp))); + else + bar->setText(toString(hp)); + + float prog = 1.0; + if (maxHp > 0) + prog = static_cast<float>(hp) / static_cast<float>(maxHp); + bar->setProgress(prog); +} + +void StatusWindow::updateMPBar(ProgressBar *const bar, const bool showMax) +{ + if (!bar) + return; + + const int mp = PlayerInfo::getAttribute(PlayerInfo::MP); + const int maxMp = PlayerInfo::getAttribute(PlayerInfo::MAX_MP); + if (showMax) + bar->setText(toString(mp).append("/").append(toString(maxMp))); + else + bar->setText(toString(mp)); + + float prog = 1.0F; + if (maxMp > 0) + prog = static_cast<float>(mp) / static_cast<float>(maxMp); + + if (Net::getPlayerHandler()->canUseMagic()) + bar->setProgressPalette(Theme::PROG_MP); + else + bar->setProgressPalette(Theme::PROG_NO_MP); + + bar->setProgress(prog); +} + +void StatusWindow::updateProgressBar(ProgressBar *const bar, const int value, + const int max, const bool percent) +{ + if (!bar) + return; + + if (max == 0) + { + // TRANSLATORS: status bar label + bar->setText(_("Max")); + bar->setProgress(1); + bar->setText(toString(value)); + } + else + { + const float progress = static_cast<float>(value) + / static_cast<float>(max); + if (percent) + { + bar->setText(strprintf("%2.5f%%", + static_cast<double>(100 * progress))); + } + else + { + bar->setText(toString(value).append("/").append(toString(max))); + } + bar->setProgress(progress); + } +} + +void StatusWindow::updateXPBar(ProgressBar *const bar, const bool percent) +{ + if (!bar) + return; + + updateProgressBar(bar, PlayerInfo::getAttribute(PlayerInfo::EXP), + PlayerInfo::getAttribute(PlayerInfo::EXP_NEEDED), percent); +} + +void StatusWindow::updateJobBar(ProgressBar *const bar, const bool percent) +{ + if (!bar) + return; + + const std::pair<int, int> exp = PlayerInfo::getStatExperience( + Net::getPlayerHandler()->getJobLocation()); + updateProgressBar(bar, exp.first, exp.second, percent); +} + +void StatusWindow::updateProgressBar(ProgressBar *const bar, const int id, + const bool percent) const +{ + const std::pair<int, int> exp = PlayerInfo::getStatExperience(id); + updateProgressBar(bar, exp.first, exp.second, percent); +} + +void StatusWindow::updateWeightBar(ProgressBar *const bar) +{ + if (!bar) + return; + + if (PlayerInfo::getAttribute(PlayerInfo::MAX_WEIGHT) == 0) + { + // TRANSLATORS: status bar label + bar->setText(_("Max")); + bar->setProgress(1.0); + } + else + { + const int totalWeight = PlayerInfo::getAttribute( + PlayerInfo::TOTAL_WEIGHT); + const int maxWeight = PlayerInfo::getAttribute(PlayerInfo::MAX_WEIGHT); + const float progress = static_cast<float>(totalWeight) + / static_cast<float>(maxWeight); + bar->setText(strprintf("%s/%s", Units::formatWeight( + totalWeight).c_str(), Units::formatWeight(maxWeight).c_str())); + bar->setProgress(progress); + } +} + +void StatusWindow::updateMoneyBar(ProgressBar *const bar) +{ + if (!bar) + return; + + const int money = PlayerInfo::getAttribute(PlayerInfo::MONEY); + bar->setText(Units::formatCurrency(money).c_str()); + if (money > 0) + { + const float progress = static_cast<float>(money) + / static_cast<float>(1000000000); + bar->setProgress(progress); + } + else + { + bar->setProgress(1.0); + } +} + +void StatusWindow::updateArrowsBar(ProgressBar *const bar) +{ + if (!bar || !equipmentWindow) + return; + + const Item *const item = equipmentWindow->getEquipment( + Equipment::EQUIP_PROJECTILE_SLOT); + + if (item && item->getQuantity() > 0) + bar->setText(toString(item->getQuantity())); + else + bar->setText("0"); +} + +void StatusWindow::updateInvSlotsBar(ProgressBar *const bar) +{ + if (!bar) + return; + + const Inventory *const inv = PlayerInfo::getInventory(); + if (!inv) + return; + + const int usedSlots = inv->getNumberOfSlotsUsed(); + const int maxSlots = inv->getSize(); + + if (maxSlots) + { + bar->setProgress(static_cast<float>(usedSlots) + / static_cast<float>(maxSlots)); + } + + bar->setText(strprintf("%d", usedSlots)); +} + +std::string StatusWindow::translateLetter(const char *const letters) +{ + char buf[2]; + char *const str = gettext(letters); + if (strlen(str) != 3) + return letters; + + buf[0] = str[1]; + buf[1] = 0; + return std::string(buf); +} + +std::string StatusWindow::translateLetter2(std::string letters) +{ + if (letters.size() < 5) + return ""; + + return std::string(gettext(letters.substr(1, 1).c_str())); +} + +void StatusWindow::updateStatusBar(ProgressBar *const bar, + const bool percent A_UNUSED) +{ + if (!player_node || !viewport) + return; + + bar->setText(translateLetter2(player_node->getInvertDirectionString()) + .append(translateLetter2(player_node->getCrazyMoveTypeString())) + .append(translateLetter2(player_node->getMoveToTargetTypeString())) + .append(translateLetter2(player_node->getFollowModeString())) + .append(" ").append(translateLetter2( + player_node->getAttackWeaponTypeString())) + .append(translateLetter2(player_node->getAttackTypeString())) + .append(translateLetter2(player_node->getMagicAttackString())) + .append(translateLetter2(player_node->getPvpAttackString())) + .append(" ").append(translateLetter2( + player_node->getQuickDropCounterString())) + .append(translateLetter2(player_node->getPickUpTypeString())) + .append(" ").append(translateLetter2( + player_node->getDebugPathString())) + .append(" ").append(translateLetter2( + player_node->getImitationModeString())) + .append(translateLetter2(player_node->getCameraModeString())) + .append(translateLetter2(player_node->getAwayModeString()))); + + bar->setProgress(50); + if (player_node->getDisableGameModifiers()) + bar->setColor(Theme::getThemeColor(Theme::STATUSBAR_ON)); + else + bar->setColor(Theme::getThemeColor(Theme::STATUSBAR_OFF)); +} + +void StatusWindow::action(const gcn::ActionEvent &event) +{ + if (!chatWindow) + return; + + if (event.getId() == "copy") + { + Attrs::const_iterator it = mAttrs.begin(); + const Attrs::const_iterator it_end = mAttrs.end(); + std::string str; + while (it != it_end) + { + const ChangeDisplay *const attr = dynamic_cast<ChangeDisplay*>( + (*it).second); + if (attr) + { + str.append(strprintf("%s:%s ", attr->getShortName().c_str(), + attr->getValue().c_str())); + } + ++ it; + } + chatWindow->addInputText(str); + } +} + +AttrDisplay::AttrDisplay(const Widget2 *const widget, + const int id, const std::string &name, + const std::string &shortName) : + Container(widget), + mId(id), + mName(name), + mShortName(shortName), + mLayout(new LayoutHelper(this)), + mLabel(new Label(this, name)), + mValue(new Label(this, "1 ")) +{ + setSize(100, 32); + + mLabel->setAlignment(Graphics::CENTER); + mValue->setAlignment(Graphics::CENTER); +} + +AttrDisplay::~AttrDisplay() +{ + delete mLayout; + mLayout = nullptr; +} + +std::string AttrDisplay::update() +{ + const int base = PlayerInfo::getStatBase(mId); + const int bonus = PlayerInfo::getStatMod(mId); + std::string value = toString(base + bonus); + if (bonus) + value.append(strprintf("=%d%+d", base, bonus)); + mValue->setCaption(value); + return mName; +} + +DerDisplay::DerDisplay(const Widget2 *const widget, + const int id, const std::string &name, + const std::string &shortName) : + AttrDisplay(widget, id, name, shortName) +{ + ContainerPlacer place = mLayout->getPlacer(0, 0); + + place(0, 0, mLabel, 3); + place(3, 0, mValue, 2); + + update(); +} + +ChangeDisplay::ChangeDisplay(const Widget2 *const widget, + const int id, const std::string &name, + const std::string &shortName) : + AttrDisplay(widget, id, name, shortName), + gcn::ActionListener(), + mNeeded(1), + // TRANSLATORS: status window label + mPoints(new Label(this, _("Max"))), + mDec(nullptr), + // TRANSLATORS: status window label (plus sign) + mInc(new Button(this, _("+"), "inc", this)) +{ + // Do the layout + ContainerPlacer place = mLayout->getPlacer(0, 0); + + place(0, 0, mLabel, 3); + place(4, 0, mValue, 2); + place(6, 0, mInc); + place(7, 0, mPoints); + + if (Net::getPlayerHandler()->canCorrectAttributes()) + { + // TRANSLATORS: status window label (minus sign) + mDec = new Button(this, _("-"), "dec", this); + mDec->setWidth(mInc->getWidth()); + + place(3, 0, mDec); + } + + update(); +} + +std::string ChangeDisplay::update() +{ + if (mNeeded > 0) + { + mPoints->setCaption(toString(mNeeded)); + } + else + { + // TRANSLATORS: status bar label + mPoints->setCaption(_("Max")); + } + + if (mDec) + mDec->setEnabled(PlayerInfo::getAttribute(PlayerInfo::CORR_POINTS)); + + mInc->setEnabled(PlayerInfo::getAttribute(PlayerInfo::CHAR_POINTS) + >= mNeeded && mNeeded > 0); + + return AttrDisplay::update(); +} + +void ChangeDisplay::setPointsNeeded(const int needed) +{ + mNeeded = needed; + update(); +} + +void ChangeDisplay::action(const gcn::ActionEvent &event) +{ + if (Net::getPlayerHandler()->canCorrectAttributes() && + event.getSource() == mDec) + { + const int newcorrpoints = PlayerInfo::getAttribute( + PlayerInfo::CORR_POINTS); + PlayerInfo::setAttribute(PlayerInfo::CORR_POINTS, newcorrpoints - 1); + + const int newpoints = PlayerInfo::getAttribute( + PlayerInfo::CHAR_POINTS) + 1; + PlayerInfo::setAttribute(PlayerInfo::CHAR_POINTS, newpoints); + + const int newbase = PlayerInfo::getStatBase(mId) - 1; + PlayerInfo::setStatBase(mId, newbase); + + Net::getPlayerHandler()->decreaseAttribute(mId); + } + else if (event.getSource() == mInc) + { + int cnt = 1; + if (config.getBoolValue("quickStats")) + { + cnt = mInc->getClickCount(); + if (cnt > 10) + cnt = 10; + } + + const int newpoints = PlayerInfo::getAttribute( + PlayerInfo::CHAR_POINTS) - cnt; + PlayerInfo::setAttribute(PlayerInfo::CHAR_POINTS, newpoints); + + const int newbase = PlayerInfo::getStatBase(mId) + cnt; + PlayerInfo::setStatBase(mId, newbase); + + for (unsigned f = 0; f < mInc->getClickCount(); f ++) + { + Net::getPlayerHandler()->increaseAttribute(mId); + if (cnt != 1) + SDL_Delay(100); + } + } +} |