예제 #1
0
    void SpellBuyingWindow::addSpell(const ESM::Spell& spell)
    {
        const MWWorld::ESMStore &store =
            MWBase::Environment::get().getWorld()->getStore();

        int price = static_cast<int>(spell.mData.mCost*store.get<ESM::GameSetting>().find("fSpellValueMult")->mValue.getFloat());
        price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true);

        MWWorld::Ptr player = MWMechanics::getPlayer();
        int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);

        // TODO: refactor to use MyGUI::ListBox

        MyGUI::Button* toAdd =
            mSpellsView->createWidget<MyGUI::Button>(
                price <= playerGold ? "SandTextButton" : "SandTextButtonDisabled", // can't use setEnabled since that removes tooltip
                0,
                mCurrentY,
                200,
                sLineHeight,
                MyGUI::Align::Default
            );

        mCurrentY += sLineHeight;

        toAdd->setUserData(price);
        toAdd->setCaptionWithReplacing(spell.mName+"   -   "+MyGUI::utility::toString(price)+"#{sgp}");
        toAdd->setSize(mSpellsView->getWidth(),sLineHeight);
        toAdd->eventMouseWheel += MyGUI::newDelegate(this, &SpellBuyingWindow::onMouseWheel);
        toAdd->setUserString("ToolTipType", "Spell");
        toAdd->setUserString("Spell", spell.mId);
        toAdd->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellBuyingWindow::onSpellButtonClick);
        mSpellsWidgetMap.insert(std::make_pair (toAdd, spell.mId));
    }
예제 #2
0
    void SpellBuyingWindow::addSpell(const std::string& spellId)
    {
        const MWWorld::ESMStore &store =
            MWBase::Environment::get().getWorld()->getStore();

        const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(spellId);
        int price = spell->mData.mCost*store.get<ESM::GameSetting>().find("fSpellValueMult")->getFloat();
        price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true);

        MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
        int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);

        MyGUI::Button* toAdd =
            mSpellsView->createWidget<MyGUI::Button>(
                "SandTextButton",
                0,
                mCurrentY,
                200,
                sLineHeight,
                MyGUI::Align::Default
            );
        toAdd->setEnabled(price<=playerGold);

        mCurrentY += sLineHeight;

        toAdd->setUserData(price);
        toAdd->setCaptionWithReplacing(spell->mName+"   -   "+boost::lexical_cast<std::string>(price)+"#{sgp}");
        toAdd->setSize(toAdd->getTextSize().width,sLineHeight);
        toAdd->eventMouseWheel += MyGUI::newDelegate(this, &SpellBuyingWindow::onMouseWheel);
        toAdd->setUserString("ToolTipType", "Spell");
        toAdd->setUserString("Spell", spellId);
        toAdd->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellBuyingWindow::onSpellButtonClick);
        mSpellsWidgetMap.insert(std::make_pair (toAdd, spellId));
    }
예제 #3
0
    void SpellBuyingWindow::addSpell(const std::string& spellId)
    {
        const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId);
        int price = spell->mData.mCost*MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fSpellValueMult")->getFloat();

        MyGUI::Button* toAdd =
            mSpellsView->createWidget<MyGUI::Button>(
                (price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SpellText",
                0,
                mCurrentY,
                200,
                sLineHeight,
                MyGUI::Align::Default
            );

        mCurrentY += sLineHeight;
        /// \todo price adjustment depending on merchantile skill

        toAdd->setUserData(price);
        toAdd->setCaptionWithReplacing(spell->mName+"   -   "+boost::lexical_cast<std::string>(price)+"#{sgp}");
        toAdd->setSize(toAdd->getTextSize().width,sLineHeight);
        toAdd->eventMouseWheel += MyGUI::newDelegate(this, &SpellBuyingWindow::onMouseWheel);
        toAdd->setUserString("ToolTipType", "Spell");
        toAdd->setUserString("Spell", spellId);
        toAdd->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellBuyingWindow::onSpellButtonClick);
        mSpellsWidgetMap.insert(std::make_pair (toAdd, spellId));
    }
