1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-02 03:15:35 +00:00

Use a separate class to handle activator mechanics

This commit is contained in:
Chris Robinson 2013-01-28 23:39:11 -08:00
parent 487c83e943
commit 8d98f3649c
12 changed files with 168 additions and 56 deletions

View file

@ -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

View file

@ -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).

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,62 @@
#include "activators.hpp"
#include <OgreVector3.h>
#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();
}
}

View file

@ -0,0 +1,42 @@
#ifndef GAME_MWMECHANICS_ACTIVATORS_H
#define GAME_MWMECHANICS_ACTOVATRS_H
#include <string>
#include <map>
#include "character.hpp"
namespace MWWorld
{
class Ptr;
class CellStore;
}
namespace MWMechanics
{
class Activators
{
typedef std::map<MWWorld::Ptr,CharacterController> 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

View file

@ -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

View file

@ -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);
}
}

View file

@ -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).

View file

@ -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);

View file

@ -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
{