diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index c527a645c..cd2dbaddf 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -47,7 +47,13 @@ namespace MWMechanics MagicEffects now = creatureStats.mSpells.getMagicEffects(); - /// \todo add effects from active spells and equipment + if (creature.getTypeName()==typeid (ESM::NPC).name()) + { + MWWorld::InventoryStore& store = MWWorld::Class::get (creature).getInventoryStore (creature); + now += store.getMagicEffects(); + } + + /// \todo add effects from active spells MagicEffects diff = MagicEffects::diff (creatureStats.mMagicEffects, now); diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index 3cb3f3bdc..f677e0dcb 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -90,7 +90,7 @@ namespace MWWorld void clear(); ///< Empty container. - void flagAsModified(); + virtual void flagAsModified(); ///< \attention This function is internal to the world model and should not be called from /// outside. diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 3e535793c..6981aea02 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -4,6 +4,12 @@ #include #include +#include + +#include "../mwbase/environment.hpp" + +#include "../mwworld/world.hpp" + #include "../mwmechanics/npcstats.hpp" #include "class.hpp" @@ -32,13 +38,13 @@ void MWWorld::InventoryStore::initSlots (TSlots& slots) slots.push_back (end()); } -MWWorld::InventoryStore::InventoryStore() +MWWorld::InventoryStore::InventoryStore() : mMagicEffectsUpToDate (false) { initSlots (mSlots); } MWWorld::InventoryStore::InventoryStore (const InventoryStore& store) -: ContainerStore (store) +: ContainerStore (store), mMagicEffectsUpToDate (false) { copySlots (store); } @@ -201,6 +207,38 @@ void MWWorld::InventoryStore::autoEquip (const MWMechanics::NpcStats& stats) } } +const MWMechanics::MagicEffects& MWWorld::InventoryStore::getMagicEffects() +{ + if (!mMagicEffectsUpToDate) + { + mMagicEffects = MWMechanics::MagicEffects(); + + for (TSlots::const_iterator iter (mSlots.begin()); iter!=mSlots.end(); ++iter) + if (*iter!=end()) + { + std::string enchantmentId = MWWorld::Class::get (**iter).getEnchantment (**iter); + + if (!enchantmentId.empty()) + { + const ESM::Enchantment& enchantment = + *MWBase::Environment::get().getWorld()->getStore().enchants.find (enchantmentId); + + if (enchantment.data.type==ESM::Enchantment::ConstantEffect) + mMagicEffects.add (enchantment.effects); + } + } + + mMagicEffectsUpToDate = true; + } + + return mMagicEffects; +} + +void MWWorld::InventoryStore::flagAsModified() +{ + mMagicEffectsUpToDate = false; +} + bool MWWorld::InventoryStore::stacks(const Ptr& ptr1, const Ptr& ptr2) { bool canStack = MWWorld::ContainerStore::stacks(ptr1, ptr2); diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp index 05fc651ee..dcfb21f30 100644 --- a/apps/openmw/mwworld/inventorystore.hpp +++ b/apps/openmw/mwworld/inventorystore.hpp @@ -3,6 +3,8 @@ #include "containerstore.hpp" +#include "../mwmechanics/magiceffects.hpp" + namespace MWMechanics { struct NpcStats; @@ -41,6 +43,9 @@ namespace MWWorld private: + mutable MWMechanics::MagicEffects mMagicEffects; + mutable bool mMagicEffectsUpToDate; + typedef std::vector TSlots; mutable TSlots mSlots; @@ -65,6 +70,15 @@ namespace MWWorld void autoEquip (const MWMechanics::NpcStats& stats); ///< Auto equip items according to stats and item value. + const MWMechanics::MagicEffects& getMagicEffects(); + ///< Return magic effects from worn items. + /// + /// \todo make this const again, after the constness of Ptrs and iterators has been addressed. + + virtual void flagAsModified(); + ///< \attention This function is internal to the world model and should not be called from + /// outside. + protected: virtual bool stacks (const Ptr& ptr1, const Ptr& ptr2);