예제 #4
0
파일: list.cpp 프로젝트: 0xmono/openmw
        void MWList::redraw(bool scrollbarShown)
        {
            const int _scrollBarWidth = 20; // fetch this from skin?
            const int scrollBarWidth = scrollbarShown ? _scrollBarWidth : 0;
            const int spacing = 3;
            size_t viewPosition = -mScrollView->getViewOffset().top;

            while (mScrollView->getChildCount())
            {
                MyGUI::Gui::getInstance().destroyWidget(mScrollView->getChildAt(0));
            }

            mItemHeight = 0;
            int i=0;
            for (std::vector<std::string>::const_iterator it=mItems.begin();
                it!=mItems.end(); ++it)
            {
                if (*it != "")
                {
                    MyGUI::Button* button = mScrollView->createWidget<MyGUI::Button>(
                        "MW_ListLine", MyGUI::IntCoord(0, mItemHeight, mScrollView->getSize().width - scrollBarWidth - 2, 24),
                        MyGUI::Align::Left | MyGUI::Align::Top, getName() + "_item_" + (*it));
                    button->setCaption((*it));
                    button->getSubWidgetText()->setWordWrap(true);
                    button->getSubWidgetText()->setTextAlign(MyGUI::Align::Left);
                    button->eventMouseWheel += MyGUI::newDelegate(this, &MWList::onMouseWheel);
                    button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWList::onItemSelected);

                    int height = button->getTextSize().height;
                    button->setSize(MyGUI::IntSize(button->getSize().width, height));
                    button->setUserData(i);

                    mItemHeight += height + spacing;
                }
                else
                {
                    MyGUI::ImageBox* separator = mScrollView->createWidget<MyGUI::ImageBox>("MW_HLine",
                        MyGUI::IntCoord(2, mItemHeight, mScrollView->getWidth() - scrollBarWidth - 4, 18),
                        MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
                    separator->setNeedMouseFocus(false);

                    mItemHeight += 18 + spacing;
                }
                ++i;
            }
            mScrollView->setCanvasSize(mClient->getSize().width, std::max(mItemHeight, mClient->getSize().height));

            if (!scrollbarShown && mItemHeight > mClient->getSize().height)
                redraw(true);

            size_t viewRange = mScrollView->getCanvasSize().height;
            if(viewPosition > viewRange)
                viewPosition = viewRange;
            mScrollView->setViewOffset(MyGUI::IntPoint(0, -viewPosition));
        }
예제 #5
0
    void TravelWindow::addDestination(const std::string& name, ESM::Position pos, bool interior)
    {
        int price;

        const MWWorld::Store<ESM::GameSetting> &gmst =
            MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();

        MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
        int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);

        if (!mPtr.getCell()->isExterior())
        {
            price = gmst.find("fMagesGuildTravel")->mValue.getInteger();
        }
        else
        {
            ESM::Position PlayerPos = player.getRefData().getPosition();
            float d = sqrt(pow(pos.pos[0] - PlayerPos.pos[0], 2) + pow(pos.pos[1] - PlayerPos.pos[1], 2) + pow(pos.pos[2] - PlayerPos.pos[2], 2));
            price = static_cast<int>(d / gmst.find("fTravelMult")->mValue.getFloat());
        }

        price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true);

        // Add price for the travelling followers
        std::set<MWWorld::Ptr> followers;
        MWWorld::ActionTeleport::getFollowersToTeleport(player, followers);

        // Apply followers cost, in vanilla one follower travels for free
        if (Settings::Manager::getBool("charge for every follower travelling", "Game"))
            price *= 1 + static_cast<int>(followers.size());
        else
            price *= std::max(1, static_cast<int>(followers.size()));

        int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2;

        MyGUI::Button* toAdd = mDestinationsView->createWidget<MyGUI::Button>("SandTextButton", 0, mCurrentY, 200, lineHeight, MyGUI::Align::Default);
        toAdd->setEnabled(price <= playerGold);
        mCurrentY += lineHeight;
        if(interior)
            toAdd->setUserString("interior","y");
        else
            toAdd->setUserString("interior","n");

        std::ostringstream oss;
        oss << price;
        toAdd->setUserString("price",oss.str());

        toAdd->setCaptionWithReplacing("#{sCell=" + name + "}   -   " + MyGUI::utility::toString(price)+"#{sgp}");
        toAdd->setSize(mDestinationsView->getWidth(),lineHeight);
        toAdd->eventMouseWheel += MyGUI::newDelegate(this, &TravelWindow::onMouseWheel);
        toAdd->setUserString("Destination", name);
        toAdd->setUserData(pos);
        toAdd->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onTravelButtonClick);
    }
