1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-31 23:45:35 +00:00

Limit AiWander destination by wander distance

From initial actor position.

findRandomPointAroundCircle may return a position outside given range. Use
raycast to choose a different reachable point within a radius but double check
and discard if it's still outside.

Use wander radius instead of wander distance for findRandomPointAroundCircle to
have better chance for a position to be inside wander distance.
This commit is contained in:
elsid 2022-08-30 20:19:01 +02:00 committed by Bret Curtis
parent 85f343e87a
commit d9a6350c5e
2 changed files with 22 additions and 8 deletions

View file

@ -153,6 +153,7 @@
Bug #6910: Torches should not be extinguished when not being held
Bug #6913: Constant effect enchanted items don't break invisibility
Bug #6923: Dispose of corpse prevents respawning after load
Bug #6937: Divided by Nix Hounds quest is broken
Feature #890: OpenMW-CS: Column filtering
Feature #1465: "Reset" argument for AI functions
Feature #2491: Ability to make OpenMW "portable"

View file

@ -360,14 +360,27 @@ namespace MWMechanics
if (!isWaterCreature && !isFlyingCreature)
{
// findRandomPointAroundCircle uses wanderDistance as limit for random and not as exact distance
if (const auto destination = DetourNavigator::findRandomPointAroundCircle(*navigator, agentBounds,
mInitialActorPosition, wanderDistance, navigatorFlags, []() {
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
return Misc::Rng::rollProbability(prng);
}))
mDestination = *destination;
else
mDestination = getRandomPointAround(mInitialActorPosition, wanderRadius);
const auto getRandom = []()
{
return Misc::Rng::rollProbability(MWBase::Environment::get().getWorld()->getPrng());
};
auto destination = DetourNavigator::findRandomPointAroundCircle(*navigator, agentBounds,
mInitialActorPosition, wanderRadius, navigatorFlags, getRandom);
if (destination.has_value())
{
osg::Vec3f direction = *destination - mInitialActorPosition;
if (direction.length() > wanderDistance)
{
direction.normalize();
const osg::Vec3f adjustedDestination = mInitialActorPosition + direction * wanderRadius;
destination = DetourNavigator::raycast(*navigator, agentBounds, currentPosition,
adjustedDestination, navigatorFlags);
if (destination.has_value() && (*destination - mInitialActorPosition).length() > wanderDistance)
continue;
}
}
mDestination = destination.has_value() ? *destination
: getRandomPointAround(mInitialActorPosition, wanderRadius);
}
else
mDestination = getRandomPointAround(mInitialActorPosition, wanderRadius);