Issue #256: consider equipped items when calculating magic effects

This commit is contained in:
Marc Zinnschlag 2012-05-18 15:48:55 +02:00
parent 372efaafd7
commit 124ea77612
4 changed files with 62 additions and 4 deletions

View file

@ -47,7 +47,13 @@ namespace MWMechanics
MagicEffects now = creatureStats.mSpells.getMagicEffects(); 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); MagicEffects diff = MagicEffects::diff (creatureStats.mMagicEffects, now);

View file

@ -90,7 +90,7 @@ namespace MWWorld
void clear(); void clear();
///< Empty container. ///< Empty container.
void flagAsModified(); virtual void flagAsModified();
///< \attention This function is internal to the world model and should not be called from ///< \attention This function is internal to the world model and should not be called from
/// outside. /// outside.

View file

@ -4,6 +4,12 @@
#include <iterator> #include <iterator>
#include <algorithm> #include <algorithm>
#include <components/esm/loadench.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/world.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
#include "class.hpp" #include "class.hpp"
@ -32,13 +38,13 @@ void MWWorld::InventoryStore::initSlots (TSlots& slots)
slots.push_back (end()); slots.push_back (end());
} }
MWWorld::InventoryStore::InventoryStore() MWWorld::InventoryStore::InventoryStore() : mMagicEffectsUpToDate (false)
{ {
initSlots (mSlots); initSlots (mSlots);
} }
MWWorld::InventoryStore::InventoryStore (const InventoryStore& store) MWWorld::InventoryStore::InventoryStore (const InventoryStore& store)
: ContainerStore (store) : ContainerStore (store), mMagicEffectsUpToDate (false)
{ {
copySlots (store); 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 MWWorld::InventoryStore::stacks(const Ptr& ptr1, const Ptr& ptr2)
{ {
bool canStack = MWWorld::ContainerStore::stacks(ptr1, ptr2); bool canStack = MWWorld::ContainerStore::stacks(ptr1, ptr2);

View file

@ -3,6 +3,8 @@
#include "containerstore.hpp" #include "containerstore.hpp"
#include "../mwmechanics/magiceffects.hpp"
namespace MWMechanics namespace MWMechanics
{ {
struct NpcStats; struct NpcStats;
@ -41,6 +43,9 @@ namespace MWWorld
private: private:
mutable MWMechanics::MagicEffects mMagicEffects;
mutable bool mMagicEffectsUpToDate;
typedef std::vector<ContainerStoreIterator> TSlots; typedef std::vector<ContainerStoreIterator> TSlots;
mutable TSlots mSlots; mutable TSlots mSlots;
@ -65,6 +70,15 @@ namespace MWWorld
void autoEquip (const MWMechanics::NpcStats& stats); void autoEquip (const MWMechanics::NpcStats& stats);
///< Auto equip items according to stats and item value. ///< 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: protected:
virtual bool stacks (const Ptr& ptr1, const Ptr& ptr2); virtual bool stacks (const Ptr& ptr1, const Ptr& ptr2);