예제 #6
0
    void TrainingWindow::startTraining (MWWorld::Ptr actor)
    {
        mPtr = actor;

        MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
        int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);

        mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(playerGold));

        MWMechanics::NpcStats& npcStats = actor.getClass().getNpcStats (actor);

        // NPC can train you in his best 3 skills
        std::vector< std::pair<int, int> > skills;

        for (int i=0; i<ESM::Skill::Length; ++i)
        {
            int value = npcStats.getSkill (i).getBase ();

            skills.push_back(std::make_pair(i, value));
        }

        std::sort(skills.begin(), skills.end(), sortSkills);

        MyGUI::EnumeratorWidgetPtr widgets = mTrainingOptions->getEnumerator ();
        MyGUI::Gui::getInstance ().destroyWidgets (widgets);

        MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats (player);

        const MWWorld::Store<ESM::GameSetting> &gmst =
            MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();

        for (int i=0; i<3; ++i)
        {
            int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer
                    (mPtr,pcStats.getSkill (skills[i].first).getBase() * gmst.find("iTrainingMod")->getInt (),true);

            MyGUI::Button* button = mTrainingOptions->createWidget<MyGUI::Button>("SandTextButton",
                MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default);

            button->setEnabled(price <= playerGold);
            button->setUserData(skills[i].first);
            button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected);

            button->setCaptionWithReplacing("#{" + ESM::Skill::sSkillNameIds[skills[i].first] + "} - " + boost::lexical_cast<std::string>(price));

            button->setSize(button->getTextSize ().width+12, button->getSize().height);

            ToolTips::createSkillToolTip (button, skills[i].first);
        }

        center();
    }
예제 #7
0
    void EffectEditorBase::updateEffectsView ()
    {
        MyGUI::EnumeratorWidgetPtr oldWidgets = mUsedEffectsView->getEnumerator ();
        MyGUI::Gui::getInstance ().destroyWidgets (oldWidgets);

        MyGUI::IntSize size(0,0);

        int i = 0;
        for (std::vector<ESM::ENAMstruct>::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it)
        {
            Widgets::SpellEffectParams params;
            params.mEffectID = it->mEffectID;
            params.mSkill = it->mSkill;
            params.mAttribute = it->mAttribute;
            params.mDuration = it->mDuration;
            params.mMagnMin = it->mMagnMin;
            params.mMagnMax = it->mMagnMax;
            params.mRange = it->mRange;
            params.mArea = it->mArea;
            params.mIsConstant = mConstantEffect;

            MyGUI::Button* button = mUsedEffectsView->createWidget<MyGUI::Button>("", MyGUI::IntCoord(0, size.height, 0, 24), MyGUI::Align::Default);
            button->setUserData(i);
            button->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellCreationDialog::onEditEffect);
            button->setNeedMouseFocus (true);

            Widgets::MWSpellEffectPtr effect = button->createWidget<Widgets::MWSpellEffect>("MW_EffectImage", MyGUI::IntCoord(0,0,0,24), MyGUI::Align::Default);

            effect->setNeedMouseFocus (false);
            effect->setSpellEffect (params);

            effect->setSize(effect->getRequestedWidth (), 24);
            button->setSize(effect->getRequestedWidth (), 24);

            size.width = std::max(size.width, effect->getRequestedWidth ());
            size.height += 24;
            ++i;
        }

        // Canvas size must be expressed with HScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
        mUsedEffectsView->setVisibleHScroll(false);
        mUsedEffectsView->setCanvasSize(size);
        mUsedEffectsView->setVisibleHScroll(true);

        notifyEffectsChanged();
    }
