diff --git a/apps/openmw/mwrender/actoranimation.cpp b/apps/openmw/mwrender/actoranimation.cpp index 5dcd5212c..75e56e9e7 100644 --- a/apps/openmw/mwrender/actoranimation.cpp +++ b/apps/openmw/mwrender/actoranimation.cpp @@ -26,10 +26,8 @@ namespace MWRender { -ActorAnimation::ActorAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem, - bool disableListener) - : Animation(ptr, parentNode, resourceSystem), - mListenerDisabled(disableListener) +ActorAnimation::ActorAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem) + : Animation(ptr, parentNode, resourceSystem) { MWWorld::ContainerStore& store = mPtr.getClass().getContainerStore(mPtr); @@ -41,16 +39,10 @@ ActorAnimation::ActorAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr addHiddenItemLight(*iter, light); } } - - if (!mListenerDisabled) - store.setContListener(this); } ActorAnimation::~ActorAnimation() { - if (!mListenerDisabled && mPtr.getRefData().getCustomData() && mPtr.getClass().getContainerStore(mPtr).getContListener() == this) - mPtr.getClass().getContainerStore(mPtr).setContListener(NULL); - for (ItemLightMap::iterator iter = mItemLights.begin(); iter != mItemLights.end(); ++iter) { mInsert->removeChild(iter->second); diff --git a/apps/openmw/mwrender/actoranimation.hpp b/apps/openmw/mwrender/actoranimation.hpp index 6922603e1..c00f05718 100644 --- a/apps/openmw/mwrender/actoranimation.hpp +++ b/apps/openmw/mwrender/actoranimation.hpp @@ -31,8 +31,7 @@ namespace MWRender class ActorAnimation : public Animation, public MWWorld::ContainerStoreListener { public: - ActorAnimation(const MWWorld::Ptr &ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem, - bool disableListener=false); + ActorAnimation(const MWWorld::Ptr &ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem); virtual ~ActorAnimation(); virtual void itemAdded(const MWWorld::ConstPtr& item, int count); @@ -44,8 +43,6 @@ class ActorAnimation : public Animation, public MWWorld::ContainerStoreListener typedef std::map > ItemLightMap; ItemLightMap mItemLights; - - bool mListenerDisabled; }; } diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 30d3a049e..6f0f3426c 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -464,6 +464,11 @@ namespace MWRender return mPtr; } + MWWorld::Ptr Animation::getPtr() + { + return mPtr; + } + void Animation::setActive(bool active) { if (mSkeleton) diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index f765a7a40..d04760368 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -343,6 +343,8 @@ public: MWWorld::ConstPtr getPtr() const; + MWWorld::Ptr getPtr(); + /// Set active flag on the object skeleton, if one exists. /// @see SceneUtil::Skeleton::setActive void setActive(bool active); diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index 8c0ec3b80..68b5bbad8 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -220,7 +220,7 @@ namespace MWRender { mAnimation.reset(NULL); - mAnimation.reset(new NpcAnimation(mCharacter, mNode, mResourceSystem, true, true, + mAnimation.reset(new NpcAnimation(mCharacter, mNode, mResourceSystem, true, (renderHeadOnly() ? NpcAnimation::VM_HeadOnly : NpcAnimation::VM_Normal))); onSetup(); diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 8f87c46fb..b23edbe1c 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -269,13 +269,6 @@ const NpcAnimation::PartBoneMap NpcAnimation::sPartList = createPartListMap(); NpcAnimation::~NpcAnimation() { - if (!mListenerDisabled - // No need to getInventoryStore() to reset, if none exists - // This is to avoid triggering the listener via ensureCustomData()->autoEquip()->fireEquipmentChanged() - // all from within this destructor. ouch! - && mPtr.getRefData().getCustomData() && mPtr.getClass().getInventoryStore(mPtr).getInvListener() == this) - mPtr.getClass().getInventoryStore(mPtr).setInvListener(NULL, mPtr); - // do not detach (delete) parts yet, this is done so the background thread can handle the deletion for(size_t i = 0;i < ESM::PRT_Count;i++) { @@ -285,9 +278,8 @@ NpcAnimation::~NpcAnimation() } NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem, - bool disableListener, bool disableSounds, ViewMode viewMode, float firstPersonFieldOfView) - : ActorAnimation(ptr, parentNode, resourceSystem, disableListener), - mListenerDisabled(disableListener), + bool disableSounds, ViewMode viewMode, float firstPersonFieldOfView) + : ActorAnimation(ptr, parentNode, resourceSystem), mViewMode(viewMode), mShowWeapons(false), mShowCarriedLeft(true), @@ -309,9 +301,6 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr par } updateNpcBase(); - - if (!disableListener) - mPtr.getClass().getInventoryStore(mPtr).setInvListener(this, mPtr); } void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode) diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 892851890..427a1baf8 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -38,8 +38,6 @@ public: private: static const PartBoneMap sPartList; - bool mListenerDisabled; - // Bounded Parts PartHolderPtr mObjectParts[ESM::PRT_Count]; std::string mSoundIds[ESM::PRT_Count]; @@ -105,7 +103,7 @@ public: * @param disableSounds Same as \a disableListener but for playing items sounds * @param viewMode */ - NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem, bool disableListener = false, + NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem, bool disableSounds = false, ViewMode viewMode=VM_Normal, float firstPersonFieldOfView=55.f); virtual ~NpcAnimation(); diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp index 49c707d1d..23a342735 100644 --- a/apps/openmw/mwrender/objects.cpp +++ b/apps/openmw/mwrender/objects.cpp @@ -92,6 +92,8 @@ void Objects::insertCreature(const MWWorld::Ptr &ptr, const std::string &mesh, b else anim.reset(new CreatureAnimation(ptr, mesh, mResourceSystem)); + ptr.getClass().getContainerStore(ptr).setContListener(static_cast(anim.get())); + mObjects.insert(std::make_pair(ptr, anim.release())); } @@ -102,6 +104,9 @@ void Objects::insertNPC(const MWWorld::Ptr &ptr) std::auto_ptr anim (new NpcAnimation(ptr, osg::ref_ptr(ptr.getRefData().getBaseNode()), mResourceSystem)); + ptr.getClass().getInventoryStore(ptr).setInvListener(anim.get(), ptr); + ptr.getClass().getInventoryStore(ptr).setContListener(anim.get()); + mObjects.insert(std::make_pair(ptr, anim.release())); } @@ -119,6 +124,13 @@ bool Objects::removeObject (const MWWorld::Ptr& ptr) delete iter->second; mObjects.erase(iter); + if (ptr.getClass().isNpc()) + { + MWWorld::InventoryStore& store = ptr.getClass().getInventoryStore(ptr); + store.setInvListener(NULL, ptr); + store.setContListener(NULL); + } + ptr.getRefData().getBaseNode()->getParent(0)->removeChild(ptr.getRefData().getBaseNode()); ptr.getRefData().setBaseNode(NULL); @@ -132,10 +144,19 @@ void Objects::removeCell(const MWWorld::CellStore* store) { for(PtrAnimationMap::iterator iter = mObjects.begin();iter != mObjects.end();) { - if(iter->first.getCell() == store) + MWWorld::Ptr ptr = iter->second->getPtr(); + if(ptr.getCell() == store) { if (mUnrefQueue.get()) mUnrefQueue->push(iter->second->getObjectRoot()); + + if (ptr.getClass().isNpc() && ptr.getRefData().getCustomData()) + { + MWWorld::InventoryStore& store = ptr.getClass().getInventoryStore(ptr); + store.setInvListener(NULL, ptr); + store.setContListener(NULL); + } + delete iter->second; mObjects.erase(iter++); } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 09e1bb026..afdb50926 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -821,7 +821,7 @@ namespace MWRender void RenderingManager::renderPlayer(const MWWorld::Ptr &player) { - mPlayerAnimation.reset(new NpcAnimation(player, player.getRefData().getBaseNode(), mResourceSystem, 0, false, NpcAnimation::VM_Normal, + mPlayerAnimation.reset(new NpcAnimation(player, player.getRefData().getBaseNode(), mResourceSystem, 0, NpcAnimation::VM_Normal, mFirstPersonFieldOfView)); mCamera->setAnimation(mPlayerAnimation.get()); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 3d9300264..9d3110a67 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -31,6 +31,7 @@ #include "../mwmechanics/aiavoiddoor.hpp" //Used to tell actors to avoid doors #include "../mwrender/animation.hpp" +#include "../mwrender/npcanimation.hpp" #include "../mwrender/renderingmanager.hpp" #include "../mwrender/camera.hpp" #include "../mwrender/vismask.hpp" @@ -2212,7 +2213,12 @@ namespace MWWorld { MWBase::Environment::get().getMechanicsManager()->remove(getPlayerPtr()); - mRendering->renderPlayer(getPlayerPtr()); + MWWorld::Ptr player = getPlayerPtr(); + + mRendering->renderPlayer(player); + MWRender::NpcAnimation* anim = static_cast(mRendering->getAnimation(player)); + player.getClass().getInventoryStore(player).setInvListener(anim, player); + player.getClass().getInventoryStore(player).setContListener(anim); scaleObject(getPlayerPtr(), 1.f); // apply race height