diff --git a/apps/openmw/mwmechanics/aipackage.hpp b/apps/openmw/mwmechanics/aipackage.hpp index ca33f5dc90..edb62c97c4 100644 --- a/apps/openmw/mwmechanics/aipackage.hpp +++ b/apps/openmw/mwmechanics/aipackage.hpp @@ -119,6 +119,7 @@ namespace MWMechanics /// Reset pathfinding state void reset(); + virtual void resetInitialPosition() {} /// Return if actor's rotation speed is sufficient to rotate to the destination pathpoint on the run. Otherwise /// actor should rotate while standing. diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index 019aaf7c0a..70b94b1eba 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -400,7 +400,7 @@ namespace MWMechanics const auto newTypeId = package.getTypeId(); if (currentTypeId <= MWMechanics::AiPackageTypeId::Wander && !hasPackage(MWMechanics::AiPackageTypeId::InternalTravel) - && (newTypeId <= MWMechanics::AiPackageTypeId::Combat || newTypeId == MWMechanics::AiPackageTypeId::Pursue + && (newTypeId == MWMechanics::AiPackageTypeId::Combat || newTypeId == MWMechanics::AiPackageTypeId::Pursue || newTypeId == MWMechanics::AiPackageTypeId::Cast)) { osg::Vec3f dest; @@ -444,8 +444,15 @@ namespace MWMechanics if ((*it)->getPriority() <= package.getPriority()) { + if (cancelOther && isActualAiPackage((*it)->getTypeId())) + mAiState.reset(); onPackageAdded(package); - mPackages.insert(it, package.clone()); + it = mPackages.insert(it, package.clone()); + if (newTypeId == MWMechanics::AiPackageTypeId::Follow) + { + for (++it; it != mPackages.end(); ++it) + (*it)->resetInitialPosition(); + } return; } } @@ -455,11 +462,7 @@ namespace MWMechanics // Make sure that temporary storage is empty if (cancelOther) - { - mAiState.moveIn(std::make_unique()); - mAiState.moveIn(std::make_unique()); - mAiState.moveIn(std::make_unique()); - } + mAiState.reset(); } bool MWMechanics::AiSequence::isEmpty() const diff --git a/apps/openmw/mwmechanics/aistate.hpp b/apps/openmw/mwmechanics/aistate.hpp index f2ce17fd9c..bb88557b6d 100644 --- a/apps/openmw/mwmechanics/aistate.hpp +++ b/apps/openmw/mwmechanics/aistate.hpp @@ -59,12 +59,7 @@ namespace MWMechanics mStorage = std::make_unique(payload); } - /// \brief takes ownership of the passed object - template - void moveIn(std::unique_ptr&& storage) - { - mStorage = std::move(storage); - } + void reset() { mStorage.reset(); } }; } diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 3c299c1490..dd0c65a2f2 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -676,6 +676,13 @@ namespace MWMechanics stopMovement(actor); } + void AiWander::resetInitialPosition() + { + mStoredInitialActorPosition = false; + mPathFinder.clearPath(); + mHasDestination = false; + } + bool AiWander::playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect) { if ((GroupIndex_MinIdle <= idleSelect) && (idleSelect <= GroupIndex_MaxIdle)) @@ -804,7 +811,7 @@ namespace MWMechanics converter.toWorld(dest); - state.moveIn(std::make_unique()); + state.reset(); osg::Vec3f pos(static_cast(dest.mX), static_cast(dest.mY), static_cast(dest.mZ)); MWBase::Environment::get().getWorld()->moveObject(actor, pos); diff --git a/apps/openmw/mwmechanics/aiwander.hpp b/apps/openmw/mwmechanics/aiwander.hpp index f4d5585fe7..52473ef559 100644 --- a/apps/openmw/mwmechanics/aiwander.hpp +++ b/apps/openmw/mwmechanics/aiwander.hpp @@ -121,6 +121,8 @@ namespace MWMechanics static std::string_view getIdleGroupName(size_t index) { return sIdleSelectToGroupName[index]; } + void resetInitialPosition() override; + private: void stopWalking(const MWWorld::Ptr& actor);