Optimize AI package target comparisons

ini_importer_tests
Evil Eye 11 months ago
parent 8ed7a5319d
commit 340d1423c6

@ -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<MWWorld::Ptr> list;
forEachFollowingPackage(
mActors, actorPtr, getPlayer(), [&](const Actor& actor, const std::shared_ptr<AiPackage>& 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<int> list;
forEachFollowingPackage(
mActors, actor, getPlayer(), [&](const Actor&, const std::shared_ptr<AiPackage>& package) {
if (package->followTargetThroughDoors() && package->getTarget() == actor)
if (package->followTargetThroughDoors() && package->targetIs(actor))
{
list.push_back(static_cast<const AiFollow*>(package.get())->getFollowIndex());
return false;
@ -2172,7 +2172,7 @@ namespace MWMechanics
std::map<int, MWWorld::Ptr> map;
forEachFollowingPackage(
mActors, actor, getPlayer(), [&](const Actor& otherActor, const std::shared_ptr<AiPackage>& package) {
if (package->followTargetThroughDoors() && package->getTarget() == actor)
if (package->followTargetThroughDoors() && package->targetIs(actor))
{
const int index = static_cast<const AiFollow*>(package.get())->getFollowIndex();
map[index] = otherActor.getPtr();

@ -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

@ -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); }

@ -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;
}
}

Loading…
Cancel
Save