diff --git a/apps/openmw/mwmechanics/aipackage.hpp b/apps/openmw/mwmechanics/aipackage.hpp index 06b4adf61..d9a7fa386 100644 --- a/apps/openmw/mwmechanics/aipackage.hpp +++ b/apps/openmw/mwmechanics/aipackage.hpp @@ -79,6 +79,9 @@ 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; + /// 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); }; + /// Return true if having this AiPackage makes the actor side with the target in fights (default false) virtual bool sideWithTarget() const; diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 3ad45e2c3..2e832dc3f 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -335,9 +335,18 @@ namespace MWMechanics bool AiWander::getRepeat() const { - return mRepeat; + return mRepeat; } + osg::Vec3f AiWander::getDestination(const MWWorld::Ptr& actor) const + { + if (mHasDestination) + return mDestination; + + const ESM::Pathgrid::Point currentPosition = actor.getRefData().getPosition().pos; + const osg::Vec3f currentPositionVec3f = osg::Vec3f(currentPosition.mX, currentPosition.mY, currentPosition.mZ); + return currentPositionVec3f; + } bool AiWander::isPackageCompleted(const MWWorld::Ptr& actor, AiWanderStorage& storage) { @@ -346,8 +355,8 @@ namespace MWMechanics // End package if duration is complete if (mRemainingDuration <= 0) { - stopWalking(actor, storage); - return true; + stopWalking(actor, storage); + return true; } } // if get here, not yet completed diff --git a/apps/openmw/mwmechanics/aiwander.hpp b/apps/openmw/mwmechanics/aiwander.hpp index 3f69d107d..d96d93165 100644 --- a/apps/openmw/mwmechanics/aiwander.hpp +++ b/apps/openmw/mwmechanics/aiwander.hpp @@ -47,9 +47,11 @@ namespace MWMechanics virtual void writeState(ESM::AiSequence::AiSequence &sequence) const; virtual void fastForward(const MWWorld::Ptr& actor, AiState& state); - + bool getRepeat() const; - + + osg::Vec3f getDestination(const MWWorld::Ptr& actor) const; + enum GreetingState { Greet_None, Greet_InProgress, diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index d032ed632..55aace8e7 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1605,12 +1605,22 @@ namespace MWMechanics return; // we should return a wandering actor back after combat - // TODO: only for stationary wander? - if (!aiSequence.isInCombat() && aiSequence.getLastRunTypeId() == MWMechanics::AiPackage::TypeIdWander) + // the same thing for actors without AI packages + if (!aiSequence.isInCombat() && aiSequence.getTypeId() <= MWMechanics::AiPackage::TypeIdWander) { - osg::Vec3f pos = ptr.getRefData().getPosition().asVec3(); + int typeId = aiSequence.getTypeId(); + osg::Vec3f dest; + if (typeId == MWMechanics::AiPackage::TypeIdNone) + { + dest = ptr.getRefData().getPosition().asVec3(); + } + else if (typeId == MWMechanics::AiPackage::TypeIdWander) + { + AiPackage* activePackage = aiSequence.getActivePackage(); + dest = activePackage->getDestination(ptr); + } - MWMechanics::AiTravel travelPackage(pos.x(), pos.y(), pos.z()); + MWMechanics::AiTravel travelPackage(dest.x(), dest.y(), dest.z()); aiSequence.stack(travelPackage, ptr, false); }