diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index f9239d32d4..5db2e6ca29 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -2083,7 +2083,7 @@ namespace MWMechanics for (const auto& package : stats.getAiSequence()) { if (excludeInfighting && !sameActor && package->getTypeId() == AiPackageTypeId::Combat - && package->getTarget() == actorPtr) + && package->targetIs(actorPtr)) break; if (package->sideWithTarget() && !package->getTarget().isEmpty()) { @@ -2103,7 +2103,7 @@ namespace MWMechanics } list.push_back(package->getTarget()); } - else if (package->getTarget() == actorPtr) + else if (package->targetIs(actorPtr)) { list.push_back(iteratedActor); } @@ -2122,7 +2122,7 @@ namespace MWMechanics std::vector list; forEachFollowingPackage( mActors, actorPtr, getPlayer(), [&](const Actor& actor, const std::shared_ptr& package) { - if (package->followTargetThroughDoors() && package->getTarget() == actorPtr) + if (package->followTargetThroughDoors() && package->targetIs(actorPtr)) list.push_back(actor.getPtr()); else if (package->getTypeId() != AiPackageTypeId::Combat && package->getTypeId() != AiPackageTypeId::Wander) @@ -2154,7 +2154,7 @@ namespace MWMechanics std::vector list; forEachFollowingPackage( mActors, actor, getPlayer(), [&](const Actor&, const std::shared_ptr& package) { - if (package->followTargetThroughDoors() && package->getTarget() == actor) + if (package->followTargetThroughDoors() && package->targetIs(actor)) { list.push_back(static_cast(package.get())->getFollowIndex()); return false; @@ -2172,7 +2172,7 @@ namespace MWMechanics std::map map; forEachFollowingPackage( mActors, actor, getPlayer(), [&](const Actor& otherActor, const std::shared_ptr& package) { - if (package->followTargetThroughDoors() && package->getTarget() == actor) + if (package->followTargetThroughDoors() && package->targetIs(actor)) { const int index = static_cast(package.get())->getFollowIndex(); map[index] = otherActor.getPtr(); diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index fe83ce11ab..4bcfc7dedd 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -98,6 +98,26 @@ MWWorld::Ptr MWMechanics::AiPackage::getTarget() const return mCachedTarget; } +bool MWMechanics::AiPackage::targetIs(const MWWorld::Ptr& ptr) const +{ + if (mTargetActorId == -2) + return ptr.isEmpty(); + else if (mTargetActorId == -1) + { + if (mTargetActorRefId.empty()) + { + mTargetActorId = -2; + return ptr.isEmpty(); + } + if (!ptr.isEmpty() && ptr.getCellRef().getRefId() == mTargetActorRefId) + return getTarget() == ptr; + return false; + } + if (ptr.isEmpty() || !ptr.getClass().isActor()) + return false; + return ptr.getClass().getCreatureStats(ptr).getActorId() == mTargetActorId; +} + void MWMechanics::AiPackage::reset() { // reset all members diff --git a/apps/openmw/mwmechanics/aipackage.hpp b/apps/openmw/mwmechanics/aipackage.hpp index 9e13ee9cd5..29a9f9c9ad 100644 --- a/apps/openmw/mwmechanics/aipackage.hpp +++ b/apps/openmw/mwmechanics/aipackage.hpp @@ -87,6 +87,8 @@ namespace MWMechanics /// Get the target actor the AI is targeted at (not applicable to all AI packages, default return empty Ptr) virtual MWWorld::Ptr getTarget() const; + /// Optimized version of getTarget() == ptr + virtual bool targetIs(const MWWorld::Ptr& ptr) const; /// Get the destination point of the AI package (not applicable to all AI packages, default return (0, 0, 0)) virtual osg::Vec3f getDestination(const MWWorld::Ptr& actor) const { return osg::Vec3f(0, 0, 0); } diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index 5d6f25ecb8..82c4b1c0bd 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -176,11 +176,11 @@ namespace MWMechanics if (!isInCombat()) return false; - for (auto it = mPackages.begin(); it != mPackages.end(); ++it) + for (const auto& package : mPackages) { - if ((*it)->getTypeId() == AiPackageTypeId::Combat) + if (package->getTypeId() == AiPackageTypeId::Combat) { - if ((*it)->getTarget() == actor) + if (package->targetIs(actor)) return true; } }