From fdabef65a1ccae23007a720a224d6e76dfd3ea12 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 29 Jan 2013 00:19:24 -0800 Subject: [PATCH] Use a method to update an object's cell in the mechanics manager This prevents destroying and recreating the object's character controller (and messing up the current animation) when moving between cells. --- apps/openmw/mwbase/mechanicsmanager.hpp | 3 +++ apps/openmw/mwmechanics/activators.cpp | 11 ++++++++++ apps/openmw/mwmechanics/activators.hpp | 3 +++ apps/openmw/mwmechanics/actors.cpp | 11 ++++++++++ apps/openmw/mwmechanics/actors.hpp | 3 +++ .../mwmechanics/mechanicsmanagerimp.cpp | 9 ++++++++ .../mwmechanics/mechanicsmanagerimp.hpp | 3 +++ apps/openmw/mwworld/worldimp.cpp | 22 +++++-------------- 8 files changed, 49 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index ec616fcaf2..cb9539ef65 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -43,6 +43,9 @@ namespace MWBase virtual void remove (const MWWorld::Ptr& ptr) = 0; ///< Deregister an object for management + virtual void updateCell(const MWWorld::Ptr &ptr) = 0; + ///< Moves an object to a new cell + virtual void drop (const MWWorld::CellStore *cellStore) = 0; ///< Deregister all objects in the given cell. diff --git a/apps/openmw/mwmechanics/activators.cpp b/apps/openmw/mwmechanics/activators.cpp index 799d7ecd55..20b7865f53 100644 --- a/apps/openmw/mwmechanics/activators.cpp +++ b/apps/openmw/mwmechanics/activators.cpp @@ -25,6 +25,17 @@ void Activators::removeActivator (const MWWorld::Ptr& ptr) mActivators.erase(iter); } +void Activators::updateActivatorCell(const MWWorld::Ptr &ptr) +{ + PtrControllerMap::iterator iter = mActivators.find(ptr); + if(iter != mActivators.end()) + { + CharacterController ctrl = iter->second; + mActivators.erase(iter); + mActivators.insert(std::make_pair(ptr, ctrl)); + } +} + void Activators::dropActivators (const MWWorld::Ptr::CellStore *cellStore) { PtrControllerMap::iterator iter = mActivators.begin(); diff --git a/apps/openmw/mwmechanics/activators.hpp b/apps/openmw/mwmechanics/activators.hpp index 3ddb0f8432..5c3eba2206 100644 --- a/apps/openmw/mwmechanics/activators.hpp +++ b/apps/openmw/mwmechanics/activators.hpp @@ -28,6 +28,9 @@ namespace MWMechanics void removeActivator (const MWWorld::Ptr& ptr); ///< Deregister an activator + void updateActivatorCell(const MWWorld::Ptr& ptr); + ///< Updates an activator with a new cell store + void dropActivators (const MWWorld::CellStore *cellStore); ///< Deregister all activators in the given cell. diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 98ae3e7558..27b7ad14e9 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -179,6 +179,17 @@ namespace MWMechanics mActors.erase(iter); } + void Actors::updateActorCell(const MWWorld::Ptr &ptr) + { + PtrControllerMap::iterator iter = mActors.find(ptr); + if(iter != mActors.end()) + { + CharacterController ctrl = iter->second; + mActors.erase(iter); + mActors.insert(std::make_pair(ptr, ctrl)); + } + } + void Actors::dropActors (const MWWorld::Ptr::CellStore *cellStore) { PtrControllerMap::iterator iter = mActors.begin(); diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 6fed9eff73..8c3df6c281 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -53,6 +53,9 @@ namespace MWMechanics /// /// \note Ignored, if \a ptr is not a registered actor. + void updateActorCell(const MWWorld::Ptr& ptr); + ///< Updates an actor with a new cell store + void dropActors (const MWWorld::CellStore *cellStore); ///< Deregister all actors in the given cell. diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 3e56cbcb12..9e76084f5a 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -190,6 +190,15 @@ namespace MWMechanics mActors.removeActor(ptr); } + void MechanicsManager::updateCell(const MWWorld::Ptr &ptr) + { + if(ptr.getTypeName() == typeid(ESM::Activator).name()) + mActivators.updateActivatorCell(ptr); + else + mActors.updateActorCell(ptr); + } + + void MechanicsManager::drop(const MWWorld::CellStore *cellStore) { if(!mWatched.isEmpty() && mWatched.getCell() == cellStore) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index f70242bb98..99010b7ffd 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -48,6 +48,9 @@ namespace MWMechanics virtual void remove (const MWWorld::Ptr& ptr); ///< Deregister an object for management + virtual void updateCell(const MWWorld::Ptr &ptr); + ///< Moves an object to a new cell + virtual void drop(const MWWorld::CellStore *cellStore); ///< Deregister all objects in the given cell. diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index a1d713a8aa..84a6b1b3df 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -729,24 +729,14 @@ namespace MWWorld addContainerScripts(copy, &newCell); mRendering->moveObjectToCell(copy, vec, currCell); + MWBase::MechanicsManager *mechMgr = MWBase::Environment::get().getMechanicsManager(); + mechMgr->updateCell(copy); - if (MWWorld::Class::get(ptr).isActor()) + std::string script = MWWorld::Class::get(ptr).getScript(ptr); + if(!script.empty()) { - MWBase::MechanicsManager *mechMgr = - MWBase::Environment::get().getMechanicsManager(); - - mechMgr->remove(ptr); - mechMgr->add(copy); - } - else - { - std::string script = - MWWorld::Class::get(ptr).getScript(ptr); - if (!script.empty()) - { - mLocalScripts.remove(ptr); - mLocalScripts.add(script, copy); - } + mLocalScripts.remove(ptr); + mLocalScripts.add(script, copy); } } ptr.getRefData().setCount(0);