diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 7cfeb84c5..e09dfb108 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -30,7 +30,7 @@ add_openmw_dir (mwgui formatting inventorywindow container hud countdialog tradewindow settingswindow confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog - enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor + enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index a2c3a318b..2eb96249c 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -19,6 +19,7 @@ #include "inventorywindow.hpp" #include "container.hpp" #include "console.hpp" +#include "spellicons.hpp" using namespace MWGui; @@ -32,7 +33,6 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop) , mWeapStatus(NULL) , mSpellStatus(NULL) , mEffectBox(NULL) - , mEffect1(NULL) , mMinimap(NULL) , mCompass(NULL) , mCrosshair(NULL) @@ -86,9 +86,7 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop) mSpellBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked); getWidget(mEffectBox, "EffectBox"); - getWidget(mEffect1, "Effect1"); mEffectBoxBaseRight = viewSize.width - mEffectBox->getRight(); - mEffectBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked); getWidget(mMinimapBox, "MiniMapBox"); mMinimapBoxBaseRight = viewSize.width - mMinimapBox->getRight(); @@ -107,13 +105,18 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop) getWidget(mTriangleCounter, "TriangleCounter"); getWidget(mBatchCounter, "BatchCounter"); - setEffect("icons\\s\\tx_s_chameleon.dds"); - LocalMapBase::init(mMinimap, mCompass, this); mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked); mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver); mMainWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &HUD::onWorldMouseLostFocus); + + mSpellIcons = new SpellIcons(); +} + +HUD::~HUD() +{ + delete mSpellIcons; } void HUD::setFpsLevel(int level) @@ -156,11 +159,6 @@ void HUD::setBatchCount(unsigned int count) mBatchCounter->setCaption(boost::lexical_cast(count)); } -void HUD::setEffect(const char *img) -{ - mEffect1->setImageTexture(img); -} - void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat& value) { static const char *ids[] = @@ -542,3 +540,8 @@ void HUD::updatePositions() mMapVisible = mMinimapBox->getVisible (); mEffectBox->setPosition((viewSize.width - mEffectBoxBaseRight) - mEffectBox->getWidth() + effectsDx, mEffectBox->getTop()); } + +void HUD::update() +{ + mSpellIcons->updateWidgets(mEffectBox, true); +} diff --git a/apps/openmw/mwgui/hud.hpp b/apps/openmw/mwgui/hud.hpp index 013ad59f0..39d6eadca 100644 --- a/apps/openmw/mwgui/hud.hpp +++ b/apps/openmw/mwgui/hud.hpp @@ -8,12 +8,13 @@ namespace MWGui { class DragAndDrop; + class SpellIcons; class HUD : public OEngine::GUI::Layout, public LocalMapBase { public: HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop); - void setEffect(const char *img); + virtual ~HUD(); void setValue (const std::string& id, const MWMechanics::DynamicStat& value); void setFPS(float fps); void setTriangleCount(unsigned int count); @@ -43,6 +44,10 @@ namespace MWGui bool getWorldMouseOver() { return mWorldMouseOver; } + MyGUI::Widget* getEffectBox() { return mEffectBox; } + + void update(); + private: MyGUI::ProgressPtr mHealth, mMagicka, mStamina; MyGUI::Widget* mHealthFrame; @@ -51,7 +56,6 @@ namespace MWGui MyGUI::ProgressPtr mWeapStatus, mSpellStatus; MyGUI::Widget *mEffectBox, *mMinimapBox; MyGUI::Button* mMinimapButton; - MyGUI::ImageBox* mEffect1; MyGUI::ScrollView* mMinimap; MyGUI::ImageBox* mCompass; MyGUI::ImageBox* mCrosshair; @@ -85,6 +89,8 @@ namespace MWGui bool mWorldMouseOver; + SpellIcons* mSpellIcons; + void onWorldClicked(MyGUI::Widget* _sender); void onWorldMouseOver(MyGUI::Widget* _sender, int x, int y); void onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new); diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp new file mode 100644 index 000000000..19b2a87ec --- /dev/null +++ b/apps/openmw/mwgui/spellicons.cpp @@ -0,0 +1,246 @@ +#include "spellicons.hpp" + +#include +#include +#include + +#include + +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" + +#include "../mwworld/player.hpp" +#include "../mwworld/class.hpp" + +#include "../mwmechanics/activespells.hpp" +#include "../mwmechanics/creaturestats.hpp" + +#include "tooltips.hpp" + + +namespace MWGui +{ + + void SpellIcons::updateWidgets(MyGUI::Widget *parent, bool adjustSize) + { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + const MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); + + std::map > effects; + + // add permanent spells + const MWMechanics::Spells& spells = stats.getSpells(); + for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it) + { + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find(it->first); + + // these are the spell types that are permanently in effect + if (!(spell->mData.mType == ESM::Spell::ST_Ability) + && !(spell->mData.mType == ESM::Spell::ST_Disease) + && !(spell->mData.mType == ESM::Spell::ST_Curse) + && !(spell->mData.mType == ESM::Spell::ST_Blight)) + continue; + ESM::EffectList list = spell->mEffects; + for (std::vector::const_iterator effectIt = list.mList.begin(); + effectIt != list.mList.end(); ++effectIt) + { + const ESM::MagicEffect* magicEffect = + MWBase::Environment::get().getWorld ()->getStore ().get().find(effectIt->mEffectID); + MagicEffectInfo effectInfo; + effectInfo.mSource = getSpellDisplayName (it->first); + effectInfo.mKey = MWMechanics::EffectKey (effectIt->mEffectID); + if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill) + effectInfo.mKey.mArg = effectIt->mSkill; + else if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute) + effectInfo.mKey.mArg = effectIt->mAttribute; + // just using the min magnitude here, permanent spells with a random magnitude just wouldn't make any sense + effectInfo.mMagnitude = effectIt->mMagnMin; + effectInfo.mPermanent = true; + + effects[effectIt->mEffectID].push_back (effectInfo); + } + } + + // add lasting effect spells/potions etc + const MWMechanics::ActiveSpells::TContainer& activeSpells = stats.getActiveSpells().getActiveSpells(); + for (MWMechanics::ActiveSpells::TContainer::const_iterator it = activeSpells.begin(); + it != activeSpells.end(); ++it) + { + ESM::EffectList list = getSpellEffectList(it->first); + + float timeScale = MWBase::Environment::get().getWorld()->getTimeScaleFactor(); + + for (std::vector::const_iterator effectIt = list.mList.begin(); + effectIt != list.mList.end(); ++effectIt) + { + const ESM::MagicEffect* magicEffect = + MWBase::Environment::get().getWorld ()->getStore ().get().find(effectIt->mEffectID); + + MagicEffectInfo effectInfo; + effectInfo.mSource = getSpellDisplayName (it->first); + effectInfo.mKey = MWMechanics::EffectKey (effectIt->mEffectID); + if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill) + effectInfo.mKey.mArg = effectIt->mSkill; + else if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute) + effectInfo.mKey.mArg = effectIt->mAttribute; + effectInfo.mMagnitude = effectIt->mMagnMin + (effectIt->mMagnMax-effectIt->mMagnMin) * it->second.second; + effectInfo.mRemainingTime = effectIt->mDuration + + (it->second.first - MWBase::Environment::get().getWorld()->getTimeStamp())*3600/timeScale; + + effects[effectIt->mEffectID].push_back (effectInfo); + } + } + + parent->setVisible(effects.size() != 0); + + int w=2; + if (adjustSize) + { + int s = effects.size() * 16+4; + int diff = parent->getWidth() - s; + parent->setSize(s, parent->getHeight()); + parent->setPosition(parent->getLeft()+diff, parent->getTop()); + } + + + for (std::map >::const_iterator it = effects.begin(); it != effects.end(); ++it) + { + MyGUI::ImageBox* image; + if (mWidgetMap.find(it->first) == mWidgetMap.end()) + image = parent->createWidget + ("ImageBox", MyGUI::IntCoord(w,2,16,16), MyGUI::Align::Default); + else + image = mWidgetMap[it->first]; + mWidgetMap[it->first] = image; + image->setPosition(w,2); + image->setVisible(true); + + const ESM::MagicEffect* effect = + MWBase::Environment::get().getWorld ()->getStore ().get().find(it->first); + + std::string icon = effect->mIcon; + icon[icon.size()-3] = 'd'; + icon[icon.size()-2] = 'd'; + icon[icon.size()-1] = 's'; + icon = "icons\\" + icon; + + image->setImageTexture(icon); + w += 16; + + float remainingDuration = 0; + + std::string sourcesDescription; + + const float fadeTime = 5.f; + + for (std::vector::const_iterator effectIt = it->second.begin(); + effectIt != it->second.end(); ++effectIt) + { + if (effectIt != it->second.begin()) + sourcesDescription += "\n"; + + // if at least one of the effect sources is permanent, the effect will never wear off + if (effectIt->mPermanent) + remainingDuration = fadeTime; + else + remainingDuration = std::max(remainingDuration, effectIt->mRemainingTime); + + sourcesDescription += effectIt->mSource; + + if (effect->mData.mFlags & ESM::MagicEffect::TargetSkill) + sourcesDescription += " (" + + MWBase::Environment::get().getWindowManager()->getGameSettingString( + ESM::Skill::sSkillNameIds[effectIt->mKey.mArg], "") + ")"; + if (effect->mData.mFlags & ESM::MagicEffect::TargetAttribute) + sourcesDescription += " (" + + MWBase::Environment::get().getWindowManager()->getGameSettingString( + ESM::Attribute::sGmstAttributeIds[effectIt->mKey.mArg], "") + ")"; + + if (!(effect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) + { + std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", ""); + std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", ""); + + sourcesDescription += ": " + boost::lexical_cast(effectIt->mMagnitude); + sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? pts : pt); + } + } + + std::string name = ESM::MagicEffect::effectIdToString (it->first); + + ToolTipInfo tooltipInfo; + tooltipInfo.caption = "#{" + name + "}"; + tooltipInfo.icon = effect->mIcon; + tooltipInfo.text = sourcesDescription; + tooltipInfo.imageSize = 16; + tooltipInfo.wordWrap = false; + + image->setUserData(tooltipInfo); + image->setUserString("ToolTipType", "ToolTipInfo"); + + // Fade out during the last 5 seconds + image->setAlpha(std::min(remainingDuration/fadeTime, 1.f)); + } + + // hide inactive effects + for (std::map::iterator it = mWidgetMap.begin(); it != mWidgetMap.end(); ++it) + { + if (effects.find(it->first) == effects.end()) + it->second->setVisible(false); + } + + } + + + std::string SpellIcons::getSpellDisplayName (const std::string& id) + { + if (const ESM::Spell *spell = + MWBase::Environment::get().getWorld()->getStore().get().search (id)) + return spell->mName; + + if (const ESM::Potion *potion = + MWBase::Environment::get().getWorld()->getStore().get().search (id)) + return potion->mName; + + if (const ESM::Ingredient *ingredient = + MWBase::Environment::get().getWorld()->getStore().get().search (id)) + return ingredient->mName; + + throw std::runtime_error ("ID " + id + " has no display name"); + } + + ESM::EffectList SpellIcons::getSpellEffectList (const std::string& id) + { + if (const ESM::Spell *spell = + MWBase::Environment::get().getWorld()->getStore().get().search (id)) + return spell->mEffects; + + if (const ESM::Potion *potion = + MWBase::Environment::get().getWorld()->getStore().get().search (id)) + return potion->mEffects; + + if (const ESM::Ingredient *ingredient = + MWBase::Environment::get().getWorld()->getStore().get().search (id)) + { + const ESM::MagicEffect *magicEffect = + MWBase::Environment::get().getWorld()->getStore().get().find ( + ingredient->mData.mEffectID[0]); + + ESM::ENAMstruct effect; + effect.mEffectID = ingredient->mData.mEffectID[0]; + effect.mSkill = ingredient->mData.mSkills[0]; + effect.mAttribute = ingredient->mData.mAttributes[0]; + effect.mRange = 0; + effect.mArea = 0; + effect.mDuration = magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration ? 0 : 1; + effect.mMagnMin = 1; + effect.mMagnMax = 1; + ESM::EffectList result; + result.mList.push_back (effect); + return result; + } + throw std::runtime_error("ID " + id + " does not have effects"); + } + +} diff --git a/apps/openmw/mwgui/spellicons.hpp b/apps/openmw/mwgui/spellicons.hpp new file mode 100644 index 000000000..af600e347 --- /dev/null +++ b/apps/openmw/mwgui/spellicons.hpp @@ -0,0 +1,47 @@ +#ifndef MWGUI_SPELLICONS_H +#define MWGUI_SPELLICONS_H + +#include + +#include "../mwmechanics/magiceffects.hpp" + +namespace MyGUI +{ + class Widget; + class ImageBox; +} +namespace ESM +{ + struct ENAMstruct; + struct EffectList; +} + +namespace MWGui +{ + + // information about a single magic effect source as required for display in the tooltip + struct MagicEffectInfo + { + MagicEffectInfo() : mPermanent(false) {} + std::string mSource; // display name for effect source (e.g. potion name) + MWMechanics::EffectKey mKey; + int mMagnitude; + float mRemainingTime; + bool mPermanent; // the effect is permanent + }; + + class SpellIcons + { + public: + void updateWidgets(MyGUI::Widget* parent, bool adjustSize); + + private: + std::string getSpellDisplayName (const std::string& id); + ESM::EffectList getSpellEffectList (const std::string& id); + + std::map mWidgetMap; + }; + +} + +#endif diff --git a/apps/openmw/mwgui/spellwindow.cpp b/apps/openmw/mwgui/spellwindow.cpp index 47e1d739a..50691d554 100644 --- a/apps/openmw/mwgui/spellwindow.cpp +++ b/apps/openmw/mwgui/spellwindow.cpp @@ -19,6 +19,7 @@ #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/spellsuccess.hpp" +#include "spellicons.hpp" #include "inventorywindow.hpp" #include "confirmationdialog.hpp" @@ -51,6 +52,8 @@ namespace MWGui , mHeight(0) , mWidth(0) { + mSpellIcons = new SpellIcons(); + getWidget(mSpellView, "SpellView"); getWidget(mEffectBox, "EffectsBox"); @@ -61,6 +64,11 @@ namespace MWGui mMainWidget->castType()->eventWindowChangeCoord += MyGUI::newDelegate(this, &SpellWindow::onWindowResize); } + SpellWindow::~SpellWindow() + { + delete mSpellIcons; + } + void SpellWindow::onPinToggled() { mWindowManager.setSpellVisibility(!mPinned); @@ -73,6 +81,8 @@ namespace MWGui void SpellWindow::updateSpells() { + mSpellIcons->updateWidgets(mEffectBox, false); + const int spellHeight = 18; mHeight = 0; diff --git a/apps/openmw/mwgui/spellwindow.hpp b/apps/openmw/mwgui/spellwindow.hpp index caa67fd74..1963d4346 100644 --- a/apps/openmw/mwgui/spellwindow.hpp +++ b/apps/openmw/mwgui/spellwindow.hpp @@ -5,10 +5,13 @@ namespace MWGui { + class SpellIcons; + class SpellWindow : public WindowPinnableBase { public: SpellWindow(MWBase::WindowManager& parWindowManager); + virtual ~SpellWindow(); void updateSpells(); @@ -33,6 +36,8 @@ namespace MWGui virtual void onPinToggled(); virtual void open(); + + SpellIcons* mSpellIcons; }; } diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index c7acf568d..b42f9ac25 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -127,9 +127,7 @@ void ToolTips::onFrame(float frameDuration) Widget* focus = InputManager::getInstance().getMouseFocusWidget(); if (focus == 0) - { return; - } IntSize tooltipSize; @@ -168,6 +166,10 @@ void ToolTips::onFrame(float frameDuration) mFocusObject = *focus->getUserData(); tooltipSize = getToolTipViaPtr(false); } + else if (type == "ToolTipInfo") + { + tooltipSize = createToolTip(*focus->getUserData()); + } else if (type == "AvatarItemSelection") { MyGUI::IntCoord avatarPos = mWindowManager->getInventoryWindow ()->getAvatarScreenCoord (); @@ -363,7 +365,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) std::string caption = info.caption; std::string image = info.icon; - int imageSize = (image != "") ? 32 : 0; + int imageSize = (image != "") ? info.imageSize : 0; std::string text = info.text; // remove the first newline (easier this way) @@ -403,7 +405,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) EditBox* captionWidget = mDynamicToolTipBox->createWidget("NormalText", IntCoord(0, 0, 300, 300), Align::Left | Align::Top, "ToolTipCaption"); captionWidget->setProperty("Static", "true"); - captionWidget->setCaption(caption); + captionWidget->setCaptionWithReplacing(caption); IntSize captionSize = captionWidget->getTextSize(); int captionHeight = std::max(caption != "" ? captionSize.height : 0, imageSize); @@ -411,7 +413,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) EditBox* textWidget = mDynamicToolTipBox->createWidget("SandText", IntCoord(0, captionHeight+imageCaptionVPadding, 300, 300-captionHeight-imageCaptionVPadding), Align::Stretch, "ToolTipText"); textWidget->setProperty("Static", "true"); textWidget->setProperty("MultiLine", "true"); - textWidget->setProperty("WordWrap", "true"); + textWidget->setProperty("WordWrap", info.wordWrap ? "true" : "false"); textWidget->setCaptionWithReplacing(text); textWidget->setTextAlign(Align::HCenter | Align::Top); IntSize textSize = textWidget->getTextSize(); diff --git a/apps/openmw/mwgui/tooltips.hpp b/apps/openmw/mwgui/tooltips.hpp index 4048d0d5a..ba94915cc 100644 --- a/apps/openmw/mwgui/tooltips.hpp +++ b/apps/openmw/mwgui/tooltips.hpp @@ -15,11 +15,14 @@ namespace MWGui public: ToolTipInfo() : isPotion(false) + , imageSize(32) + , wordWrap(true) {} std::string caption; std::string text; std::string icon; + int imageSize; // enchantment (for cloth, armor, weapons) std::string enchant; @@ -28,6 +31,7 @@ namespace MWGui Widgets::SpellEffectList effects; bool isPotion; // potions do not show target in the tooltip + bool wordWrap; }; class ToolTips : public OEngine::GUI::Layout diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index f932c1f03..ade681963 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -421,17 +421,7 @@ void MWSpellEffect::updateWidgets() } if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute) { - static const char *attributes[8] = { - "sAttributeStrength", - "sAttributeIntelligence", - "sAttributeWillpower", - "sAttributeAgility", - "sAttributeSpeed", - "sAttributeEndurance", - "sAttributePersonality", - "sAttributeLuck" - }; - spellLine += " " + mWindowManager->getGameSettingString(attributes[mEffectParams.mAttribute], ""); + spellLine += " " + mWindowManager->getGameSettingString(ESM::Attribute::sGmstAttributeIds[mEffectParams.mAttribute], ""); } if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 1138f62fa..0110171e6 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -54,6 +54,7 @@ #include "imagebutton.hpp" #include "exposedwindow.hpp" #include "cursor.hpp" +#include "spellicons.hpp" using namespace MWGui; @@ -270,6 +271,8 @@ void WindowManager::update() mHud->setTriangleCount(mTriangleCount); mHud->setBatchCount(mBatchCount); + mHud->update(); + mCursor->update(); } diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index e2d64a855..4e8f12160 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -73,6 +73,7 @@ namespace MWGui class EnchantingDialog; class TrainingWindow; class Cursor; + class SpellIcons; class WindowManager : public MWBase::WindowManager { diff --git a/apps/openmw/mwmechanics/activespells.cpp b/apps/openmw/mwmechanics/activespells.cpp index ee1e9da36..933c5094d 100644 --- a/apps/openmw/mwmechanics/activespells.cpp +++ b/apps/openmw/mwmechanics/activespells.cpp @@ -274,4 +274,9 @@ namespace MWMechanics } return false; } + + const ActiveSpells::TContainer& ActiveSpells::getActiveSpells() const + { + return mSpells; + } } diff --git a/apps/openmw/mwmechanics/activespells.hpp b/apps/openmw/mwmechanics/activespells.hpp index 6b832f4cd..05aa2bbdd 100644 --- a/apps/openmw/mwmechanics/activespells.hpp +++ b/apps/openmw/mwmechanics/activespells.hpp @@ -63,6 +63,8 @@ namespace MWMechanics const MagicEffects& getMagicEffects() const; + const TContainer& getActiveSpells() const; + TIterator begin() const; TIterator end() const; diff --git a/files/mygui/openmw_hud.layout b/files/mygui/openmw_hud.layout index e4c6f0765..382bc6dc9 100644 --- a/files/mygui/openmw_hud.layout +++ b/files/mygui/openmw_hud.layout @@ -61,10 +61,7 @@ - - + diff --git a/files/mygui/openmw_hud_box.skin.xml b/files/mygui/openmw_hud_box.skin.xml index 23480e8d3..f847ca51a 100644 --- a/files/mygui/openmw_hud_box.skin.xml +++ b/files/mygui/openmw_hud_box.skin.xml @@ -16,6 +16,10 @@ + + + + diff --git a/files/mygui/openmw_spell_window.layout b/files/mygui/openmw_spell_window.layout index 6c6629605..18a5af352 100644 --- a/files/mygui/openmw_spell_window.layout +++ b/files/mygui/openmw_spell_window.layout @@ -4,8 +4,8 @@ - - + +