Don't consider non-solid actors truly levitating (bug #4746)

pull/2058/head
Capostrophic 6 years ago
parent 45d7c005ad
commit 7b33838b33

@ -8,6 +8,7 @@
Bug #4715: "Cannot get class of an empty object" exception after pressing ESC in the dialogue mode
Bug #4720: Inventory avatar has shield with two-handed weapon during [un]equipping animation
Bug #4723: ResetActors command works incorrectly
Bug #4746: Non-solid player can't run or sneak
Feature #2229: Improve pathfinding AI
Feature #3442: Default values for fallbacks from ini file
Feature #4673: Weapon sheathing

@ -413,5 +413,5 @@ DetourNavigator::Flags MWMechanics::AiPackage::getNavigatorFlags(const MWWorld::
bool MWMechanics::AiPackage::canActorMoveByZAxis(const MWWorld::Ptr& actor) const
{
MWBase::World* world = MWBase::Environment::get().getWorld();
return (actor.getClass().canSwim(actor) && world->isSwimming(actor)) || world->isFlying(actor);
return (actor.getClass().canSwim(actor) && world->isSwimming(actor)) || world->isFlying(actor) || !world->isActorCollisionEnabled(actor);
}

@ -209,7 +209,8 @@ namespace MWMechanics
}
bool actorCanMoveByZ = (actor.getClass().canSwim(actor) && MWBase::Environment::get().getWorld()->isSwimming(actor))
|| MWBase::Environment::get().getWorld()->isFlying(actor);
|| MWBase::Environment::get().getWorld()->isFlying(actor)
|| !MWBase::Environment::get().getWorld()->isActorCollisionEnabled(actor);
if(actorCanMoveByZ && mDistance > 0) {
// Typically want to idle for a short time before the next wander

@ -1886,6 +1886,7 @@ void CharacterController::update(float duration, bool animationOnly)
bool incapacitated = (cls.getCreatureStats(mPtr).isParalyzed() || cls.getCreatureStats(mPtr).getKnockedDown());
bool inwater = world->isSwimming(mPtr);
bool flying = world->isFlying(mPtr);
bool solid = world->isActorCollisionEnabled(mPtr);
// Can't run and sneak while flying (see speed formula in Npc/Creature::getSpeed)
bool sneak = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Sneak) && !flying;
bool isrunning = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Run) && !flying;
@ -1894,7 +1895,7 @@ void CharacterController::update(float duration, bool animationOnly)
//Force Jump Logic
bool isMoving = (std::abs(cls.getMovementSettings(mPtr).mPosition[0]) > .5 || std::abs(cls.getMovementSettings(mPtr).mPosition[1]) > .5);
if(!inwater && !flying)
if(!inwater && !flying && solid)
{
//Force Jump
if(stats.getMovementFlag(MWMechanics::CreatureStats::Flag_ForceJump))
@ -2002,12 +2003,12 @@ void CharacterController::update(float duration, bool animationOnly)
cls.getCreatureStats(mPtr).setFatigue(fatigue);
}
if(sneak || inwater || flying || incapacitated)
if(sneak || inwater || flying || incapacitated || !solid)
vec.z() = 0.0f;
bool inJump = true;
bool playLandingSound = false;
if(!onground && !flying && !inwater)
if(!onground && !flying && !inwater && solid)
{
// In the air (either getting up —ascending part of jump— or falling).
@ -2060,7 +2061,7 @@ void CharacterController::update(float duration, bool animationOnly)
}
}
}
else if(mJumpState == JumpState_InAir && !inwater && !flying)
else if(mJumpState == JumpState_InAir && !inwater && !flying && solid)
{
forcestateupdate = true;
jumpstate = JumpState_Landing;
@ -2099,7 +2100,7 @@ void CharacterController::update(float duration, bool animationOnly)
}
else
{
if(mPtr.getClass().isNpc() && mJumpState == JumpState_InAir && !flying)
if(mPtr.getClass().isNpc() && mJumpState == JumpState_InAir && !flying && solid)
playLandingSound = true;
jumpstate = mAnimation->isPlaying(mCurrentJump) ? JumpState_Landing : JumpState_None;

@ -1385,7 +1385,7 @@ namespace MWWorld
pos.z() += 20; // place slightly above. will snap down to ground with code below
if (force || !isFlying(ptr))
if (force || !ptr.getClass().isActor() || (!isFlying(ptr) && isActorCollisionEnabled(ptr)))
{
osg::Vec3f traced = mPhysics->traceDown(ptr, pos, Constants::CellSizeInUnits);
if (traced.z() < pos.z())
@ -2229,11 +2229,11 @@ namespace MWWorld
bool World::isFlying(const MWWorld::Ptr &ptr) const
{
const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
if(!ptr.getClass().isActor())
return false;
const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
if (stats.isDead())
return false;
@ -2245,7 +2245,7 @@ namespace MWWorld
return true;
const MWPhysics::Actor* actor = mPhysics->getActor(ptr);
if(!actor || !actor->getCollisionMode())
if(!actor)
return true;
return false;

Loading…
Cancel
Save