/* * The Mana Client * Copyright (C) 2009-2012 The Mana Developers * * This file is part of The Mana 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/abilitieswindow.h" #include "log.h" #include "gui/setup.h" #include "gui/widgets/button.h" #include "gui/widgets/container.h" #include "gui/widgets/icon.h" #include "gui/widgets/label.h" #include "gui/widgets/progressbar.h" #include "gui/widgets/windowcontainer.h" #include "net/net.h" #include "net/abilityhandler.h" #include "resources/abilitydb.h" #include "resources/theme.h" #include "utils/dtor.h" #include "utils/gettext.h" #include "localplayer.h" #include #define ABILITIES_WIDTH 200 #define ABILITIES_HEIGHT 32 class AbilityEntry : public Container { public: AbilityEntry(AbilityInfo *info); void update(int current, int needed); protected: friend class AbilitiesWindow; AbilityInfo *mInfo; private: Icon *mIcon = nullptr; // icon to display Label *mNameLabel = nullptr; // name to display Button *mUse = nullptr; // use button (only shown when applicable) ProgressBar *mRechargeBar = nullptr; // recharge bar (only shown when applicable) }; AbilitiesWindow::AbilitiesWindow(): Window(_("Abilities")) { setWindowName("Abilities"); setCloseButton(true); setResizable(true); setSaveVisible(true); setDefaultSize(windowContainer->getWidth() - 280, 40, ABILITIES_WIDTH + 20, 225); setupWindow->registerWindowForReset(this); center(); loadWindowState(); } AbilitiesWindow::~AbilitiesWindow() { // Clear gui } void AbilitiesWindow::action(const gcn::ActionEvent &event) { if (event.getId() == "use") { auto *disp = dynamic_cast(event.getSource()->getParent()); if (disp) { if (disp->mInfo->targetMode == AbilityInfo::TARGET_BEING) { Being *target = local_player->getTarget(); if (target) Net::getAbilityHandler()->useOn(disp->mInfo->id, target->getId()); else Net::getAbilityHandler()->use(disp->mInfo->id); } else { // TODO: Allow the player to aim at a position on the map and // Use abilities on the map position. } } } else if (event.getId() == "close") { setVisible(false); } } void AbilitiesWindow::draw(gcn::Graphics *graphics) { // update the progress bars const std::map &abilityData = PlayerInfo::getAbilityStatus(); bool foundNew = false; unsigned int found = 0; // number of entries in abilityData which match mEntries for (auto &[id, ability] : abilityData) { auto e = mEntries.find(id); if (e == mEntries.end()) { // found a new ability - abort update and rebuild from scratch foundNew = true; break; } // update progress bar of ability e->second->update(ability.currentMana, ability.neededMana); found++; } // a rebuild is needed when a) the number of abilities changed or b) an existing entry isn't found anymore if (foundNew || found != mEntries.size()) rebuild(abilityData); Window::draw(graphics); } void AbilitiesWindow::rebuild(const std::map &abilityData) { delete_all(mEntries); mEntries.clear(); int vPos = 0; //vertical position of next placed element for (auto &[id, ability] : abilityData) { logger->log("Updating ability GUI for %d", id); AbilityInfo *info = AbilityDB::get(id); if (info) { info->rechargeCurrent = ability.currentMana; info->rechargeNeeded = ability.neededMana; auto *entry = new AbilityEntry(info); entry->setPosition(0, vPos); vPos += entry->getHeight() + 3; add(entry); mEntries[id] = entry; } else { logger->log("Warning: No info available of ability %d", id); } } } AbilityEntry::AbilityEntry(AbilityInfo *info) : mInfo(info) { setSize(ABILITIES_WIDTH, ABILITIES_HEIGHT); if (!info->icon.empty()) mIcon = new Icon(info->icon); else mIcon = new Icon(Theme::getImageFromTheme("unknown-item.png")); mIcon->setPosition(1, 0); add(mIcon); mNameLabel = new Label(info->name); mNameLabel->setPosition(35, 0); add(mNameLabel); mUse = new Button("Use", "use", abilitiesWindow); mUse->setPosition(getWidth() - mUse->getWidth(), 5); add(mUse); if (info->rechargeable) { float progress = (float)info->rechargeCurrent / (float)info->rechargeNeeded; mRechargeBar = new ProgressBar(progress, 100, 10, Theme::PROG_MP); mRechargeBar->setSmoothProgress(false); mRechargeBar->setPosition(mNameLabel->getX(), 18); add(mRechargeBar); } } void AbilityEntry::update(int current, int needed) { if (mRechargeBar) { float progress = (float)current / (float)needed; mRechargeBar->setProgress(progress); } }