예제 #8
0
    void EffectEditorBase::updateEffectsView ()
    {
        MyGUI::EnumeratorWidgetPtr oldWidgets = mUsedEffectsView->getEnumerator ();
        MyGUI::Gui::getInstance ().destroyWidgets (oldWidgets);

        MyGUI::IntSize size(0,0);

        int i = 0;
        for (std::vector<ESM::ENAMstruct>::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it)
        {
            Widgets::SpellEffectParams params;
            params.mEffectID = it->mEffectID;
            params.mSkill = it->mSkill;
            params.mAttribute = it->mAttribute;
            params.mDuration = it->mDuration;
            params.mMagnMin = it->mMagnMin;
            params.mMagnMax = it->mMagnMax;
            params.mRange = it->mRange;
            params.mArea = it->mArea;

            MyGUI::Button* button = mUsedEffectsView->createWidget<MyGUI::Button>("", MyGUI::IntCoord(0, size.height, 0, 24), MyGUI::Align::Default);
            button->setUserData(i);
            button->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellCreationDialog::onEditEffect);
            button->setNeedMouseFocus (true);

            Widgets::MWSpellEffectPtr effect = button->createWidget<Widgets::MWSpellEffect>("MW_EffectImage", MyGUI::IntCoord(0,0,0,24), MyGUI::Align::Default);

            effect->setNeedMouseFocus (false);
            effect->setWindowManager (MWBase::Environment::get().getWindowManager ());
            effect->setSpellEffect (params);

            effect->setSize(effect->getRequestedWidth (), 24);
            button->setSize(effect->getRequestedWidth (), 24);

            size.width = std::max(size.width, effect->getRequestedWidth ());
            size.height += 24;
            ++i;
        }

        mUsedEffectsView->setCanvasSize(size);

        notifyEffectsChanged();
    }
예제 #9
0
    void TravelWindow::addDestination(const std::string& name,ESM::Position pos,bool interior)
    {
        int price = 0;

        const MWWorld::Store<ESM::GameSetting> &gmst =
            MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();

        MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
        int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);

        if(interior)
        {
            price = gmst.find("fMagesGuildTravel")->getFloat();
        }
        else
        {
            ESM::Position PlayerPos = player.getRefData().getPosition();
            float d = sqrt( pow(pos.pos[0] - PlayerPos.pos[0],2) + pow(pos.pos[1] - PlayerPos.pos[1],2) + pow(pos.pos[2] - PlayerPos.pos[2],2)   );
            price = d/gmst.find("fTravelMult")->getFloat();
        }

        price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true);

        MyGUI::Button* toAdd = mDestinationsView->createWidget<MyGUI::Button>("SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default);
        toAdd->setEnabled(price<=playerGold);
        mCurrentY += sLineHeight;
        if(interior)
            toAdd->setUserString("interior","y");
        else
            toAdd->setUserString("interior","n");

        std::ostringstream oss;
        oss << price;
        toAdd->setUserString("price",oss.str());

        toAdd->setCaptionWithReplacing("#{sCell=" + name + "}   -   " + boost::lexical_cast<std::string>(price)+"#{sgp}");
        toAdd->setSize(toAdd->getTextSize().width,sLineHeight);
        toAdd->eventMouseWheel += MyGUI::newDelegate(this, &TravelWindow::onMouseWheel);
        toAdd->setUserString("Destination", name);
        toAdd->setUserData(pos);
        toAdd->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onTravelButtonClick);
    }
