forked from mirror/openmw-tes3mp
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:
parent
2c51e7345f
commit
53f4b92426
9 changed files with 40 additions and 1 deletions
|
@ -187,6 +187,7 @@ namespace MWBase
|
||||||
///Returns the list of actors which are siding with the given actor in fights
|
///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 **/
|
/**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> 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;
|
virtual std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor) = 0;
|
||||||
|
|
||||||
///Returns a list of actors who are fighting the given actor within the fAlarmDistance
|
///Returns a list of actors who are fighting the given actor within the fAlarmDistance
|
||||||
|
|
|
@ -1327,6 +1327,28 @@ namespace MWMechanics
|
||||||
return list;
|
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> Actors::getActorsFollowingIndices(const MWWorld::Ptr &actor)
|
||||||
{
|
{
|
||||||
std::list<int> list;
|
std::list<int> list;
|
||||||
|
|
|
@ -114,6 +114,7 @@ namespace MWMechanics
|
||||||
///Returns the list of actors which are siding with the given actor in fights
|
///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 **/
|
/**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> 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
|
/// Get the list of AiFollow::mFollowIndex for all actors following this target
|
||||||
std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor);
|
std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor);
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
MWWorld::Ptr getTarget();
|
MWWorld::Ptr getTarget();
|
||||||
virtual bool sideWithTarget() const { return true; }
|
virtual bool sideWithTarget() const { return true; }
|
||||||
|
virtual bool followTargetThroughDoors() const { return true; }
|
||||||
|
|
||||||
virtual AiFollow *clone() const;
|
virtual AiFollow *clone() const;
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,11 @@ bool MWMechanics::AiPackage::sideWithTarget() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MWMechanics::AiPackage::followTargetThroughDoors() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
MWMechanics::AiPackage::AiPackage() : mTimer(0.26f) { //mTimer starts at .26 to force initial pathbuild
|
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)
|
/// Return true if having this AiPackage makes the actor side with the target in fights (default false)
|
||||||
virtual bool sideWithTarget() const;
|
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);
|
bool isTargetMagicallyHidden(const MWWorld::Ptr& target);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -1492,6 +1492,11 @@ namespace MWMechanics
|
||||||
return mActors.getActorsSidingWith(actor);
|
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)
|
std::list<int> MechanicsManager::getActorsFollowingIndices(const MWWorld::Ptr& actor)
|
||||||
{
|
{
|
||||||
return mActors.getActorsFollowingIndices(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 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> 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<int> getActorsFollowingIndices(const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
virtual std::list<MWWorld::Ptr> getActorsFighting(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)
|
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)
|
for(std::list<MWWorld::Ptr>::iterator it = followers.begin();it != followers.end();++it)
|
||||||
{
|
{
|
||||||
if (out.insert(*it).second)
|
if (out.insert(*it).second)
|
||||||
|
|
Loading…
Reference in a new issue