mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-28 17:39:42 +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
945448cdf1
commit
709baafd12
2 changed files with 22 additions and 8 deletions
|
@ -6,6 +6,7 @@
|
|||
Bug #5057: Weapon swing sound plays at same pitch whether it hits or misses
|
||||
Bug #5129: Stuttering animation on Centurion Archer
|
||||
Bug #5977: Fatigueless NPCs' corpse underwater changes animation on game load
|
||||
Bug #6937: Divided by Nix Hounds quest is broken
|
||||
Bug #6939: OpenMW-CS: ID columns are too short
|
||||
Bug #6949: Sun Damage effect doesn't work in quasi exteriors
|
||||
Bug #6964: Nerasa Dralor Won't Follow
|
||||
|
|
|
@ -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