diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 7cfc0861c..31afc126a 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -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 getActorsSidingWith(const MWWorld::Ptr& actor) = 0; + virtual std::list getActorsFollowing(const MWWorld::Ptr& actor) = 0; virtual std::list getActorsFollowingIndices(const MWWorld::Ptr& actor) = 0; ///Returns a list of actors who are fighting the given actor within the fAlarmDistance diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index ee114dff2..7f857a700 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1327,6 +1327,28 @@ namespace MWMechanics return list; } + std::list Actors::getActorsFollowing(const MWWorld::Ptr& actor) + { + std::list 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::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 Actors::getActorsFollowingIndices(const MWWorld::Ptr &actor) { std::list list; diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 494216ba8..0bdf611d2 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -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 getActorsSidingWith(const MWWorld::Ptr& actor); + std::list getActorsFollowing(const MWWorld::Ptr& actor); /// Get the list of AiFollow::mFollowIndex for all actors following this target std::list getActorsFollowingIndices(const MWWorld::Ptr& actor); diff --git a/apps/openmw/mwmechanics/aifollow.hpp b/apps/openmw/mwmechanics/aifollow.hpp index 97140a63a..017ea7122 100644 --- a/apps/openmw/mwmechanics/aifollow.hpp +++ b/apps/openmw/mwmechanics/aifollow.hpp @@ -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; diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index fef10b730..cb2b002f6 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -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 } diff --git a/apps/openmw/mwmechanics/aipackage.hpp b/apps/openmw/mwmechanics/aipackage.hpp index 4b760e4c9..76f89dff4 100644 --- a/apps/openmw/mwmechanics/aipackage.hpp +++ b/apps/openmw/mwmechanics/aipackage.hpp @@ -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: diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 21039cc65..9dafebffa 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1492,6 +1492,11 @@ namespace MWMechanics return mActors.getActorsSidingWith(actor); } + std::list MechanicsManager::getActorsFollowing(const MWWorld::Ptr& actor) + { + return mActors.getActorsFollowing(actor); + } + std::list MechanicsManager::getActorsFollowingIndices(const MWWorld::Ptr& actor) { return mActors.getActorsFollowingIndices(actor); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 279adeeed..603888adc 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -151,6 +151,7 @@ namespace MWMechanics virtual void getActorsInRange(const osg::Vec3f &position, float radius, std::vector &objects); virtual std::list getActorsSidingWith(const MWWorld::Ptr& actor); + virtual std::list getActorsFollowing(const MWWorld::Ptr& actor); virtual std::list getActorsFollowingIndices(const MWWorld::Ptr& actor); virtual std::list getActorsFighting(const MWWorld::Ptr& actor); diff --git a/apps/openmw/mwworld/actionteleport.cpp b/apps/openmw/mwworld/actionteleport.cpp index bcb1fc6d4..031f07258 100644 --- a/apps/openmw/mwworld/actionteleport.cpp +++ b/apps/openmw/mwworld/actionteleport.cpp @@ -13,7 +13,7 @@ namespace void getFollowers (const MWWorld::Ptr& actor, std::set& out) { - std::list followers = MWBase::Environment::get().getMechanicsManager()->getActorsSidingWith(actor); + std::list followers = MWBase::Environment::get().getMechanicsManager()->getActorsFollowing(actor); for(std::list::iterator it = followers.begin();it != followers.end();++it) { if (out.insert(*it).second)