Merge branch 'cattlethief' into 'master'
Some checks failed
Build and test / MacOS (push) Has been cancelled
Build and test / Read .env file and expose it as output (push) Has been cancelled
Build and test / Ubuntu (push) Has been cancelled
Build and test / Windows (2019) (push) Has been cancelled
Build and test / Windows (2022) (push) Has been cancelled

Fix AI issues with Command spells

Closes #5331

See merge request OpenMW/openmw!4599
This commit is contained in:
Evil Eye 2025-04-24 12:11:26 +00:00
commit 8b6582100b
5 changed files with 22 additions and 14 deletions

View file

@ -119,6 +119,7 @@ namespace MWMechanics
/// Reset pathfinding state /// Reset pathfinding state
void reset(); void reset();
virtual void resetInitialPosition() {}
/// Return if actor's rotation speed is sufficient to rotate to the destination pathpoint on the run. Otherwise /// Return if actor's rotation speed is sufficient to rotate to the destination pathpoint on the run. Otherwise
/// actor should rotate while standing. /// actor should rotate while standing.

View file

@ -400,7 +400,7 @@ namespace MWMechanics
const auto newTypeId = package.getTypeId(); const auto newTypeId = package.getTypeId();
if (currentTypeId <= MWMechanics::AiPackageTypeId::Wander if (currentTypeId <= MWMechanics::AiPackageTypeId::Wander
&& !hasPackage(MWMechanics::AiPackageTypeId::InternalTravel) && !hasPackage(MWMechanics::AiPackageTypeId::InternalTravel)
&& (newTypeId <= MWMechanics::AiPackageTypeId::Combat || newTypeId == MWMechanics::AiPackageTypeId::Pursue && (newTypeId == MWMechanics::AiPackageTypeId::Combat || newTypeId == MWMechanics::AiPackageTypeId::Pursue
|| newTypeId == MWMechanics::AiPackageTypeId::Cast)) || newTypeId == MWMechanics::AiPackageTypeId::Cast))
{ {
osg::Vec3f dest; osg::Vec3f dest;
@ -444,8 +444,15 @@ namespace MWMechanics
if ((*it)->getPriority() <= package.getPriority()) if ((*it)->getPriority() <= package.getPriority())
{ {
if (cancelOther && isActualAiPackage((*it)->getTypeId()))
mAiState.reset();
onPackageAdded(package); 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; return;
} }
} }
@ -455,11 +462,7 @@ namespace MWMechanics
// Make sure that temporary storage is empty // Make sure that temporary storage is empty
if (cancelOther) if (cancelOther)
{ mAiState.reset();
mAiState.moveIn(std::make_unique<AiCombatStorage>());
mAiState.moveIn(std::make_unique<AiFollowStorage>());
mAiState.moveIn(std::make_unique<AiWanderStorage>());
}
} }
bool MWMechanics::AiSequence::isEmpty() const bool MWMechanics::AiSequence::isEmpty() const

View file

@ -59,12 +59,7 @@ namespace MWMechanics
mStorage = std::make_unique<Derived>(payload); mStorage = std::make_unique<Derived>(payload);
} }
/// \brief takes ownership of the passed object void reset() { mStorage.reset(); }
template <class Derived>
void moveIn(std::unique_ptr<Derived>&& storage)
{
mStorage = std::move(storage);
}
}; };
} }

View file

@ -676,6 +676,13 @@ namespace MWMechanics
stopMovement(actor); stopMovement(actor);
} }
void AiWander::resetInitialPosition()
{
mStoredInitialActorPosition = false;
mPathFinder.clearPath();
mHasDestination = false;
}
bool AiWander::playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect) bool AiWander::playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect)
{ {
if ((GroupIndex_MinIdle <= idleSelect) && (idleSelect <= GroupIndex_MaxIdle)) if ((GroupIndex_MinIdle <= idleSelect) && (idleSelect <= GroupIndex_MaxIdle))
@ -804,7 +811,7 @@ namespace MWMechanics
converter.toWorld(dest); converter.toWorld(dest);
state.moveIn(std::make_unique<AiWanderStorage>()); state.reset();
osg::Vec3f pos(static_cast<float>(dest.mX), static_cast<float>(dest.mY), static_cast<float>(dest.mZ)); osg::Vec3f pos(static_cast<float>(dest.mX), static_cast<float>(dest.mY), static_cast<float>(dest.mZ));
MWBase::Environment::get().getWorld()->moveObject(actor, pos); MWBase::Environment::get().getWorld()->moveObject(actor, pos);

View file

@ -121,6 +121,8 @@ namespace MWMechanics
static std::string_view getIdleGroupName(size_t index) { return sIdleSelectToGroupName[index]; } static std::string_view getIdleGroupName(size_t index) { return sIdleSelectToGroupName[index]; }
void resetInitialPosition() override;
private: private:
void stopWalking(const MWWorld::Ptr& actor); void stopWalking(const MWWorld::Ptr& actor);