mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 19:19:56 +00:00
Merge pull request #1570
This commit is contained in:
commit
3984dc8f16
3 changed files with 28 additions and 18 deletions
|
@ -101,8 +101,17 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const ESM::Pathgr
|
||||||
{
|
{
|
||||||
bool wasShortcutting = mIsShortcutting;
|
bool wasShortcutting = mIsShortcutting;
|
||||||
bool destInLOS = false;
|
bool destInLOS = false;
|
||||||
if (getTypeId() != TypeIdWander) // prohibit shortcuts for AiWander
|
|
||||||
mIsShortcutting = shortcutPath(start, dest, actor, &destInLOS); // try to shortcut first
|
const MWWorld::Class& actorClass = actor.getClass();
|
||||||
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
|
|
||||||
|
// check if actor can move along z-axis
|
||||||
|
bool actorCanMoveByZ = (actorClass.canSwim(actor) && MWBase::Environment::get().getWorld()->isSwimming(actor))
|
||||||
|
|| world->isFlying(actor);
|
||||||
|
|
||||||
|
// Prohibit shortcuts for AiWander, if the actor can not move in 3 dimensions.
|
||||||
|
if (actorCanMoveByZ || getTypeId() != TypeIdWander)
|
||||||
|
mIsShortcutting = shortcutPath(start, dest, actor, &destInLOS, actorCanMoveByZ); // try to shortcut first
|
||||||
|
|
||||||
if (!mIsShortcutting)
|
if (!mIsShortcutting)
|
||||||
{
|
{
|
||||||
|
@ -235,20 +244,9 @@ const MWMechanics::PathgridGraph& MWMechanics::AiPackage::getPathGridGraph(const
|
||||||
return *cache[id].get();
|
return *cache[id].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MWMechanics::AiPackage::shortcutPath(const ESM::Pathgrid::Point& startPoint, const ESM::Pathgrid::Point& endPoint, const MWWorld::Ptr& actor, bool *destInLOS)
|
bool MWMechanics::AiPackage::shortcutPath(const ESM::Pathgrid::Point& startPoint, const ESM::Pathgrid::Point& endPoint, const MWWorld::Ptr& actor, bool *destInLOS, bool isPathClear)
|
||||||
{
|
{
|
||||||
const MWWorld::Class& actorClass = actor.getClass();
|
if (!mShortcutProhibited || (PathFinder::MakeOsgVec3(mShortcutFailPos) - PathFinder::MakeOsgVec3(startPoint)).length() >= PATHFIND_SHORTCUT_RETRY_DIST)
|
||||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
|
||||||
|
|
||||||
// check if actor can move along z-axis
|
|
||||||
bool actorCanMoveByZ = (actorClass.canSwim(actor) && MWBase::Environment::get().getWorld()->isSwimming(actor))
|
|
||||||
|| world->isFlying(actor);
|
|
||||||
|
|
||||||
// don't use pathgrid when actor can move in 3 dimensions
|
|
||||||
bool isPathClear = actorCanMoveByZ;
|
|
||||||
|
|
||||||
if (!isPathClear
|
|
||||||
&& (!mShortcutProhibited || (PathFinder::MakeOsgVec3(mShortcutFailPos) - PathFinder::MakeOsgVec3(startPoint)).length() >= PATHFIND_SHORTCUT_RETRY_DIST))
|
|
||||||
{
|
{
|
||||||
// check if target is clearly visible
|
// check if target is clearly visible
|
||||||
isPathClear = !MWBase::Environment::get().getWorld()->castRay(
|
isPathClear = !MWBase::Environment::get().getWorld()->castRay(
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace MWMechanics
|
||||||
/// If a shortcut is possible then path will be cleared and filled with the destination point.
|
/// If a shortcut is possible then path will be cleared and filled with the destination point.
|
||||||
/// \param destInLOS If not NULL function will return ray cast check result
|
/// \param destInLOS If not NULL function will return ray cast check result
|
||||||
/// \return If can shortcut the path
|
/// \return If can shortcut the path
|
||||||
bool shortcutPath(const ESM::Pathgrid::Point& startPoint, const ESM::Pathgrid::Point& endPoint, const MWWorld::Ptr& actor, bool *destInLOS);
|
bool shortcutPath(const ESM::Pathgrid::Point& startPoint, const ESM::Pathgrid::Point& endPoint, const MWWorld::Ptr& actor, bool *destInLOS, bool isPathClear);
|
||||||
|
|
||||||
/// Check if the way to the destination is clear, taking into account actor speed
|
/// Check if the way to the destination is clear, taking into account actor speed
|
||||||
bool checkWayIsClearForActor(const ESM::Pathgrid::Point& startPoint, const ESM::Pathgrid::Point& endPoint, const MWWorld::Ptr& actor);
|
bool checkWayIsClearForActor(const ESM::Pathgrid::Point& startPoint, const ESM::Pathgrid::Point& endPoint, const MWWorld::Ptr& actor);
|
||||||
|
|
|
@ -265,9 +265,20 @@ namespace MWMechanics
|
||||||
getAllowedNodes(actor, currentCell->getCell(), storage);
|
getAllowedNodes(actor, currentCell->getCell(), storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool actorCanMoveByZ = (actor.getClass().canSwim(actor) && MWBase::Environment::get().getWorld()->isSwimming(actor))
|
||||||
|
|| MWBase::Environment::get().getWorld()->isFlying(actor);
|
||||||
|
|
||||||
|
if(actorCanMoveByZ && mDistance > 0) {
|
||||||
|
// Typically want to idle for a short time before the next wander
|
||||||
|
if (Misc::Rng::rollDice(100) >= 92 && storage.mState != Wander_Walking) {
|
||||||
|
wanderNearStart(actor, storage, mDistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
storage.mCanWanderAlongPathGrid = false;
|
||||||
|
}
|
||||||
// If the package has a wander distance but no pathgrid is available,
|
// If the package has a wander distance but no pathgrid is available,
|
||||||
// randomly idle or wander near spawn point
|
// randomly idle or wander near spawn point
|
||||||
if(storage.mAllowedNodes.empty() && mDistance > 0 && !storage.mIsWanderingManually) {
|
else if(storage.mAllowedNodes.empty() && mDistance > 0 && !storage.mIsWanderingManually) {
|
||||||
// Typically want to idle for a short time before the next wander
|
// Typically want to idle for a short time before the next wander
|
||||||
if (Misc::Rng::rollDice(100) >= 96) {
|
if (Misc::Rng::rollDice(100) >= 96) {
|
||||||
wanderNearStart(actor, storage, mDistance);
|
wanderNearStart(actor, storage, mDistance);
|
||||||
|
@ -373,7 +384,7 @@ namespace MWMechanics
|
||||||
do {
|
do {
|
||||||
// Determine a random location within radius of original position
|
// Determine a random location within radius of original position
|
||||||
const float pi = 3.14159265359f;
|
const float pi = 3.14159265359f;
|
||||||
const float wanderRadius = Misc::Rng::rollClosedProbability() * wanderDistance;
|
const float wanderRadius = (0.2f + Misc::Rng::rollClosedProbability() * 0.8f) * wanderDistance;
|
||||||
const float randomDirection = Misc::Rng::rollClosedProbability() * 2.0f * pi;
|
const float randomDirection = Misc::Rng::rollClosedProbability() * 2.0f * pi;
|
||||||
const float destinationX = mInitialActorPosition.x() + wanderRadius * std::cos(randomDirection);
|
const float destinationX = mInitialActorPosition.x() + wanderRadius * std::cos(randomDirection);
|
||||||
const float destinationY = mInitialActorPosition.y() + wanderRadius * std::sin(randomDirection);
|
const float destinationY = mInitialActorPosition.y() + wanderRadius * std::sin(randomDirection);
|
||||||
|
@ -661,6 +672,7 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
unsigned int randNode = Misc::Rng::rollDice(storage.mAllowedNodes.size());
|
unsigned int randNode = Misc::Rng::rollDice(storage.mAllowedNodes.size());
|
||||||
ESM::Pathgrid::Point dest(storage.mAllowedNodes[randNode]);
|
ESM::Pathgrid::Point dest(storage.mAllowedNodes[randNode]);
|
||||||
|
|
||||||
ToWorldCoordinates(dest, storage.mCell->getCell());
|
ToWorldCoordinates(dest, storage.mCell->getCell());
|
||||||
|
|
||||||
// actor position is already in world coordinates
|
// actor position is already in world coordinates
|
||||||
|
|
Loading…
Reference in a new issue