mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 18:35:20 +00:00
Merge remote-tracking branch 'scrawl/effects'
This commit is contained in:
commit
5595675664
@ -30,7 +30,7 @@ add_openmw_dir (mwgui
|
|||||||
formatting inventorywindow container hud countdialog tradewindow settingswindow
|
formatting inventorywindow container hud countdialog tradewindow settingswindow
|
||||||
confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
|
confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
|
||||||
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
|
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
|
||||||
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor
|
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwdialogue
|
add_openmw_dir (mwdialogue
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/objects.hpp"
|
||||||
#include "../mwrender/renderinginterface.hpp"
|
#include "../mwrender/renderinginterface.hpp"
|
||||||
|
|
||||||
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
void Potion::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Potion::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
@ -138,6 +140,23 @@ namespace MWClass
|
|||||||
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
|
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
|
||||||
|
|
||||||
info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects);
|
info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects);
|
||||||
|
|
||||||
|
// hide effects the player doesnt know about
|
||||||
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer();
|
||||||
|
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player);
|
||||||
|
int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase();
|
||||||
|
int i=0;
|
||||||
|
for (MWGui::Widgets::SpellEffectList::iterator it = info.effects.begin(); it != info.effects.end(); ++it)
|
||||||
|
{
|
||||||
|
/// \todo this code is duplicated from mwclass/ingredient, put it in a helper function
|
||||||
|
it->mKnown = ( (i == 0 && alchemySkill >= 15)
|
||||||
|
|| (i == 1 && alchemySkill >= 30)
|
||||||
|
|| (i == 2 && alchemySkill >= 45)
|
||||||
|
|| (i == 3 && alchemySkill >= 60));
|
||||||
|
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
info.isPotion = true;
|
info.isPotion = true;
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "inventorywindow.hpp"
|
#include "inventorywindow.hpp"
|
||||||
#include "container.hpp"
|
#include "container.hpp"
|
||||||
#include "console.hpp"
|
#include "console.hpp"
|
||||||
|
#include "spellicons.hpp"
|
||||||
|
|
||||||
using namespace MWGui;
|
using namespace MWGui;
|
||||||
|
|
||||||
@ -32,7 +33,6 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
|
|||||||
, mWeapStatus(NULL)
|
, mWeapStatus(NULL)
|
||||||
, mSpellStatus(NULL)
|
, mSpellStatus(NULL)
|
||||||
, mEffectBox(NULL)
|
, mEffectBox(NULL)
|
||||||
, mEffect1(NULL)
|
|
||||||
, mMinimap(NULL)
|
, mMinimap(NULL)
|
||||||
, mCompass(NULL)
|
, mCompass(NULL)
|
||||||
, mCrosshair(NULL)
|
, mCrosshair(NULL)
|
||||||
@ -86,9 +86,7 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
|
|||||||
mSpellBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked);
|
mSpellBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked);
|
||||||
|
|
||||||
getWidget(mEffectBox, "EffectBox");
|
getWidget(mEffectBox, "EffectBox");
|
||||||
getWidget(mEffect1, "Effect1");
|
|
||||||
mEffectBoxBaseRight = viewSize.width - mEffectBox->getRight();
|
mEffectBoxBaseRight = viewSize.width - mEffectBox->getRight();
|
||||||
mEffectBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked);
|
|
||||||
|
|
||||||
getWidget(mMinimapBox, "MiniMapBox");
|
getWidget(mMinimapBox, "MiniMapBox");
|
||||||
mMinimapBoxBaseRight = viewSize.width - mMinimapBox->getRight();
|
mMinimapBoxBaseRight = viewSize.width - mMinimapBox->getRight();
|
||||||
@ -107,13 +105,18 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
|
|||||||
getWidget(mTriangleCounter, "TriangleCounter");
|
getWidget(mTriangleCounter, "TriangleCounter");
|
||||||
getWidget(mBatchCounter, "BatchCounter");
|
getWidget(mBatchCounter, "BatchCounter");
|
||||||
|
|
||||||
setEffect("icons\\s\\tx_s_chameleon.dds");
|
|
||||||
|
|
||||||
LocalMapBase::init(mMinimap, mCompass, this);
|
LocalMapBase::init(mMinimap, mCompass, this);
|
||||||
|
|
||||||
mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked);
|
mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked);
|
||||||
mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver);
|
mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver);
|
||||||
mMainWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &HUD::onWorldMouseLostFocus);
|
mMainWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &HUD::onWorldMouseLostFocus);
|
||||||
|
|
||||||
|
mSpellIcons = new SpellIcons();
|
||||||
|
}
|
||||||
|
|
||||||
|
HUD::~HUD()
|
||||||
|
{
|
||||||
|
delete mSpellIcons;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HUD::setFpsLevel(int level)
|
void HUD::setFpsLevel(int level)
|
||||||
@ -156,11 +159,6 @@ void HUD::setBatchCount(unsigned int count)
|
|||||||
mBatchCounter->setCaption(boost::lexical_cast<std::string>(count));
|
mBatchCounter->setCaption(boost::lexical_cast<std::string>(count));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HUD::setEffect(const char *img)
|
|
||||||
{
|
|
||||||
mEffect1->setImageTexture(img);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<float>& value)
|
void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<float>& value)
|
||||||
{
|
{
|
||||||
static const char *ids[] =
|
static const char *ids[] =
|
||||||
@ -542,3 +540,8 @@ void HUD::updatePositions()
|
|||||||
mMapVisible = mMinimapBox->getVisible ();
|
mMapVisible = mMinimapBox->getVisible ();
|
||||||
mEffectBox->setPosition((viewSize.width - mEffectBoxBaseRight) - mEffectBox->getWidth() + effectsDx, mEffectBox->getTop());
|
mEffectBox->setPosition((viewSize.width - mEffectBoxBaseRight) - mEffectBox->getWidth() + effectsDx, mEffectBox->getTop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HUD::update()
|
||||||
|
{
|
||||||
|
mSpellIcons->updateWidgets(mEffectBox, true);
|
||||||
|
}
|
||||||
|
@ -8,12 +8,13 @@
|
|||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
class DragAndDrop;
|
class DragAndDrop;
|
||||||
|
class SpellIcons;
|
||||||
|
|
||||||
class HUD : public OEngine::GUI::Layout, public LocalMapBase
|
class HUD : public OEngine::GUI::Layout, public LocalMapBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop);
|
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<float>& value);
|
void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
|
||||||
void setFPS(float fps);
|
void setFPS(float fps);
|
||||||
void setTriangleCount(unsigned int count);
|
void setTriangleCount(unsigned int count);
|
||||||
@ -43,6 +44,10 @@ namespace MWGui
|
|||||||
|
|
||||||
bool getWorldMouseOver() { return mWorldMouseOver; }
|
bool getWorldMouseOver() { return mWorldMouseOver; }
|
||||||
|
|
||||||
|
MyGUI::Widget* getEffectBox() { return mEffectBox; }
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MyGUI::ProgressPtr mHealth, mMagicka, mStamina;
|
MyGUI::ProgressPtr mHealth, mMagicka, mStamina;
|
||||||
MyGUI::Widget* mHealthFrame;
|
MyGUI::Widget* mHealthFrame;
|
||||||
@ -51,7 +56,6 @@ namespace MWGui
|
|||||||
MyGUI::ProgressPtr mWeapStatus, mSpellStatus;
|
MyGUI::ProgressPtr mWeapStatus, mSpellStatus;
|
||||||
MyGUI::Widget *mEffectBox, *mMinimapBox;
|
MyGUI::Widget *mEffectBox, *mMinimapBox;
|
||||||
MyGUI::Button* mMinimapButton;
|
MyGUI::Button* mMinimapButton;
|
||||||
MyGUI::ImageBox* mEffect1;
|
|
||||||
MyGUI::ScrollView* mMinimap;
|
MyGUI::ScrollView* mMinimap;
|
||||||
MyGUI::ImageBox* mCompass;
|
MyGUI::ImageBox* mCompass;
|
||||||
MyGUI::ImageBox* mCrosshair;
|
MyGUI::ImageBox* mCrosshair;
|
||||||
@ -85,6 +89,8 @@ namespace MWGui
|
|||||||
|
|
||||||
bool mWorldMouseOver;
|
bool mWorldMouseOver;
|
||||||
|
|
||||||
|
SpellIcons* mSpellIcons;
|
||||||
|
|
||||||
void onWorldClicked(MyGUI::Widget* _sender);
|
void onWorldClicked(MyGUI::Widget* _sender);
|
||||||
void onWorldMouseOver(MyGUI::Widget* _sender, int x, int y);
|
void onWorldMouseOver(MyGUI::Widget* _sender, int x, int y);
|
||||||
void onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new);
|
void onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new);
|
||||||
|
293
apps/openmw/mwgui/spellicons.cpp
Normal file
293
apps/openmw/mwgui/spellicons.cpp
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
#include "spellicons.hpp"
|
||||||
|
|
||||||
|
#include <MyGUI_Widget.h>
|
||||||
|
#include <MyGUI_Gui.h>
|
||||||
|
#include <MyGUI_ImageBox.h>
|
||||||
|
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
|
#include "../mwworld/player.hpp"
|
||||||
|
#include "../mwworld/class.hpp"
|
||||||
|
#include "../mwworld/inventorystore.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 <int, std::vector<MagicEffectInfo> > effects;
|
||||||
|
|
||||||
|
// add permanent item enchantments
|
||||||
|
MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player);
|
||||||
|
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||||
|
{
|
||||||
|
MWWorld::ContainerStoreIterator it = store.getSlot(slot);
|
||||||
|
if (it == store.end())
|
||||||
|
continue;
|
||||||
|
std::string enchantment = MWWorld::Class::get(*it).getEnchantment(*it);
|
||||||
|
if (enchantment.empty())
|
||||||
|
continue;
|
||||||
|
const ESM::Enchantment* enchant = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(enchantment);
|
||||||
|
if (enchant->mData.mType != ESM::Enchantment::ConstantEffect)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const ESM::EffectList& list = enchant->mEffects;
|
||||||
|
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = list.mList.begin();
|
||||||
|
effectIt != list.mList.end(); ++effectIt)
|
||||||
|
{
|
||||||
|
const ESM::MagicEffect* magicEffect =
|
||||||
|
MWBase::Environment::get().getWorld ()->getStore ().get<ESM::MagicEffect>().find(effectIt->mEffectID);
|
||||||
|
|
||||||
|
MagicEffectInfo effectInfo;
|
||||||
|
effectInfo.mSource = MWWorld::Class::get(*it).getName(*it);
|
||||||
|
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 enchantments with a random magnitude just wouldn't make any sense
|
||||||
|
effectInfo.mMagnitude = effectIt->mMagnMin;
|
||||||
|
effectInfo.mPermanent = true;
|
||||||
|
effects[effectIt->mEffectID].push_back (effectInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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<ESM::Spell>().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;
|
||||||
|
const ESM::EffectList& list = spell->mEffects;
|
||||||
|
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = list.mList.begin();
|
||||||
|
effectIt != list.mList.end(); ++effectIt)
|
||||||
|
{
|
||||||
|
const ESM::MagicEffect* magicEffect =
|
||||||
|
MWBase::Environment::get().getWorld ()->getStore ().get<ESM::MagicEffect>().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)
|
||||||
|
{
|
||||||
|
const ESM::EffectList& list = getSpellEffectList(it->first);
|
||||||
|
|
||||||
|
float timeScale = MWBase::Environment::get().getWorld()->getTimeScaleFactor();
|
||||||
|
|
||||||
|
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = list.mList.begin();
|
||||||
|
effectIt != list.mList.end(); ++effectIt)
|
||||||
|
{
|
||||||
|
const ESM::MagicEffect* magicEffect =
|
||||||
|
MWBase::Environment::get().getWorld ()->getStore ().get<ESM::MagicEffect>().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;
|
||||||
|
|
||||||
|
// ingredients need special casing for their magnitude / duration
|
||||||
|
/// \todo duplicated from ActiveSpells, helper function?
|
||||||
|
if (MWBase::Environment::get().getWorld()->getStore().get<ESM::Ingredient>().search (it->first))
|
||||||
|
{
|
||||||
|
effectInfo.mRemainingTime = effectIt->mDuration * it->second.second +
|
||||||
|
(it->second.first - MWBase::Environment::get().getWorld()->getTimeStamp())*3600/timeScale;
|
||||||
|
|
||||||
|
effectInfo.mMagnitude = static_cast<int> (0.05*it->second.second / (0.1 * magicEffect->mData.mBaseCost));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 <int, std::vector<MagicEffectInfo> >::const_iterator it = effects.begin(); it != effects.end(); ++it)
|
||||||
|
{
|
||||||
|
MyGUI::ImageBox* image;
|
||||||
|
if (mWidgetMap.find(it->first) == mWidgetMap.end())
|
||||||
|
image = parent->createWidget<MyGUI::ImageBox>
|
||||||
|
("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<ESM::MagicEffect>().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<MagicEffectInfo>::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<std::string>(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<int, MyGUI::ImageBox*>::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<ESM::Spell>().search (id))
|
||||||
|
return spell->mName;
|
||||||
|
|
||||||
|
if (const ESM::Potion *potion =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Potion>().search (id))
|
||||||
|
return potion->mName;
|
||||||
|
|
||||||
|
if (const ESM::Ingredient *ingredient =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Ingredient>().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<ESM::Spell>().search (id))
|
||||||
|
return spell->mEffects;
|
||||||
|
|
||||||
|
if (const ESM::Potion *potion =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Potion>().search (id))
|
||||||
|
return potion->mEffects;
|
||||||
|
|
||||||
|
if (const ESM::Ingredient *ingredient =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Ingredient>().search (id))
|
||||||
|
{
|
||||||
|
const ESM::MagicEffect *magicEffect =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().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");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
47
apps/openmw/mwgui/spellicons.hpp
Normal file
47
apps/openmw/mwgui/spellicons.hpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#ifndef MWGUI_SPELLICONS_H
|
||||||
|
#define MWGUI_SPELLICONS_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#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<int, MyGUI::ImageBox*> mWidgetMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -19,6 +19,7 @@
|
|||||||
#include "../mwmechanics/creaturestats.hpp"
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
#include "../mwmechanics/spellsuccess.hpp"
|
#include "../mwmechanics/spellsuccess.hpp"
|
||||||
|
|
||||||
|
#include "spellicons.hpp"
|
||||||
#include "inventorywindow.hpp"
|
#include "inventorywindow.hpp"
|
||||||
#include "confirmationdialog.hpp"
|
#include "confirmationdialog.hpp"
|
||||||
|
|
||||||
@ -51,6 +52,8 @@ namespace MWGui
|
|||||||
, mHeight(0)
|
, mHeight(0)
|
||||||
, mWidth(0)
|
, mWidth(0)
|
||||||
{
|
{
|
||||||
|
mSpellIcons = new SpellIcons();
|
||||||
|
|
||||||
getWidget(mSpellView, "SpellView");
|
getWidget(mSpellView, "SpellView");
|
||||||
getWidget(mEffectBox, "EffectsBox");
|
getWidget(mEffectBox, "EffectsBox");
|
||||||
|
|
||||||
@ -61,6 +64,11 @@ namespace MWGui
|
|||||||
mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &SpellWindow::onWindowResize);
|
mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &SpellWindow::onWindowResize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpellWindow::~SpellWindow()
|
||||||
|
{
|
||||||
|
delete mSpellIcons;
|
||||||
|
}
|
||||||
|
|
||||||
void SpellWindow::onPinToggled()
|
void SpellWindow::onPinToggled()
|
||||||
{
|
{
|
||||||
mWindowManager.setSpellVisibility(!mPinned);
|
mWindowManager.setSpellVisibility(!mPinned);
|
||||||
@ -73,6 +81,8 @@ namespace MWGui
|
|||||||
|
|
||||||
void SpellWindow::updateSpells()
|
void SpellWindow::updateSpells()
|
||||||
{
|
{
|
||||||
|
mSpellIcons->updateWidgets(mEffectBox, false);
|
||||||
|
|
||||||
const int spellHeight = 18;
|
const int spellHeight = 18;
|
||||||
|
|
||||||
mHeight = 0;
|
mHeight = 0;
|
||||||
|
@ -5,10 +5,13 @@
|
|||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
class SpellIcons;
|
||||||
|
|
||||||
class SpellWindow : public WindowPinnableBase
|
class SpellWindow : public WindowPinnableBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SpellWindow(MWBase::WindowManager& parWindowManager);
|
SpellWindow(MWBase::WindowManager& parWindowManager);
|
||||||
|
virtual ~SpellWindow();
|
||||||
|
|
||||||
void updateSpells();
|
void updateSpells();
|
||||||
|
|
||||||
@ -33,6 +36,8 @@ namespace MWGui
|
|||||||
|
|
||||||
virtual void onPinToggled();
|
virtual void onPinToggled();
|
||||||
virtual void open();
|
virtual void open();
|
||||||
|
|
||||||
|
SpellIcons* mSpellIcons;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,9 +127,7 @@ void ToolTips::onFrame(float frameDuration)
|
|||||||
|
|
||||||
Widget* focus = InputManager::getInstance().getMouseFocusWidget();
|
Widget* focus = InputManager::getInstance().getMouseFocusWidget();
|
||||||
if (focus == 0)
|
if (focus == 0)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
IntSize tooltipSize;
|
IntSize tooltipSize;
|
||||||
|
|
||||||
@ -168,6 +166,10 @@ void ToolTips::onFrame(float frameDuration)
|
|||||||
mFocusObject = *focus->getUserData<MWWorld::Ptr>();
|
mFocusObject = *focus->getUserData<MWWorld::Ptr>();
|
||||||
tooltipSize = getToolTipViaPtr(false);
|
tooltipSize = getToolTipViaPtr(false);
|
||||||
}
|
}
|
||||||
|
else if (type == "ToolTipInfo")
|
||||||
|
{
|
||||||
|
tooltipSize = createToolTip(*focus->getUserData<MWGui::ToolTipInfo>());
|
||||||
|
}
|
||||||
else if (type == "AvatarItemSelection")
|
else if (type == "AvatarItemSelection")
|
||||||
{
|
{
|
||||||
MyGUI::IntCoord avatarPos = mWindowManager->getInventoryWindow ()->getAvatarScreenCoord ();
|
MyGUI::IntCoord avatarPos = mWindowManager->getInventoryWindow ()->getAvatarScreenCoord ();
|
||||||
@ -363,7 +365,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
|
|||||||
|
|
||||||
std::string caption = info.caption;
|
std::string caption = info.caption;
|
||||||
std::string image = info.icon;
|
std::string image = info.icon;
|
||||||
int imageSize = (image != "") ? 32 : 0;
|
int imageSize = (image != "") ? info.imageSize : 0;
|
||||||
std::string text = info.text;
|
std::string text = info.text;
|
||||||
|
|
||||||
// remove the first newline (easier this way)
|
// remove the first newline (easier this way)
|
||||||
@ -403,7 +405,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
|
|||||||
|
|
||||||
EditBox* captionWidget = mDynamicToolTipBox->createWidget<EditBox>("NormalText", IntCoord(0, 0, 300, 300), Align::Left | Align::Top, "ToolTipCaption");
|
EditBox* captionWidget = mDynamicToolTipBox->createWidget<EditBox>("NormalText", IntCoord(0, 0, 300, 300), Align::Left | Align::Top, "ToolTipCaption");
|
||||||
captionWidget->setProperty("Static", "true");
|
captionWidget->setProperty("Static", "true");
|
||||||
captionWidget->setCaption(caption);
|
captionWidget->setCaptionWithReplacing(caption);
|
||||||
IntSize captionSize = captionWidget->getTextSize();
|
IntSize captionSize = captionWidget->getTextSize();
|
||||||
|
|
||||||
int captionHeight = std::max(caption != "" ? captionSize.height : 0, imageSize);
|
int captionHeight = std::max(caption != "" ? captionSize.height : 0, imageSize);
|
||||||
@ -411,7 +413,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
|
|||||||
EditBox* textWidget = mDynamicToolTipBox->createWidget<EditBox>("SandText", IntCoord(0, captionHeight+imageCaptionVPadding, 300, 300-captionHeight-imageCaptionVPadding), Align::Stretch, "ToolTipText");
|
EditBox* textWidget = mDynamicToolTipBox->createWidget<EditBox>("SandText", IntCoord(0, captionHeight+imageCaptionVPadding, 300, 300-captionHeight-imageCaptionVPadding), Align::Stretch, "ToolTipText");
|
||||||
textWidget->setProperty("Static", "true");
|
textWidget->setProperty("Static", "true");
|
||||||
textWidget->setProperty("MultiLine", "true");
|
textWidget->setProperty("MultiLine", "true");
|
||||||
textWidget->setProperty("WordWrap", "true");
|
textWidget->setProperty("WordWrap", info.wordWrap ? "true" : "false");
|
||||||
textWidget->setCaptionWithReplacing(text);
|
textWidget->setCaptionWithReplacing(text);
|
||||||
textWidget->setTextAlign(Align::HCenter | Align::Top);
|
textWidget->setTextAlign(Align::HCenter | Align::Top);
|
||||||
IntSize textSize = textWidget->getTextSize();
|
IntSize textSize = textWidget->getTextSize();
|
||||||
|
@ -15,11 +15,14 @@ namespace MWGui
|
|||||||
public:
|
public:
|
||||||
ToolTipInfo()
|
ToolTipInfo()
|
||||||
: isPotion(false)
|
: isPotion(false)
|
||||||
|
, imageSize(32)
|
||||||
|
, wordWrap(true)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::string caption;
|
std::string caption;
|
||||||
std::string text;
|
std::string text;
|
||||||
std::string icon;
|
std::string icon;
|
||||||
|
int imageSize;
|
||||||
|
|
||||||
// enchantment (for cloth, armor, weapons)
|
// enchantment (for cloth, armor, weapons)
|
||||||
std::string enchant;
|
std::string enchant;
|
||||||
@ -28,6 +31,7 @@ namespace MWGui
|
|||||||
Widgets::SpellEffectList effects;
|
Widgets::SpellEffectList effects;
|
||||||
|
|
||||||
bool isPotion; // potions do not show target in the tooltip
|
bool isPotion; // potions do not show target in the tooltip
|
||||||
|
bool wordWrap;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ToolTips : public OEngine::GUI::Layout
|
class ToolTips : public OEngine::GUI::Layout
|
||||||
|
@ -421,17 +421,7 @@ void MWSpellEffect::updateWidgets()
|
|||||||
}
|
}
|
||||||
if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute)
|
if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute)
|
||||||
{
|
{
|
||||||
static const char *attributes[8] = {
|
spellLine += " " + mWindowManager->getGameSettingString(ESM::Attribute::sGmstAttributeIds[mEffectParams.mAttribute], "");
|
||||||
"sAttributeStrength",
|
|
||||||
"sAttributeIntelligence",
|
|
||||||
"sAttributeWillpower",
|
|
||||||
"sAttributeAgility",
|
|
||||||
"sAttributeSpeed",
|
|
||||||
"sAttributeEndurance",
|
|
||||||
"sAttributePersonality",
|
|
||||||
"sAttributeLuck"
|
|
||||||
};
|
|
||||||
spellLine += " " + mWindowManager->getGameSettingString(attributes[mEffectParams.mAttribute], "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
|
if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
#include "imagebutton.hpp"
|
#include "imagebutton.hpp"
|
||||||
#include "exposedwindow.hpp"
|
#include "exposedwindow.hpp"
|
||||||
#include "cursor.hpp"
|
#include "cursor.hpp"
|
||||||
|
#include "spellicons.hpp"
|
||||||
|
|
||||||
using namespace MWGui;
|
using namespace MWGui;
|
||||||
|
|
||||||
@ -270,6 +271,8 @@ void WindowManager::update()
|
|||||||
mHud->setTriangleCount(mTriangleCount);
|
mHud->setTriangleCount(mTriangleCount);
|
||||||
mHud->setBatchCount(mBatchCount);
|
mHud->setBatchCount(mBatchCount);
|
||||||
|
|
||||||
|
mHud->update();
|
||||||
|
|
||||||
mCursor->update();
|
mCursor->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ namespace MWGui
|
|||||||
class EnchantingDialog;
|
class EnchantingDialog;
|
||||||
class TrainingWindow;
|
class TrainingWindow;
|
||||||
class Cursor;
|
class Cursor;
|
||||||
|
class SpellIcons;
|
||||||
|
|
||||||
class WindowManager : public MWBase::WindowManager
|
class WindowManager : public MWBase::WindowManager
|
||||||
{
|
{
|
||||||
|
@ -62,7 +62,7 @@ namespace MWMechanics
|
|||||||
|
|
||||||
for (TIterator iter (begin()); iter!=end(); ++iter)
|
for (TIterator iter (begin()); iter!=end(); ++iter)
|
||||||
{
|
{
|
||||||
std::pair<ESM::EffectList, bool> effects = getEffectList (iter->first);
|
std::pair<ESM::EffectList, std::pair<bool, bool> > effects = getEffectList (iter->first);
|
||||||
|
|
||||||
const MWWorld::TimeStamp& start = iter->second.first;
|
const MWWorld::TimeStamp& start = iter->second.first;
|
||||||
float magnitude = iter->second.second;
|
float magnitude = iter->second.second;
|
||||||
@ -74,7 +74,7 @@ namespace MWMechanics
|
|||||||
{
|
{
|
||||||
int duration = iter->mDuration;
|
int duration = iter->mDuration;
|
||||||
|
|
||||||
if (effects.second)
|
if (effects.second.first)
|
||||||
duration *= magnitude;
|
duration *= magnitude;
|
||||||
|
|
||||||
MWWorld::TimeStamp end = start;
|
MWWorld::TimeStamp end = start;
|
||||||
@ -85,7 +85,7 @@ namespace MWMechanics
|
|||||||
{
|
{
|
||||||
EffectParam param;
|
EffectParam param;
|
||||||
|
|
||||||
if (effects.second)
|
if (effects.second.first)
|
||||||
{
|
{
|
||||||
const ESM::MagicEffect *magicEffect =
|
const ESM::MagicEffect *magicEffect =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find (
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find (
|
||||||
@ -113,15 +113,15 @@ namespace MWMechanics
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<ESM::EffectList, bool> ActiveSpells::getEffectList (const std::string& id) const
|
std::pair<ESM::EffectList, std::pair<bool, bool> > ActiveSpells::getEffectList (const std::string& id) const
|
||||||
{
|
{
|
||||||
if (const ESM::Spell *spell =
|
if (const ESM::Spell *spell =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search (id))
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search (id))
|
||||||
return std::make_pair (spell->mEffects, false);
|
return std::make_pair (spell->mEffects, std::make_pair(false, false));
|
||||||
|
|
||||||
if (const ESM::Potion *potion =
|
if (const ESM::Potion *potion =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Potion>().search (id))
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Potion>().search (id))
|
||||||
return std::make_pair (potion->mEffects, false);
|
return std::make_pair (potion->mEffects, std::make_pair(false, true));
|
||||||
|
|
||||||
if (const ESM::Ingredient *ingredient =
|
if (const ESM::Ingredient *ingredient =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Ingredient>().search (id))
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Ingredient>().search (id))
|
||||||
@ -140,11 +140,12 @@ namespace MWMechanics
|
|||||||
effect.mMagnMin = 1;
|
effect.mMagnMin = 1;
|
||||||
effect.mMagnMax = 1;
|
effect.mMagnMax = 1;
|
||||||
|
|
||||||
std::pair<ESM::EffectList, bool> result;
|
std::pair<ESM::EffectList, std::pair<bool, bool> > result;
|
||||||
|
result.second.second = true;
|
||||||
|
result.second.first = true;
|
||||||
|
|
||||||
result.first.mList.push_back (effect);
|
result.first.mList.push_back (effect);
|
||||||
result.second = true;
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +158,8 @@ namespace MWMechanics
|
|||||||
|
|
||||||
bool ActiveSpells::addSpell (const std::string& id, const MWWorld::Ptr& actor)
|
bool ActiveSpells::addSpell (const std::string& id, const MWWorld::Ptr& actor)
|
||||||
{
|
{
|
||||||
std::pair<ESM::EffectList, bool> effects = getEffectList (id);
|
std::pair<ESM::EffectList, std::pair<bool, bool> > effects = getEffectList (id);
|
||||||
|
bool stacks = effects.second.second;
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
@ -178,7 +180,7 @@ namespace MWMechanics
|
|||||||
|
|
||||||
float random = static_cast<float> (std::rand()) / RAND_MAX;
|
float random = static_cast<float> (std::rand()) / RAND_MAX;
|
||||||
|
|
||||||
if (effects.second)
|
if (effects.second.first)
|
||||||
{
|
{
|
||||||
// ingredient -> special treatment required.
|
// ingredient -> special treatment required.
|
||||||
const CreatureStats& creatureStats = MWWorld::Class::get (actor).getCreatureStats (actor);
|
const CreatureStats& creatureStats = MWWorld::Class::get (actor).getCreatureStats (actor);
|
||||||
@ -194,7 +196,7 @@ namespace MWMechanics
|
|||||||
random *= 0.25 * x;
|
random *= 0.25 * x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iter==mSpells.end())
|
if (iter==mSpells.end() || stacks)
|
||||||
mSpells.insert (std::make_pair (id,
|
mSpells.insert (std::make_pair (id,
|
||||||
std::make_pair (MWBase::Environment::get().getWorld()->getTimeStamp(), random)));
|
std::make_pair (MWBase::Environment::get().getWorld()->getTimeStamp(), random)));
|
||||||
else
|
else
|
||||||
@ -236,7 +238,7 @@ namespace MWMechanics
|
|||||||
|
|
||||||
double ActiveSpells::timeToExpire (const TIterator& iterator) const
|
double ActiveSpells::timeToExpire (const TIterator& iterator) const
|
||||||
{
|
{
|
||||||
std::pair<ESM::EffectList, bool> effects = getEffectList (iterator->first);
|
std::pair<ESM::EffectList, std::pair<bool, bool> > effects = getEffectList (iterator->first);
|
||||||
|
|
||||||
int duration = 0;
|
int duration = 0;
|
||||||
|
|
||||||
@ -247,7 +249,7 @@ namespace MWMechanics
|
|||||||
duration = iter->mDuration;
|
duration = iter->mDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (effects.second)
|
if (effects.second.first)
|
||||||
duration *= iterator->second.second;
|
duration *= iterator->second.second;
|
||||||
|
|
||||||
double scaledDuration = duration *
|
double scaledDuration = duration *
|
||||||
@ -274,4 +276,9 @@ namespace MWMechanics
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ActiveSpells::TContainer& ActiveSpells::getActiveSpells() const
|
||||||
|
{
|
||||||
|
return mSpells;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ namespace MWMechanics
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef std::map<std::string, std::pair<MWWorld::TimeStamp, float> > TContainer;
|
typedef std::multimap<std::string, std::pair<MWWorld::TimeStamp, float> > TContainer;
|
||||||
typedef TContainer::const_iterator TIterator;
|
typedef TContainer::const_iterator TIterator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -44,7 +44,8 @@ namespace MWMechanics
|
|||||||
|
|
||||||
void rebuildEffects() const;
|
void rebuildEffects() const;
|
||||||
|
|
||||||
std::pair<ESM::EffectList, bool> getEffectList (const std::string& id) const;
|
std::pair<ESM::EffectList, std::pair<bool, bool> > getEffectList (const std::string& id) const;
|
||||||
|
///< @return (EffectList, (isIngredient, stacks))
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -63,6 +64,8 @@ namespace MWMechanics
|
|||||||
|
|
||||||
const MagicEffects& getMagicEffects() const;
|
const MagicEffects& getMagicEffects() const;
|
||||||
|
|
||||||
|
const TContainer& getActiveSpells() const;
|
||||||
|
|
||||||
TIterator begin() const;
|
TIterator begin() const;
|
||||||
|
|
||||||
TIterator end() const;
|
TIterator end() const;
|
||||||
|
@ -61,10 +61,7 @@
|
|||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
<!-- Spell effects box -->
|
<!-- Spell effects box -->
|
||||||
<Widget type="Button" skin="HUD_Box" position="199 168 20 20"
|
<Widget type="Widget" skin="HUD_Box_Transparent" position="199 168 20 20" align="Right Bottom" name="EffectBox">
|
||||||
align="Right Bottom" name="EffectBox">
|
|
||||||
<Widget type="ImageBox" skin="ImageBox" position="2 2 16 16" align="Left Bottom"
|
|
||||||
name="Effect1"/>
|
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
<!-- Cell name display when cell changes -->
|
<!-- Cell name display when cell changes -->
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
</Skin>
|
</Skin>
|
||||||
|
|
||||||
|
<Skin name="HUD_Box_Transparent" size="40 40">
|
||||||
|
<Child type="Widget" skin="MW_Box" offset="0 0 40 40" align="ALIGN_LEFT Stretch" name="Client"/>
|
||||||
|
</Skin>
|
||||||
|
|
||||||
<Skin name="HUD_Box_NoTransp" size="40 40">
|
<Skin name="HUD_Box_NoTransp" size="40 40">
|
||||||
|
|
||||||
<!-- Borders -->
|
<!-- Borders -->
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
<Widget type="ExposedWindow" skin="MW_Window_Pinnable" layer="Windows" position="0 0 300 600" name="_Main">
|
<Widget type="ExposedWindow" skin="MW_Window_Pinnable" layer="Windows" position="0 0 300 600" name="_Main">
|
||||||
|
|
||||||
<!-- Effect box-->
|
<!-- Effect box-->
|
||||||
<Widget type="Widget" skin="MW_Box" position="8 8 268 24" align="Left Top HStretch">
|
<Widget type="Widget" skin="MW_Box" position="8 8 268 23" align="Left Top HStretch">
|
||||||
<Widget type="Widget" skin="" position="4 4 260 16" align="Left Top Stretch" name="EffectsBox">
|
<Widget type="Widget" skin="" position="2 1 264 20" align="Left Top Stretch" name="EffectsBox">
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user