예제 #10
0
void MerchantRepair::startRepair(const MWWorld::Ptr &actor)
{
    mActor = actor;

    while (mList->getChildCount())
        MyGUI::Gui::getInstance().destroyWidget(mList->getChildAt(0));

    int currentY = 0;

    MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
    int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);

    MWWorld::ContainerStore& store = player.getClass().getContainerStore(player);
    int categories = MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Armor;
    for (MWWorld::ContainerStoreIterator iter (store.begin(categories));
         iter!=store.end(); ++iter)
    {
        if (iter->getClass().hasItemHealth(*iter))
        {
            int maxDurability = iter->getClass().getItemMaxHealth(*iter);
            int durability = iter->getClass().getItemHealth(*iter);
            if (maxDurability == durability)
                continue;

            int basePrice = iter->getClass().getValue(*iter);
            float fRepairMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
                    .find("fRepairMult")->getFloat();

            float p = std::max(1, basePrice);
            float r = std::max(1, static_cast<int>(maxDurability / p));

            int x = ((maxDurability - durability) / r);
            x = (fRepairMult * x);

            int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mActor, x, true);


            std::string name = iter->getClass().getName(*iter)
                    + " - " + boost::lexical_cast<std::string>(price)
                    + MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
                    .find("sgp")->getString();


            MyGUI::Button* button =
                mList->createWidget<MyGUI::Button>("SandTextButton",
                    0,
                    currentY,
                    0,
                    18,
                    MyGUI::Align::Default
                );

            currentY += 18;

            button->setEnabled(price<=playerGold);
            button->setUserString("Price", boost::lexical_cast<std::string>(price));
            button->setUserData(*iter);
            button->setCaptionWithReplacing(name);
            button->setSize(button->getTextSize().width,18);
            button->eventMouseWheel += MyGUI::newDelegate(this, &MerchantRepair::onMouseWheel);
            button->setUserString("ToolTipType", "ItemPtr");
            button->eventMouseButtonClick += MyGUI::newDelegate(this, &MerchantRepair::onRepairButtonClick);
        }
    }
    // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
    mList->setVisibleVScroll(false);
    mList->setCanvasSize (MyGUI::IntSize(mList->getWidth(), std::max(mList->getHeight(), currentY)));
    mList->setVisibleVScroll(true);

    mGoldLabel->setCaptionWithReplacing("#{sGold}: "
        + boost::lexical_cast<std::string>(playerGold));
}
예제 #11
0
    void TrainingWindow::startTraining (MWWorld::Ptr actor)
    {
        mPtr = actor;

        mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()));

        MWMechanics::NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats (actor);

        // NPC can train you in his best 3 skills
        std::vector< std::pair<int, int> > bestSkills;
        bestSkills.push_back (std::make_pair(-1, -1));
        bestSkills.push_back (std::make_pair(-1, -1));
        bestSkills.push_back (std::make_pair(-1, -1));

        for (int i=0; i<ESM::Skill::Length; ++i)
        {
            int value = npcStats.getSkill (i).getBase ();

            for (int j=0; j<3; ++j)
            {
                if (value > bestSkills[j].second)
                {
                    if (j<2)
                    {
                        bestSkills[j+1] = bestSkills[j];
                    }
                    bestSkills[j] = std::make_pair(i, value);
                    break;
                }
            }
        }

        MyGUI::EnumeratorWidgetPtr widgets = mTrainingOptions->getEnumerator ();
        MyGUI::Gui::getInstance ().destroyWidgets (widgets);

        MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ();
        MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);

        const MWWorld::Store<ESM::GameSetting> &gmst =
            MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();

        for (int i=0; i<3; ++i)
        {
            int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer
                    (mPtr,pcStats.getSkill (bestSkills[i].first).getBase() * gmst.find("iTrainingMod")->getInt (),true);

            std::string skin = (price > MWBase::Environment::get().getWindowManager()->getInventoryWindow ()->getPlayerGold ()) ? "SandTextGreyedOut" : "SandTextButton";

            MyGUI::Button* button = mTrainingOptions->createWidget<MyGUI::Button>(skin,
                MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default);

            button->setUserData(bestSkills[i].first);
            button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected);

            button->setCaptionWithReplacing("#{" + ESM::Skill::sSkillNameIds[bestSkills[i].first] + "} - " + boost::lexical_cast<std::string>(price));

            button->setSize(button->getTextSize ().width+12, button->getSize().height);

            ToolTips::createSkillToolTip (button, bestSkills[i].first);
        }

        center();
    }
