diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index 8336ca971..37f5f5bf7 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -22,27 +22,6 @@ #include -namespace MWMechanics -{ - static float distance(const osg::Vec2f& lhs, const osg::Vec2f& rhs) - { - return (lhs - rhs).length2(); - } - - static float distanceIgnoreZ(const osg::Vec3f& lhs, const osg::Vec3f& rhs) - { - return distance(osg::Vec2f(lhs.x(), lhs.y()), osg::Vec2f(rhs.x(), rhs.y())); - } - - static float distance(const osg::Vec3f& lhs, const osg::Vec3f& rhs, const MWWorld::Ptr& actor) - { - const auto world = MWBase::Environment::get().getWorld(); - if (world->isSwimming(actor) || world->isFlying(actor)) - return distance(lhs, rhs); - return distanceIgnoreZ(lhs, rhs); - } -} - MWMechanics::AiPackage::~AiPackage() {} MWMechanics::AiPackage::AiPackage() : @@ -352,7 +331,7 @@ bool MWMechanics::AiPackage::checkWayIsClearForActor(const osg::Vec3f& startPoin bool MWMechanics::AiPackage::doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::Ptr& actor) const { return mPathFinder.getPath().empty() - || distance(mPathFinder.getPath().back(), newDest, actor) > 10 + || getPathDistance(actor, mPathFinder.getPath().back(), newDest) > 10 || mPathFinder.getPathCell() != actor.getCell(); } diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index 9258c6b2d..27dc0b473 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -20,6 +20,7 @@ #include "spellcasting.hpp" #include "difficultyscaling.hpp" #include "actorutil.hpp" +#include "pathfinding.hpp" namespace { @@ -467,13 +468,8 @@ namespace MWMechanics { osg::Vec3f pos1 (actor1.getRefData().getPosition().asVec3()); osg::Vec3f pos2 (actor2.getRefData().getPosition().asVec3()); - if (canActorMoveByZAxis(actor2)) - { - pos1.z() = 0.f; - pos2.z() = 0.f; - } - float d = (pos1 - pos2).length(); + float d = getAggroDistance(actor2, pos1, pos2); static const int iFightDistanceBase = MWBase::Environment::get().getWorld()->getStore().get().find( "iFightDistanceBase")->mValue.getInteger(); @@ -489,4 +485,11 @@ namespace MWMechanics return (magicEffects.get(ESM::MagicEffect::Invisibility).getMagnitude() > 0) || (magicEffects.get(ESM::MagicEffect::Chameleon).getMagnitude() > 75); } + + float getAggroDistance(const MWWorld::Ptr& actor, const osg::Vec3f& lhs, const osg::Vec3f& rhs) + { + if (canActorMoveByZAxis(actor)) + return distanceIgnoreZ(lhs, rhs); + return distance(lhs, rhs); + } } diff --git a/apps/openmw/mwmechanics/combat.hpp b/apps/openmw/mwmechanics/combat.hpp index fd2717b19..3d4a1bd77 100644 --- a/apps/openmw/mwmechanics/combat.hpp +++ b/apps/openmw/mwmechanics/combat.hpp @@ -55,6 +55,9 @@ void applyFatigueLoss(const MWWorld::Ptr& attacker, const MWWorld::Ptr& weapon, float getFightDistanceBias(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2); bool isTargetMagicallyHidden(const MWWorld::Ptr& target); + +float getAggroDistance(const MWWorld::Ptr& actor, const osg::Vec3f& lhs, const osg::Vec3f& rhs); + } #endif diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 900f97a67..97c29680c 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -18,6 +18,7 @@ #include "pathgrid.hpp" #include "coordinateconverter.hpp" +#include "actorutil.hpp" namespace { @@ -84,6 +85,13 @@ namespace namespace MWMechanics { + float getPathDistance(const MWWorld::Ptr& actor, const osg::Vec3f& lhs, const osg::Vec3f& rhs) + { + if (canActorMoveByZAxis(actor)) + return distance(lhs, rhs); + return distanceIgnoreZ(lhs, rhs); + } + bool checkWayIsClear(const osg::Vec3f& from, const osg::Vec3f& to, float offsetXY) { osg::Vec3f dir = to - from; diff --git a/apps/openmw/mwmechanics/pathfinding.hpp b/apps/openmw/mwmechanics/pathfinding.hpp index f762b6f18..b413810f4 100644 --- a/apps/openmw/mwmechanics/pathfinding.hpp +++ b/apps/openmw/mwmechanics/pathfinding.hpp @@ -13,17 +13,29 @@ namespace MWWorld { class CellStore; class ConstPtr; + class Ptr; } namespace MWMechanics { class PathgridGraph; - inline float distance(const osg::Vec3f& lhs, const osg::Vec3f& rhs) + template + inline float distance(const T& lhs, const T& rhs) { + static_assert(std::is_same::value + || std::is_same::value, + "T is not a position"); return (lhs - rhs).length(); } + inline float distanceIgnoreZ(const osg::Vec3f& lhs, const osg::Vec3f& rhs) + { + return distance(osg::Vec2f(lhs.x(), lhs.y()), osg::Vec2f(rhs.x(), rhs.y())); + } + + float getPathDistance(const MWWorld::Ptr& actor, const osg::Vec3f& lhs, const osg::Vec3f& rhs); + inline float getZAngleToDir(const osg::Vec3f& dir) { return std::atan2(dir.x(), dir.y());