AiEscort do not follow target through doors

Testing revealed a problem where the guard on the prison ship would incorrectly follow the player outside. Upon further investigation in vanilla MW, it appears that with AiEscort the actor only follows the target through doors once the AiEscort package has completed, *and* no new AI package is running yet.
openmw-38
scrawl 9 years ago
parent 2c51e7345f
commit 53f4b92426

@ -187,6 +187,7 @@ namespace MWBase
///Returns the list of actors which are siding with the given actor in fights
/**ie AiFollow or AiEscort is active and the target is the actor **/
virtual std::list<MWWorld::Ptr> getActorsSidingWith(const MWWorld::Ptr& actor) = 0;
virtual std::list<MWWorld::Ptr> getActorsFollowing(const MWWorld::Ptr& actor) = 0;
virtual std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor) = 0;
///Returns a list of actors who are fighting the given actor within the fAlarmDistance

@ -1327,6 +1327,28 @@ namespace MWMechanics
return list;
}
std::list<MWWorld::Ptr> Actors::getActorsFollowing(const MWWorld::Ptr& actor)
{
std::list<MWWorld::Ptr> list;
for(PtrActorMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
{
const MWWorld::Class &cls = iter->first.getClass();
CreatureStats &stats = cls.getCreatureStats(iter->first);
if (stats.isDead())
continue;
// An actor counts as following if AiFollow is the current AiPackage, or there are only Combat packages before the AiFollow package
for (std::list<MWMechanics::AiPackage*>::const_iterator it = stats.getAiSequence().begin(); it != stats.getAiSequence().end(); ++it)
{
if ((*it)->followTargetThroughDoors() && (*it)->getTarget() == actor)
list.push_back(iter->first);
else if ((*it)->getTypeId() != MWMechanics::AiPackage::TypeIdCombat)
break;
}
}
return list;
}
std::list<int> Actors::getActorsFollowingIndices(const MWWorld::Ptr &actor)
{
std::list<int> list;

@ -114,6 +114,7 @@ namespace MWMechanics
///Returns the list of actors which are siding with the given actor in fights
/**ie AiFollow or AiEscort is active and the target is the actor **/
std::list<MWWorld::Ptr> getActorsSidingWith(const MWWorld::Ptr& actor);
std::list<MWWorld::Ptr> getActorsFollowing(const MWWorld::Ptr& actor);
/// Get the list of AiFollow::mFollowIndex for all actors following this target
std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor);

@ -33,6 +33,7 @@ namespace MWMechanics
MWWorld::Ptr getTarget();
virtual bool sideWithTarget() const { return true; }
virtual bool followTargetThroughDoors() const { return true; }
virtual AiFollow *clone() const;

@ -30,6 +30,11 @@ bool MWMechanics::AiPackage::sideWithTarget() const
return false;
}
bool MWMechanics::AiPackage::followTargetThroughDoors() const
{
return false;
}
MWMechanics::AiPackage::AiPackage() : mTimer(0.26f) { //mTimer starts at .26 to force initial pathbuild
}

@ -75,6 +75,9 @@ namespace MWMechanics
/// Return true if having this AiPackage makes the actor side with the target in fights (default false)
virtual bool sideWithTarget() const;
/// Return true if the actor should follow the target through teleport doors (default false)
virtual bool followTargetThroughDoors() const;
bool isTargetMagicallyHidden(const MWWorld::Ptr& target);
protected:

@ -1492,6 +1492,11 @@ namespace MWMechanics
return mActors.getActorsSidingWith(actor);
}
std::list<MWWorld::Ptr> MechanicsManager::getActorsFollowing(const MWWorld::Ptr& actor)
{
return mActors.getActorsFollowing(actor);
}
std::list<int> MechanicsManager::getActorsFollowingIndices(const MWWorld::Ptr& actor)
{
return mActors.getActorsFollowingIndices(actor);

@ -151,6 +151,7 @@ namespace MWMechanics
virtual void getActorsInRange(const osg::Vec3f &position, float radius, std::vector<MWWorld::Ptr> &objects);
virtual std::list<MWWorld::Ptr> getActorsSidingWith(const MWWorld::Ptr& actor);
virtual std::list<MWWorld::Ptr> getActorsFollowing(const MWWorld::Ptr& actor);
virtual std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor);
virtual std::list<MWWorld::Ptr> getActorsFighting(const MWWorld::Ptr& actor);

@ -13,7 +13,7 @@ namespace
void getFollowers (const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out)
{
std::list<MWWorld::Ptr> followers = MWBase::Environment::get().getMechanicsManager()->getActorsSidingWith(actor);
std::list<MWWorld::Ptr> followers = MWBase::Environment::get().getMechanicsManager()->getActorsFollowing(actor);
for(std::list<MWWorld::Ptr>::iterator it = followers.begin();it != followers.end();++it)
{
if (out.insert(*it).second)

Loading…
Cancel
Save