Merge branch 'water_walking_cost' into 'master'

Use walking speed for swimming actor with water walking for pathfinding (#7758)

Closes #7758

See merge request OpenMW/openmw!3732
qt6_macos
Alexei Kotov 1 year ago
commit dfc29974d0

@ -121,6 +121,7 @@
Bug #7723: Assaulting vampires and werewolves shouldn't be a crime Bug #7723: Assaulting vampires and werewolves shouldn't be a crime
Bug #7724: Guards don't help vs werewolves Bug #7724: Guards don't help vs werewolves
Bug #7742: Governing attribute training limit should use the modified attribute Bug #7742: Governing attribute training limit should use the modified attribute
Bug #7758: Water walking is not taken into account to compute path cost on the water
Feature #2566: Handle NAM9 records for manual cell references Feature #2566: Handle NAM9 records for manual cell references
Feature #3537: Shader-based water ripples Feature #3537: Shader-based water ripples
Feature #5173: Support for NiFogProperty Feature #5173: Support for NiFogProperty

@ -283,8 +283,8 @@ namespace MWMechanics
const MWBase::World* world = MWBase::Environment::get().getWorld(); const MWBase::World* world = MWBase::Environment::get().getWorld();
// Try to build path to the target. // Try to build path to the target.
const auto agentBounds = world->getPathfindingAgentBounds(actor); const auto agentBounds = world->getPathfindingAgentBounds(actor);
const auto navigatorFlags = getNavigatorFlags(actor); const DetourNavigator::Flags navigatorFlags = getNavigatorFlags(actor);
const auto areaCosts = getAreaCosts(actor); const DetourNavigator::AreaCosts areaCosts = getAreaCosts(actor, navigatorFlags);
const ESM::Pathgrid* pathgrid = world->getStore().get<ESM::Pathgrid>().search(*actor.getCell()->getCell()); const ESM::Pathgrid* pathgrid = world->getStore().get<ESM::Pathgrid>().search(*actor.getCell()->getCell());
const auto& pathGridGraph = getPathGridGraph(pathgrid); const auto& pathGridGraph = getPathGridGraph(pathgrid);
mPathFinder.buildPath(actor, vActorPos, vTargetPos, actor.getCell(), pathGridGraph, agentBounds, mPathFinder.buildPath(actor, vActorPos, vTargetPos, actor.getCell(), pathGridGraph, agentBounds,

@ -157,8 +157,10 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f&
{ {
const ESM::Pathgrid* pathgrid const ESM::Pathgrid* pathgrid
= world->getStore().get<ESM::Pathgrid>().search(*actor.getCell()->getCell()); = world->getStore().get<ESM::Pathgrid>().search(*actor.getCell()->getCell());
const DetourNavigator::Flags navigatorFlags = getNavigatorFlags(actor);
const DetourNavigator::AreaCosts areaCosts = getAreaCosts(actor, navigatorFlags);
mPathFinder.buildLimitedPath(actor, position, dest, actor.getCell(), getPathGridGraph(pathgrid), mPathFinder.buildLimitedPath(actor, position, dest, actor.getCell(), getPathGridGraph(pathgrid),
agentBounds, getNavigatorFlags(actor), getAreaCosts(actor), endTolerance, pathType); agentBounds, navigatorFlags, areaCosts, endTolerance, pathType);
mRotateOnTheRunChecks = 3; mRotateOnTheRunChecks = 3;
// give priority to go directly on target if there is minimal opportunity // give priority to go directly on target if there is minimal opportunity
@ -486,14 +488,12 @@ DetourNavigator::Flags MWMechanics::AiPackage::getNavigatorFlags(const MWWorld::
return result; return result;
} }
DetourNavigator::AreaCosts MWMechanics::AiPackage::getAreaCosts(const MWWorld::Ptr& actor) const DetourNavigator::AreaCosts MWMechanics::AiPackage::getAreaCosts(
const MWWorld::Ptr& actor, DetourNavigator::Flags flags) const
{ {
DetourNavigator::AreaCosts costs; DetourNavigator::AreaCosts costs;
const DetourNavigator::Flags flags = getNavigatorFlags(actor);
const MWWorld::Class& actorClass = actor.getClass(); const MWWorld::Class& actorClass = actor.getClass();
const float swimSpeed = (flags & DetourNavigator::Flag_swim) == 0 ? 0.0f : actorClass.getSwimSpeed(actor);
const float walkSpeed = [&] { const float walkSpeed = [&] {
if ((flags & DetourNavigator::Flag_walk) == 0) if ((flags & DetourNavigator::Flag_walk) == 0)
return 0.0f; return 0.0f;
@ -502,6 +502,14 @@ DetourNavigator::AreaCosts MWMechanics::AiPackage::getAreaCosts(const MWWorld::P
return actorClass.getRunSpeed(actor); return actorClass.getRunSpeed(actor);
}(); }();
const float swimSpeed = [&] {
if ((flags & DetourNavigator::Flag_swim) == 0)
return 0.0f;
if (hasWaterWalking(actor))
return walkSpeed;
return actorClass.getSwimSpeed(actor);
}();
const float maxSpeed = std::max(swimSpeed, walkSpeed); const float maxSpeed = std::max(swimSpeed, walkSpeed);
if (maxSpeed == 0) if (maxSpeed == 0)

@ -150,7 +150,7 @@ namespace MWMechanics
DetourNavigator::Flags getNavigatorFlags(const MWWorld::Ptr& actor) const; DetourNavigator::Flags getNavigatorFlags(const MWWorld::Ptr& actor) const;
DetourNavigator::AreaCosts getAreaCosts(const MWWorld::Ptr& actor) const; DetourNavigator::AreaCosts getAreaCosts(const MWWorld::Ptr& actor, DetourNavigator::Flags flags) const;
const AiPackageTypeId mTypeId; const AiPackageTypeId mTypeId;
const Options mOptions; const Options mOptions;

@ -224,8 +224,10 @@ namespace MWMechanics
{ {
const auto agentBounds = MWBase::Environment::get().getWorld()->getPathfindingAgentBounds(actor); const auto agentBounds = MWBase::Environment::get().getWorld()->getPathfindingAgentBounds(actor);
constexpr float endTolerance = 0; constexpr float endTolerance = 0;
const DetourNavigator::Flags navigatorFlags = getNavigatorFlags(actor);
const DetourNavigator::AreaCosts areaCosts = getAreaCosts(actor, navigatorFlags);
mPathFinder.buildPath(actor, pos.asVec3(), mDestination, actor.getCell(), getPathGridGraph(pathgrid), mPathFinder.buildPath(actor, pos.asVec3(), mDestination, actor.getCell(), getPathGridGraph(pathgrid),
agentBounds, getNavigatorFlags(actor), getAreaCosts(actor), endTolerance, PathType::Full); agentBounds, navigatorFlags, areaCosts, endTolerance, PathType::Full);
} }
if (mPathFinder.isPathConstructed()) if (mPathFinder.isPathConstructed())
@ -367,8 +369,8 @@ namespace MWMechanics
const auto world = MWBase::Environment::get().getWorld(); const auto world = MWBase::Environment::get().getWorld();
const auto agentBounds = world->getPathfindingAgentBounds(actor); const auto agentBounds = world->getPathfindingAgentBounds(actor);
const auto navigator = world->getNavigator(); const auto navigator = world->getNavigator();
const auto navigatorFlags = getNavigatorFlags(actor); const DetourNavigator::Flags navigatorFlags = getNavigatorFlags(actor);
const auto areaCosts = getAreaCosts(actor); const DetourNavigator::AreaCosts areaCosts = getAreaCosts(actor, navigatorFlags);
auto& prng = MWBase::Environment::get().getWorld()->getPrng(); auto& prng = MWBase::Environment::get().getWorld()->getPrng();
do do

Loading…
Cancel
Save