diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index 1532cce018..ac72068263 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -140,7 +140,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& if (wasShortcutting || doesPathNeedRecalc(dest, actor.getCell())) // if need to rebuild path { const auto playerHalfExtents = world->getHalfExtents(world->getPlayerPtr()); - mPathFinder.buildPath(position, dest, actor.getCell(), getPathGridGraph(actor.getCell()), + mPathFinder.buildPath(actor, position, dest, actor.getCell(), getPathGridGraph(actor.getCell()), playerHalfExtents, getNavigatorFlags(actor)); mRotateOnTheRunChecks = 3; diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index e0822e8063..ad11f6d4e9 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -161,8 +161,8 @@ namespace MWMechanics { const auto world = MWBase::Environment::get().getWorld(); const auto playerHalfExtents = world->getHalfExtents(world->getPlayerPtr()); - mPathFinder.buildPath(pos.asVec3(), mDestination, actor.getCell(), getPathGridGraph(actor.getCell()), - playerHalfExtents, getNavigatorFlags(actor)); + mPathFinder.buildPath(actor, pos.asVec3(), mDestination, actor.getCell(), + getPathGridGraph(actor.getCell()), playerHalfExtents, getNavigatorFlags(actor)); } if (mPathFinder.isPathConstructed()) @@ -323,7 +323,7 @@ namespace MWMechanics { const auto world = MWBase::Environment::get().getWorld();; const auto playerHalfExtents = world->getHalfExtents(world->getPlayerPtr()); - mPathFinder.buildPath(currentPosition, destinationPosition, actor.getCell(), + mPathFinder.buildPath(actor, currentPosition, destinationPosition, actor.getCell(), getPathGridGraph(actor.getCell()), playerHalfExtents, getNavigatorFlags(actor)); mPathFinder.addPointToPath(destinationPosition); diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index cfa51c226b..01c417b536 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -12,6 +12,7 @@ #include "../mwbase/environment.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/class.hpp" #include "pathgrid.hpp" #include "coordinateconverter.hpp" @@ -275,14 +276,14 @@ namespace MWMechanics mConstructed = true; } - void PathFinder::buildPath(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, + void PathFinder::buildPath(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph, const osg::Vec3f& halfExtents, const DetourNavigator::Flags flags) { mPath.clear(); mCell = cell; - buildPathByNavigatorImpl(startPoint, endPoint, halfExtents, flags, std::back_inserter(mPath)); + buildPathByNavigatorImpl(actor, startPoint, endPoint, halfExtents, flags, std::back_inserter(mPath)); if (mPath.empty()) buildPathByPathgridImpl(startPoint, endPoint, pathgridGraph, std::back_inserter(mPath)); @@ -290,8 +291,8 @@ namespace MWMechanics mConstructed = true; } - void PathFinder::buildPathByNavigatorImpl(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, - const osg::Vec3f& halfExtents, const DetourNavigator::Flags flags, + void PathFinder::buildPathByNavigatorImpl(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, + const osg::Vec3f& endPoint, const osg::Vec3f& halfExtents, const DetourNavigator::Flags flags, std::back_insert_iterator> out) { try @@ -302,7 +303,10 @@ namespace MWMechanics catch (const DetourNavigator::NavigatorException& exception) { DetourNavigator::log("PathFinder::buildPathByNavigator navigator exception: ", exception.what()); - Log(Debug::Warning) << "Build path by navigator exception: " << exception.what(); + Log(Debug::Verbose) << "Build path by navigator exception: \"" << exception.what() + << "\" for \"" << actor.getClass().getName(actor) << "\" (" << actor.getBase() + << ") from " << startPoint << " to " << endPoint << " with flags (" + << DetourNavigator::WriteFlags {flags} << ")"; } } } diff --git a/apps/openmw/mwmechanics/pathfinding.hpp b/apps/openmw/mwmechanics/pathfinding.hpp index 1a35ef792e..567056fa5d 100644 --- a/apps/openmw/mwmechanics/pathfinding.hpp +++ b/apps/openmw/mwmechanics/pathfinding.hpp @@ -12,6 +12,7 @@ namespace MWWorld { class CellStore; + class ConstPtr; } namespace MWMechanics @@ -74,7 +75,7 @@ namespace MWMechanics void buildPathByPathgrid(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph); - void buildPath(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, + void buildPath(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph, const osg::Vec3f& halfExtents, const DetourNavigator::Flags flags); @@ -180,8 +181,8 @@ namespace MWMechanics void buildPathByPathgridImpl(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const PathgridGraph& pathgridGraph, std::back_insert_iterator> out); - void buildPathByNavigatorImpl(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, - const osg::Vec3f& halfExtents, const DetourNavigator::Flags flags, + void buildPathByNavigatorImpl(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, + const osg::Vec3f& endPoint, const osg::Vec3f& halfExtents, const DetourNavigator::Flags flags, std::back_insert_iterator> out); }; } diff --git a/components/detournavigator/flags.hpp b/components/detournavigator/flags.hpp index f52c0faf5a..df22209bbb 100644 --- a/components/detournavigator/flags.hpp +++ b/components/detournavigator/flags.hpp @@ -1,6 +1,8 @@ #ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_FLAGS_H #define OPENMW_COMPONENTS_DETOURNAVIGATOR_FLAGS_H +#include + namespace DetourNavigator { using Flags = unsigned short; @@ -12,6 +14,49 @@ namespace DetourNavigator Flag_swim = 1 << 1, Flag_openDoor = 1 << 2, }; + + inline std::ostream& operator <<(std::ostream& stream, const Flag value) + { + switch (value) { + case Flag_none: + return stream << "none"; + case Flag_walk: + return stream << "walk"; + case Flag_swim: + return stream << "swim"; + case Flag_openDoor: + return stream << "openDoor"; + } + } + + struct WriteFlags + { + Flags mValue; + + friend inline std::ostream& operator <<(std::ostream& stream, const WriteFlags& value) + { + if (value.mValue == Flag_none) + { + return stream << Flag_none; + } + else + { + bool first = true; + for (const auto flag : {Flag_walk, Flag_swim, Flag_openDoor}) + { + if (value.mValue & flag) + { + if (!first) + stream << " | "; + first = false; + stream << flag; + } + } + + return stream; + } + } + }; } #endif