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:
parent
85f343e87a
commit
d9a6350c5e
2 changed files with 22 additions and 8 deletions
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue