1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-16 19:19:56 +00:00

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.
This commit is contained in:
scrawl 2015-12-19 15:11:07 +01:00
parent 2c51e7345f
commit 53f4b92426
9 changed files with 40 additions and 1 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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