예제 #12
0
    void SpellWindow::updateSpells()
    {
        mSpellIcons->updateWidgets(mEffectBox, false);

        const int spellHeight = 18;

        mHeight = 0;
        while (mSpellView->getChildCount())
            MyGUI::Gui::getInstance().destroyWidget(mSpellView->getChildAt(0));

        // retrieve all player spells, divide them into Powers and Spells and sort them
        std::vector<std::string> spellList;
        MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
        MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player);
        MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
        MWMechanics::Spells& spells = stats.getSpells();

        for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
            spellList.push_back (it->first);

        const MWWorld::ESMStore &esmStore =
            MWBase::Environment::get().getWorld()->getStore();

        std::vector<std::string> powers;
        std::vector<std::string>::iterator it = spellList.begin();
        while (it != spellList.end())
        {
            const ESM::Spell* spell = esmStore.get<ESM::Spell>().find(*it);

            if (spell->mData.mType == ESM::Spell::ST_Power)
            {
                powers.push_back(*it);
                it = spellList.erase(it);
            }
            else if (spell->mData.mType == ESM::Spell::ST_Ability
                || spell->mData.mType == ESM::Spell::ST_Blight
                || spell->mData.mType == ESM::Spell::ST_Curse
                || spell->mData.mType == ESM::Spell::ST_Disease)
            {
                it = spellList.erase(it);
            }
            else
                ++it;
        }
        std::sort(powers.begin(), powers.end(), sortSpells);
        std::sort(spellList.begin(), spellList.end(), sortSpells);

        // retrieve player's enchanted items
        std::vector<MWWorld::Ptr> items;
        for (MWWorld::ContainerStoreIterator it(store.begin()); it != store.end(); ++it)
        {
            std::string enchantId = it->getClass().getEnchantment(*it);
            if (enchantId != "")
            {
                // only add items with "Cast once" or "Cast on use"
                const ESM::Enchantment* enchant =
                    esmStore.get<ESM::Enchantment>().find(enchantId);

                int type = enchant->mData.mType;
                if (type != ESM::Enchantment::CastOnce
                    && type != ESM::Enchantment::WhenUsed)
                    continue;

                items.push_back(*it);
            }
        }
        std::sort(items.begin(), items.end(), sortItems);


        int height = estimateHeight(items.size() + powers.size() + spellList.size());
        bool scrollVisible = height > mSpellView->getHeight();
        mWidth = mSpellView->getWidth() - (scrollVisible ? 18 : 0);

        // powers
        addGroup("#{sPowers}", "");

        for (std::vector<std::string>::const_iterator it = powers.begin(); it != powers.end(); ++it)
        {
            const ESM::Spell* spell = esmStore.get<ESM::Spell>().find(*it);
            MyGUI::Button* t = mSpellView->createWidget<MyGUI::Button>("SpellText",
                MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);
            t->setCaption(spell->mName);
            t->setTextAlign(MyGUI::Align::Left);
            t->setUserString("ToolTipType", "Spell");
            t->setUserString("Spell", *it);
            t->eventMouseWheel += MyGUI::newDelegate(this, &SpellWindow::onMouseWheel);
            t->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellWindow::onSpellSelected);

            if (*it == MWBase::Environment::get().getWindowManager()->getSelectedSpell())
                t->setStateSelected(true);

            mHeight += spellHeight;
        }

        // other spells
        addGroup("#{sSpells}", "#{sCostChance}");
        for (std::vector<std::string>::const_iterator it = spellList.begin(); it != spellList.end(); ++it)
        {
            const ESM::Spell* spell = esmStore.get<ESM::Spell>().find(*it);
            MyGUI::Button* t = mSpellView->createWidget<MyGUI::Button>("SpellText",
                MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);
            t->setCaption(spell->mName);
            t->setTextAlign(MyGUI::Align::Left);
            t->setUserString("ToolTipType", "Spell");
            t->setUserString("Spell", *it);
            t->eventMouseWheel += MyGUI::newDelegate(this, &SpellWindow::onMouseWheel);
            t->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellWindow::onSpellSelected);
            t->setStateSelected(*it == MWBase::Environment::get().getWindowManager()->getSelectedSpell());

            // cost / success chance
            MyGUI::Button* costChance = mSpellView->createWidget<MyGUI::Button>("SpellText",
                MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);
            std::string cost = boost::lexical_cast<std::string>(spell->mData.mCost);
            std::string chance = boost::lexical_cast<std::string>(int(MWMechanics::getSpellSuccessChance(*it, player)));
            costChance->setCaption(cost + "/" + chance);
            costChance->setTextAlign(MyGUI::Align::Right);
            costChance->setNeedMouseFocus(false);
            costChance->setStateSelected(*it == MWBase::Environment::get().getWindowManager()->getSelectedSpell());

            t->setSize(mWidth-12-costChance->getTextSize().width, t->getHeight());

            mHeight += spellHeight;
        }


        // enchanted items
        addGroup("#{sMagicItem}", "#{sCostCharge}");

        for (std::vector<MWWorld::Ptr>::const_iterator it = items.begin(); it != items.end(); ++it)
        {
            MWWorld::Ptr item = *it;

            const ESM::Enchantment* enchant =
                esmStore.get<ESM::Enchantment>().find(item.getClass().getEnchantment(item));

            // check if the item is currently equipped (will display in a different color)
            bool equipped = false;
            for (int i=0; i < MWWorld::InventoryStore::Slots; ++i)
            {
                if (store.getSlot(i) != store.end() && *store.getSlot(i) == item)
                {
                    equipped = true;
                    break;
                }
            }

            MyGUI::Button* t = mSpellView->createWidget<MyGUI::Button>(equipped ? "SpellText" : "SpellTextUnequipped",
                MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);
            t->setCaption(item.getClass().getName(item));
            t->setTextAlign(MyGUI::Align::Left);
            t->setUserData(item);
            t->setUserString("ToolTipType", "ItemPtr");
            t->setUserString("Equipped", equipped ? "true" : "false");
            t->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellWindow::onEnchantedItemSelected);
            t->eventMouseWheel += MyGUI::newDelegate(this, &SpellWindow::onMouseWheel);
            if (store.getSelectedEnchantItem() != store.end())
                t->setStateSelected(item == *store.getSelectedEnchantItem());


            // cost / charge
            MyGUI::Button* costCharge = mSpellView->createWidget<MyGUI::Button>(equipped ? "SpellText" : "SpellTextUnequipped",
                MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);

            float enchantCost = enchant->mData.mCost;
            int eSkill = player.getClass().getSkill(player, ESM::Skill::Enchant);
            int castCost = std::max(1.f, enchantCost - (enchantCost / 100) * (eSkill - 10));

            std::string cost = boost::lexical_cast<std::string>(castCost);
            int currentCharge = int(item.getCellRef().getEnchantmentCharge());
            if (currentCharge ==  -1)
                currentCharge = enchant->mData.mCharge;
            std::string charge = boost::lexical_cast<std::string>(currentCharge);
            if (enchant->mData.mType == ESM::Enchantment::CastOnce)
            {
                // this is Morrowind behaviour
                cost = "100";
                charge = "100";
            }

            costCharge->setCaption(cost + "/" + charge);
            costCharge->setTextAlign(MyGUI::Align::Right);
            costCharge->setNeedMouseFocus(false);
            if (store.getSelectedEnchantItem() != store.end())
                costCharge->setStateSelected(item == *store.getSelectedEnchantItem());

            t->setSize(mWidth-12-costCharge->getTextSize().width, t->getHeight());

            mHeight += spellHeight;
        }

        // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
        mSpellView->setVisibleVScroll(false);
        mSpellView->setCanvasSize(mSpellView->getWidth(), std::max(mSpellView->getHeight(), mHeight));
        mSpellView->setVisibleVScroll(true);
    }