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..4d1e5a0502 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; @@ -432,8 +432,14 @@ namespace MWMechanics } // insert new package in correct place depending on priority + bool resetInitialPositions = false; for (auto it = mPackages.begin(); it != mPackages.end(); ++it) { + if (resetInitialPositions) + { + (*it)->resetInitialPosition(); + continue; + } // We should override current AiCast package, if we try to add a new one. if ((*it)->getTypeId() == MWMechanics::AiPackageTypeId::Cast && package.getTypeId() == MWMechanics::AiPackageTypeId::Cast) @@ -444,22 +450,25 @@ namespace MWMechanics if ((*it)->getPriority() <= package.getPriority()) { + if (cancelOther && isActualAiPackage((*it)->getTypeId())) + mAiState.reset(); onPackageAdded(package); - mPackages.insert(it, package.clone()); - return; + it = mPackages.insert(it, package.clone()); + if (newTypeId == MWMechanics::AiPackageTypeId::Follow) + resetInitialPositions = true; + else + return; } } + if (resetInitialPositions) + return; onPackageAdded(package); mPackages.push_back(package.clone()); // 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 aed7214f4d..39525e6e65 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);