mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-28 10:09:40 +00:00
Merge pull request #2550 from elsid/fix_path_rebuild
Fix rebuild path for walking actors (Bug #5181)
This commit is contained in:
commit
5d5ec1cf63
8 changed files with 49 additions and 22 deletions
|
@ -133,7 +133,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f&
|
|||
|
||||
if (!mIsShortcutting)
|
||||
{
|
||||
if (wasShortcutting || doesPathNeedRecalc(dest, actor.getCell())) // if need to rebuild path
|
||||
if (wasShortcutting || doesPathNeedRecalc(dest, actor)) // if need to rebuild path
|
||||
{
|
||||
const auto pathfindingHalfExtents = world->getPathfindingHalfExtents(actor);
|
||||
mPathFinder.buildPath(actor, position, dest, actor.getCell(), getPathGridGraph(actor.getCell()),
|
||||
|
@ -328,11 +328,11 @@ bool MWMechanics::AiPackage::checkWayIsClearForActor(const osg::Vec3f& startPoin
|
|||
return false;
|
||||
}
|
||||
|
||||
bool MWMechanics::AiPackage::doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::CellStore* currentCell)
|
||||
bool MWMechanics::AiPackage::doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::Ptr& actor) const
|
||||
{
|
||||
return mPathFinder.getPath().empty()
|
||||
|| (distance(mPathFinder.getPath().back(), newDest) > 10)
|
||||
|| mPathFinder.getPathCell() != currentCell;
|
||||
|| getPathDistance(actor, mPathFinder.getPath().back(), newDest) > 10
|
||||
|| mPathFinder.getPathCell() != actor.getCell();
|
||||
}
|
||||
|
||||
bool MWMechanics::AiPackage::isNearInactiveCell(osg::Vec3f position)
|
||||
|
|
|
@ -120,7 +120,7 @@ namespace MWMechanics
|
|||
/// Check if the way to the destination is clear, taking into account actor speed
|
||||
bool checkWayIsClearForActor(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const MWWorld::Ptr& actor);
|
||||
|
||||
bool doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::CellStore* currentCell);
|
||||
bool doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::Ptr& actor) const;
|
||||
|
||||
void evadeObstacles(const MWWorld::Ptr& actor);
|
||||
|
||||
|
|
|
@ -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<ESM::GameSetting>().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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "pathgrid.hpp"
|
||||
#include "coordinateconverter.hpp"
|
||||
#include "actorutil.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -80,10 +81,24 @@ namespace
|
|||
const auto realHalfExtents = world->getHalfExtents(actor);
|
||||
return 2 * std::max(realHalfExtents.x(), realHalfExtents.y());
|
||||
}
|
||||
|
||||
float getHeight(const MWWorld::ConstPtr& actor)
|
||||
{
|
||||
const auto world = MWBase::Environment::get().getWorld();
|
||||
const auto halfExtents = world->getHalfExtents(actor);
|
||||
return 2.0 * halfExtents.z();
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
float getPathDistance(const MWWorld::Ptr& actor, const osg::Vec3f& lhs, const osg::Vec3f& rhs)
|
||||
{
|
||||
if (std::abs(lhs.z() - rhs.z()) > getHeight(actor) || 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;
|
||||
|
|
|
@ -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 <class T>
|
||||
inline float distance(const T& lhs, const T& rhs)
|
||||
{
|
||||
static_assert(std::is_same<T, osg::Vec2f>::value
|
||||
|| std::is_same<T, osg::Vec3f>::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());
|
||||
|
|
|
@ -176,12 +176,12 @@ recast scale factor
|
|||
|
||||
:Type: floating point
|
||||
:Range: > 0.0
|
||||
:Default: 0.017647058823529415
|
||||
:Default: 0.023529411764705882
|
||||
|
||||
Scale of nav mesh coordinates to world coordinates. Recastnavigation builds voxels for world geometry.
|
||||
Basically voxel size is 1 / "cell size". To reduce amount of voxels we apply scale factor, to make voxel size
|
||||
"recast scale factor" / "cell size". Default value calculates by this equation:
|
||||
sStepSizeUp * "recast scale factor" / "cell size" = 3 (max climb height should be equal to 3 voxels).
|
||||
sStepSizeUp * "recast scale factor" / "cell size" = 4 (max climb height should be equal to 4 voxels).
|
||||
Changing this value will change generated nav mesh. Some locations may become unavailable for NPC and creatures.
|
||||
Pay attention to slopes and roofs when change it. Increasing this value will reduce nav mesh update latency.
|
||||
|
||||
|
|
|
@ -642,8 +642,8 @@ enable = true
|
|||
# Scale of NavMesh coordinates to world coordinates (value > 0.0). Recastnavigation builds voxels for world geometry.
|
||||
# Basically voxel size is 1 / "cell size". To reduce amount of voxels we apply scale factor, to make voxel size
|
||||
# "recast scale factor" / "cell size". Default value calculates by this equation:
|
||||
# sStepSizeUp * "recast scale factor" / "cell size" = 3 (max climb height should be equal to 3 voxels)
|
||||
recast scale factor = 0.017647058823529415
|
||||
# sStepSizeUp * "recast scale factor" / "cell size" = 4 (max climb height should be equal to 4 voxels)
|
||||
recast scale factor = 0.023529411764705882
|
||||
|
||||
# The z-axis cell size to use for fields. (value > 0.0)
|
||||
# Defines voxel/grid/cell size. So their values have significant
|
||||
|
@ -711,12 +711,6 @@ max smooth path size = 1024
|
|||
# Maximum number of triangles in each node of mesh AABB tree (value > 0)
|
||||
triangles per chunk = 256
|
||||
|
||||
# Enable debug log (true, false)
|
||||
enable log = false
|
||||
|
||||
# Write debug log to this file
|
||||
log path = detournavigator.log
|
||||
|
||||
# Write recast mesh to file in .obj format for each use to update nav mesh (true, false)
|
||||
enable write recast mesh to file = false
|
||||
|
||||
|
|
Loading…
Reference in a new issue