diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index ec7700bee..73baa4e72 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -62,8 +62,9 @@ add_openmw_dir (mwclass ) add_openmw_dir (mwmechanics - mechanicsmanagerimp stat character creaturestats magiceffects movement actors drawstate spells - activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow aiescort aiactivate + mechanicsmanagerimp stat character creaturestats magiceffects movement actors activators + drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow + aiescort aiactivate ) add_openmw_dir (mwbase diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index f7bbd6a9f..ec616fcaf 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -37,21 +37,21 @@ namespace MWBase virtual ~MechanicsManager() {} - virtual void addActor (const MWWorld::Ptr& ptr) = 0; - ///< Register an actor for stats management + virtual void add (const MWWorld::Ptr& ptr) = 0; + ///< Register an object for management - virtual void removeActor (const MWWorld::Ptr& ptr) = 0; - ///< Deregister an actor for stats management + virtual void remove (const MWWorld::Ptr& ptr) = 0; + ///< Deregister an object for management - virtual void dropActors (const MWWorld::CellStore *cellStore) = 0; - ///< Deregister all actors in the given cell. + virtual void drop (const MWWorld::CellStore *cellStore) = 0; + ///< Deregister all objects in the given cell. virtual void watchActor (const MWWorld::Ptr& ptr) = 0; ///< On each update look for changes in a previously registered actor and update the /// GUI accordingly. virtual void update (float duration, bool paused) = 0; - ///< Update actor stats and store desired velocity vectors in \a movement + ///< Update objects /// /// \param paused In game type does not currently advance (this usually means some GUI /// component is up). diff --git a/apps/openmw/mwclass/activator.cpp b/apps/openmw/mwclass/activator.cpp index 292627286..3a60d9c39 100644 --- a/apps/openmw/mwclass/activator.cpp +++ b/apps/openmw/mwclass/activator.cpp @@ -32,7 +32,7 @@ namespace MWClass const std::string model = getModel(ptr); if(!model.empty()) physics.addObject(ptr); - MWBase::Environment::get().getMechanicsManager()->addActor(ptr); + MWBase::Environment::get().getMechanicsManager()->add(ptr); } std::string Activator::getModel(const MWWorld::Ptr &ptr) const diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 7b0f9f728..90dc70715 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -97,7 +97,7 @@ namespace MWClass const std::string model = getModel(ptr); if(!model.empty()) physics.addActor(ptr); - MWBase::Environment::get().getMechanicsManager()->addActor (ptr); + MWBase::Environment::get().getMechanicsManager()->add(ptr); } std::string Creature::getModel(const MWWorld::Ptr &ptr) const diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index cfbc64b87..6069e3b7c 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -142,7 +142,7 @@ namespace MWClass void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { physics.addActor(ptr); - MWBase::Environment::get().getMechanicsManager()->addActor(ptr); + MWBase::Environment::get().getMechanicsManager()->add(ptr); } std::string Npc::getModel(const MWWorld::Ptr &ptr) const diff --git a/apps/openmw/mwmechanics/activators.cpp b/apps/openmw/mwmechanics/activators.cpp new file mode 100644 index 000000000..799d7ecd5 --- /dev/null +++ b/apps/openmw/mwmechanics/activators.cpp @@ -0,0 +1,62 @@ +#include "activators.hpp" + +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" + +namespace MWMechanics +{ + +Activators::Activators() +{ +} + +void Activators::addActivator (const MWWorld::Ptr& ptr) +{ + MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr); + mActivators.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Idle, true))); +} + +void Activators::removeActivator (const MWWorld::Ptr& ptr) +{ + PtrControllerMap::iterator iter = mActivators.find(ptr); + if(iter != mActivators.end()) + mActivators.erase(iter); +} + +void Activators::dropActivators (const MWWorld::Ptr::CellStore *cellStore) +{ + PtrControllerMap::iterator iter = mActivators.begin(); + while(iter != mActivators.end()) + { + if(iter->first.getCell()==cellStore) + mActivators.erase(iter++); + else + ++iter; + } +} + +void Activators::update(float duration, bool paused) +{ + if(!paused) + { + for(PtrControllerMap::iterator iter(mActivators.begin());iter != mActivators.end();++iter) + iter->second.update(duration); + } +} + +void Activators::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number) +{ + PtrControllerMap::iterator iter = mActivators.find(ptr); + if(iter != mActivators.end()) + iter->second.playGroup(groupName, mode, number); +} +void Activators::skipAnimation(const MWWorld::Ptr& ptr) +{ + PtrControllerMap::iterator iter = mActivators.find(ptr); + if(iter != mActivators.end()) + iter->second.skipAnim(); +} + +} diff --git a/apps/openmw/mwmechanics/activators.hpp b/apps/openmw/mwmechanics/activators.hpp new file mode 100644 index 000000000..3ddb0f843 --- /dev/null +++ b/apps/openmw/mwmechanics/activators.hpp @@ -0,0 +1,42 @@ +#ifndef GAME_MWMECHANICS_ACTIVATORS_H +#define GAME_MWMECHANICS_ACTOVATRS_H + +#include +#include + +#include "character.hpp" + +namespace MWWorld +{ + class Ptr; + class CellStore; +} + +namespace MWMechanics +{ + class Activators + { + typedef std::map PtrControllerMap; + PtrControllerMap mActivators; + + public: + Activators(); + + void addActivator (const MWWorld::Ptr& ptr); + ///< Register an activator + + void removeActivator (const MWWorld::Ptr& ptr); + ///< Deregister an activator + + void dropActivators (const MWWorld::CellStore *cellStore); + ///< Deregister all activators in the given cell. + + void update (float duration, bool paused); + ///< Update activator animations + + void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number); + void skipAnimation(const MWWorld::Ptr& ptr); + }; +} + +#endif diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 6c69c457b..98ae3e755 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -166,9 +166,7 @@ namespace MWMechanics void Actors::addActor (const MWWorld::Ptr& ptr) { MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr); - /* Kind of a hack. Activators need a character controller to manage an idle state. */ - if(ptr.getTypeName() == typeid(ESM::Activator).name() || - !MWWorld::Class::get(ptr).getCreatureStats(ptr).isDead()) + if(!MWWorld::Class::get(ptr).getCreatureStats(ptr).isDead()) mActors.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Idle, true))); else mActors.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Dead, false))); @@ -205,11 +203,6 @@ namespace MWMechanics PtrControllerMap::iterator iter(mActors.begin()); while(iter != mActors.end()) { - if(iter->first.getTypeName() == typeid(ESM::Activator).name()) - { - iter++; - continue; - } if(!MWWorld::Class::get(iter->first).getCreatureStats(iter->first).isDead()) { if(iter->second.getState() == CharState_Dead) @@ -304,10 +297,7 @@ namespace MWMechanics void Actors::restoreDynamicStats() { for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter) - { - if(iter->first.getTypeName() != typeid(ESM::Activator).name()) - calculateRestoration(iter->first, 3600); - } + calculateRestoration(iter->first, 3600); } int Actors::countDeaths (const std::string& id) const diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 84145eb08..3e56cbcb1 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -175,33 +175,37 @@ namespace MWMechanics buildPlayer(); } - void MechanicsManager::addActor (const MWWorld::Ptr& ptr) + void MechanicsManager::add(const MWWorld::Ptr& ptr) { - mActors.addActor (ptr); + if(ptr.getTypeName() == typeid(ESM::Activator).name()) + mActivators.addActivator(ptr); + else + mActors.addActor(ptr); } - void MechanicsManager::removeActor (const MWWorld::Ptr& ptr) + void MechanicsManager::remove(const MWWorld::Ptr& ptr) { - if (ptr==mWatched) + if(ptr == mWatched) + mWatched = MWWorld::Ptr(); + mActors.removeActor(ptr); + } + + void MechanicsManager::drop(const MWWorld::CellStore *cellStore) + { + if(!mWatched.isEmpty() && mWatched.getCell() == cellStore) mWatched = MWWorld::Ptr(); - mActors.removeActor (ptr); + mActors.dropActors(cellStore); + mActivators.dropActivators(cellStore); } - void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore) - { - if (!mWatched.isEmpty() && mWatched.getCell()==cellStore) - mWatched = MWWorld::Ptr(); - mActors.dropActors (cellStore); - } - - void MechanicsManager::watchActor (const MWWorld::Ptr& ptr) + void MechanicsManager::watchActor(const MWWorld::Ptr& ptr) { mWatched = ptr; } - void MechanicsManager::update (float duration, bool paused) + void MechanicsManager::update(float duration, bool paused) { if (!mWatched.isEmpty()) { @@ -297,7 +301,8 @@ namespace MWMechanics winMgr->configureSkills (majorSkills, minorSkills); } - mActors.update (duration, paused); + mActors.update(duration, paused); + mActivators.update(duration, paused); } void MechanicsManager::restoreDynamicStats() @@ -631,11 +636,17 @@ namespace MWMechanics void MechanicsManager::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number) { - mActors.playAnimationGroup(ptr, groupName, mode, number); + if(ptr.getTypeName() == typeid(ESM::Activator).name()) + mActivators.playAnimationGroup(ptr, groupName, mode, number); + else + mActors.playAnimationGroup(ptr, groupName, mode, number); } void MechanicsManager::skipAnimation(const MWWorld::Ptr& ptr) { - mActors.skipAnimation(ptr); + if(ptr.getTypeName() == typeid(ESM::Activator).name()) + mActivators.skipAnimation(ptr); + else + mActors.skipAnimation(ptr); } } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index c2bbd96cf..f70242bb9 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -7,6 +7,7 @@ #include "creaturestats.hpp" #include "npcstats.hpp" +#include "activators.hpp" #include "actors.hpp" namespace Ogre @@ -29,6 +30,8 @@ namespace MWMechanics bool mUpdatePlayer; bool mClassSelected; bool mRaceSelected; + + Activators mActivators; Actors mActors; void buildPlayer(); @@ -39,21 +42,21 @@ namespace MWMechanics MechanicsManager(); - virtual void addActor (const MWWorld::Ptr& ptr); - ///< Register an actor for stats management + virtual void add (const MWWorld::Ptr& ptr); + ///< Register an object for management - virtual void removeActor (const MWWorld::Ptr& ptr); - ///< Deregister an actor for stats management + virtual void remove (const MWWorld::Ptr& ptr); + ///< Deregister an object for management - virtual void dropActors (const MWWorld::CellStore *cellStore); - ///< Deregister all actors in the given cell. + virtual void drop(const MWWorld::CellStore *cellStore); + ///< Deregister all objects in the given cell. - virtual void watchActor (const MWWorld::Ptr& ptr); + virtual void watchActor(const MWWorld::Ptr& ptr); ///< On each update look for changes in a previously registered actor and update the /// GUI accordingly. virtual void update (float duration, bool paused); - ///< Update actor stats and store desired velocity vectors in \a movement + ///< Update objects /// /// \param paused In game type does not currently advance (this usually means some GUI /// component is up). diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index e116dca57..47751acb3 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -100,7 +100,7 @@ namespace MWWorld //mPhysics->removeObject("Unnamed_43"); MWBase::Environment::get().getWorld()->getLocalScripts().clearCell (*iter); - MWBase::Environment::get().getMechanicsManager()->dropActors (*iter); + MWBase::Environment::get().getMechanicsManager()->drop (*iter); MWBase::Environment::get().getSoundManager()->stopSound (*iter); mActiveCells.erase(*iter); } @@ -166,7 +166,7 @@ namespace MWWorld MWBase::MechanicsManager *mechMgr = MWBase::Environment::get().getMechanicsManager(); - mechMgr->addActor(player); + mechMgr->add(player); mechMgr->watchActor(player); MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell); @@ -179,7 +179,7 @@ namespace MWWorld mRendering.preCellChange(mCurrentCell); // remove active - MWBase::Environment::get().getMechanicsManager()->removeActor (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + MWBase::Environment::get().getMechanicsManager()->remove(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); CellStoreCollection::iterator active = mActiveCells.begin(); @@ -443,7 +443,7 @@ namespace MWWorld void Scene::removeObjectFromScene (const Ptr& ptr) { - MWBase::Environment::get().getMechanicsManager()->removeActor (ptr); + MWBase::Environment::get().getMechanicsManager()->remove (ptr); MWBase::Environment::get().getSoundManager()->stopSound3D (ptr); mPhysics->removeObject (ptr.getRefData().getHandle()); mRendering.removeObject (ptr); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 0888a4522..a1d713a8a 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -700,6 +700,7 @@ namespace MWWorld if (*currCell != newCell) { if (isPlayer) + { if (!newCell.isExterior()) changeToInteriorCell(Misc::StringUtils::lowerCase(newCell.mCell->mName), pos); else @@ -708,7 +709,9 @@ namespace MWWorld int cellY = newCell.mCell->getGridY(); mWorldScene->changeCell(cellX, cellY, pos, false); } - else { + } + else + { if (!mWorldScene->isCellActive(*currCell)) copyObjectToCell(ptr, newCell, pos); else if (!mWorldScene->isCellActive(newCell)) @@ -732,8 +735,8 @@ namespace MWWorld MWBase::MechanicsManager *mechMgr = MWBase::Environment::get().getMechanicsManager(); - mechMgr->removeActor(ptr); - mechMgr->addActor(copy); + mechMgr->remove(ptr); + mechMgr->add(copy); } else {