mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-28 22:09:42 +00:00
Clear temporary effects before unloading actors to prevent absorb effects becoming permanent
This commit is contained in:
parent
161e042e2a
commit
b8e4f18751
12 changed files with 31 additions and 19 deletions
|
@ -56,6 +56,7 @@
|
|||
Feature #4595: Unique object identifier
|
||||
Feature #4737: Handle instance move from one cell to another
|
||||
Feature #5198: Implement "Magic effect expired" event
|
||||
Feature #5454: Clear active spells from actor when he disappears from scene
|
||||
Feature #5489: MCP: Telekinesis fix for activators
|
||||
Feature #5996: Support Lua scripts in OpenMW
|
||||
Feature #6017: Separate persistent and temporary cell references when saving
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace MWBase
|
|||
virtual void add (const MWWorld::Ptr& ptr) = 0;
|
||||
///< Register an object for management
|
||||
|
||||
virtual void remove (const MWWorld::Ptr& ptr) = 0;
|
||||
virtual void remove (const MWWorld::Ptr& ptr, bool keepActive) = 0;
|
||||
///< Deregister an object for management
|
||||
|
||||
virtual void updateCell(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr) = 0;
|
||||
|
|
|
@ -286,7 +286,7 @@ namespace MWBase
|
|||
virtual MWWorld::Ptr moveObject (const MWWorld::Ptr& ptr, const osg::Vec3f& position, bool movePhysics=true, bool moveToActive=false) = 0;
|
||||
///< @return an updated Ptr in case the Ptr's cell changes
|
||||
|
||||
virtual MWWorld::Ptr moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore* newCell, const osg::Vec3f& position, bool movePhysics=true) = 0;
|
||||
virtual MWWorld::Ptr moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore* newCell, const osg::Vec3f& position, bool movePhysics=true, bool keepActive=false) = 0;
|
||||
///< @return an updated Ptr
|
||||
|
||||
virtual MWWorld::Ptr moveObjectBy(const MWWorld::Ptr &ptr, const osg::Vec3f& vec, bool moveToActive, bool ignoreCollisions) = 0;
|
||||
|
|
|
@ -210,6 +210,14 @@ void soulTrap(const MWWorld::Ptr& creature)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void removeTemporaryEffects(const MWWorld::Ptr& ptr)
|
||||
{
|
||||
ptr.getClass().getCreatureStats(ptr).getActiveSpells().purge([] (const auto& spell)
|
||||
{
|
||||
return spell.getType() == ESM::ActiveSpells::Type_Consumable || spell.getType() == ESM::ActiveSpells::Type_Temporary;
|
||||
}, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWMechanics
|
||||
|
@ -1050,7 +1058,7 @@ namespace MWMechanics
|
|||
|
||||
void Actors::addActor (const MWWorld::Ptr& ptr, bool updateImmediately)
|
||||
{
|
||||
removeActor(ptr);
|
||||
removeActor(ptr, true);
|
||||
|
||||
MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr);
|
||||
if (!anim)
|
||||
|
@ -1098,11 +1106,13 @@ namespace MWMechanics
|
|||
ctrl->setVisibility(visibilityRatio);
|
||||
}
|
||||
|
||||
void Actors::removeActor (const MWWorld::Ptr& ptr)
|
||||
void Actors::removeActor (const MWWorld::Ptr& ptr, bool keepActive)
|
||||
{
|
||||
PtrActorMap::iterator iter = mActors.find(ptr);
|
||||
if(iter != mActors.end())
|
||||
{
|
||||
if(!keepActive)
|
||||
removeTemporaryEffects(iter->first);
|
||||
delete iter->second;
|
||||
mActors.erase(iter);
|
||||
}
|
||||
|
@ -1167,6 +1177,7 @@ namespace MWMechanics
|
|||
{
|
||||
if((iter->first.isInCell() && iter->first.getCell()==cellStore) && iter->first != ignore)
|
||||
{
|
||||
removeTemporaryEffects(iter->first);
|
||||
delete iter->second;
|
||||
mActors.erase(iter++);
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ namespace MWMechanics
|
|||
///
|
||||
/// \note Dead actors are ignored.
|
||||
|
||||
void removeActor (const MWWorld::Ptr& ptr);
|
||||
void removeActor (const MWWorld::Ptr& ptr, bool keepActive);
|
||||
///< Deregister an actor for stats management
|
||||
///
|
||||
/// \note Ignored, if \a ptr is not a registered actor.
|
||||
|
|
|
@ -259,11 +259,11 @@ namespace MWMechanics
|
|||
mActors.castSpell(ptr, spellId, manualSpell);
|
||||
}
|
||||
|
||||
void MechanicsManager::remove(const MWWorld::Ptr& ptr)
|
||||
void MechanicsManager::remove(const MWWorld::Ptr& ptr, bool keepActive)
|
||||
{
|
||||
if(ptr == MWBase::Environment::get().getWindowManager()->getWatchedActor())
|
||||
MWBase::Environment::get().getWindowManager()->watchActor(MWWorld::Ptr());
|
||||
mActors.removeActor(ptr);
|
||||
mActors.removeActor(ptr, keepActive);
|
||||
mObjects.removeObject(ptr);
|
||||
}
|
||||
|
||||
|
@ -317,7 +317,7 @@ namespace MWMechanics
|
|||
|
||||
// HACK? The player has been changed, so a new Animation object may
|
||||
// have been made for them. Make sure they're properly updated.
|
||||
mActors.removeActor(ptr);
|
||||
mActors.removeActor(ptr, true);
|
||||
mActors.addActor(ptr, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace MWMechanics
|
|||
void add (const MWWorld::Ptr& ptr) override;
|
||||
///< Register an object for management
|
||||
|
||||
void remove (const MWWorld::Ptr& ptr) override;
|
||||
void remove (const MWWorld::Ptr& ptr, bool keepActive) override;
|
||||
///< Deregister an object for management
|
||||
|
||||
void updateCell(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr) override;
|
||||
|
|
|
@ -55,10 +55,10 @@ namespace MWWorld
|
|||
int cellY;
|
||||
world->positionToIndex(mPosition.pos[0],mPosition.pos[1],cellX,cellY);
|
||||
world->moveObject(actor,world->getExterior(cellX,cellY),
|
||||
mPosition.asVec3());
|
||||
mPosition.asVec3(), true, true);
|
||||
}
|
||||
else
|
||||
world->moveObject(actor,world->getInterior(mCellName),mPosition.asVec3());
|
||||
world->moveObject(actor,world->getInterior(mCellName),mPosition.asVec3(), true, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1010,9 +1010,9 @@ namespace MWWorld
|
|||
}
|
||||
}
|
||||
|
||||
void Scene::removeObjectFromScene (const Ptr& ptr)
|
||||
void Scene::removeObjectFromScene (const Ptr& ptr, bool keepActive)
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->remove (ptr);
|
||||
MWBase::Environment::get().getMechanicsManager()->remove (ptr, keepActive);
|
||||
MWBase::Environment::get().getSoundManager()->stopSound3D (ptr);
|
||||
MWBase::Environment::get().getLuaManager()->objectRemovedFromScene(ptr);
|
||||
if (const auto object = mPhysics->getObject(ptr))
|
||||
|
|
|
@ -161,7 +161,7 @@ namespace MWWorld
|
|||
void addObjectToScene (const Ptr& ptr);
|
||||
///< Add an object that already exists in the world model to the scene.
|
||||
|
||||
void removeObjectFromScene (const Ptr& ptr);
|
||||
void removeObjectFromScene (const Ptr& ptr, bool keepActive = false);
|
||||
///< Remove an object from the scene, but not from the world model.
|
||||
|
||||
void removeFromPagedRefs(const Ptr &ptr);
|
||||
|
|
|
@ -1114,7 +1114,7 @@ namespace MWWorld
|
|||
}
|
||||
}
|
||||
|
||||
MWWorld::Ptr World::moveObject(const Ptr &ptr, CellStore* newCell, const osg::Vec3f& position, bool movePhysics)
|
||||
MWWorld::Ptr World::moveObject(const Ptr &ptr, CellStore* newCell, const osg::Vec3f& position, bool movePhysics, bool keepActive)
|
||||
{
|
||||
ESM::Position pos = ptr.getRefData().getPosition();
|
||||
std::memcpy(pos.pos, &position, sizeof(osg::Vec3f));
|
||||
|
@ -1171,7 +1171,7 @@ namespace MWWorld
|
|||
}
|
||||
else if (!newCellActive && currCellActive)
|
||||
{
|
||||
mWorldScene->removeObjectFromScene(ptr);
|
||||
mWorldScene->removeObjectFromScene(ptr, keepActive);
|
||||
mLocalScripts.remove(ptr);
|
||||
removeContainerScripts (ptr);
|
||||
haveToMove = false;
|
||||
|
@ -2433,7 +2433,7 @@ namespace MWWorld
|
|||
else
|
||||
{
|
||||
// Remove the old CharacterController
|
||||
MWBase::Environment::get().getMechanicsManager()->remove(getPlayerPtr());
|
||||
MWBase::Environment::get().getMechanicsManager()->remove(getPlayerPtr(), true);
|
||||
mNavigator->removeAgent(getPathfindingHalfExtents(getPlayerConstPtr()));
|
||||
mPhysics->remove(getPlayerPtr());
|
||||
mRendering->removePlayer(getPlayerPtr());
|
||||
|
@ -2449,7 +2449,7 @@ namespace MWWorld
|
|||
|
||||
void World::renderPlayer()
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->remove(getPlayerPtr());
|
||||
MWBase::Environment::get().getMechanicsManager()->remove(getPlayerPtr(), true);
|
||||
|
||||
MWWorld::Ptr player = getPlayerPtr();
|
||||
|
||||
|
|
|
@ -373,7 +373,7 @@ namespace MWWorld
|
|||
MWWorld::Ptr moveObject (const Ptr& ptr, const osg::Vec3f& position, bool movePhysics=true, bool moveToActive=false) override;
|
||||
///< @return an updated Ptr in case the Ptr's cell changes
|
||||
|
||||
MWWorld::Ptr moveObject (const Ptr& ptr, CellStore* newCell, const osg::Vec3f& position, bool movePhysics=true) override;
|
||||
MWWorld::Ptr moveObject (const Ptr& ptr, CellStore* newCell, const osg::Vec3f& position, bool movePhysics=true, bool keepActive=false) override;
|
||||
///< @return an updated Ptr
|
||||
|
||||
MWWorld::Ptr moveObjectBy(const Ptr& ptr, const osg::Vec3f& vec, bool moveToActive, bool ignoreCollisions) override;
|
||||
|
|
Loading…
Reference in a new issue