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

pull/541/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 #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 #4720: Inventory avatar has shield with two-handed weapon during [un]equipping animation
Bug #4723: ResetActors command works incorrectly Bug #4723: ResetActors command works incorrectly
Bug #4746: Non-solid player can't run or sneak
Feature #2229: Improve pathfinding AI Feature #2229: Improve pathfinding AI
Feature #3442: Default values for fallbacks from ini file Feature #3442: Default values for fallbacks from ini file
Feature #4673: Weapon sheathing Feature #4673: Weapon sheathing

@ -413,5 +413,5 @@ DetourNavigator::Flags MWMechanics::AiPackage::getNavigatorFlags(const MWWorld::
bool MWMechanics::AiPackage::canActorMoveByZAxis(const MWWorld::Ptr& actor) const bool MWMechanics::AiPackage::canActorMoveByZAxis(const MWWorld::Ptr& actor) const
{ {
MWBase::World* world = MWBase::Environment::get().getWorld(); 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)) 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) { if(actorCanMoveByZ && mDistance > 0) {
// Typically want to idle for a short time before the next wander // 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 incapacitated = (cls.getCreatureStats(mPtr).isParalyzed() || cls.getCreatureStats(mPtr).getKnockedDown());
bool inwater = world->isSwimming(mPtr); bool inwater = world->isSwimming(mPtr);
bool flying = world->isFlying(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) // 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 sneak = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Sneak) && !flying;
bool isrunning = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Run) && !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 //Force Jump Logic
bool isMoving = (std::abs(cls.getMovementSettings(mPtr).mPosition[0]) > .5 || std::abs(cls.getMovementSettings(mPtr).mPosition[1]) > .5); 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 //Force Jump
if(stats.getMovementFlag(MWMechanics::CreatureStats::Flag_ForceJump)) if(stats.getMovementFlag(MWMechanics::CreatureStats::Flag_ForceJump))
@ -2002,12 +2003,12 @@ void CharacterController::update(float duration, bool animationOnly)
cls.getCreatureStats(mPtr).setFatigue(fatigue); cls.getCreatureStats(mPtr).setFatigue(fatigue);
} }
if(sneak || inwater || flying || incapacitated) if(sneak || inwater || flying || incapacitated || !solid)
vec.z() = 0.0f; vec.z() = 0.0f;
bool inJump = true; bool inJump = true;
bool playLandingSound = false; bool playLandingSound = false;
if(!onground && !flying && !inwater) if(!onground && !flying && !inwater && solid)
{ {
// In the air (either getting up —ascending part of jump— or falling). // 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; forcestateupdate = true;
jumpstate = JumpState_Landing; jumpstate = JumpState_Landing;
@ -2099,7 +2100,7 @@ void CharacterController::update(float duration, bool animationOnly)
} }
else else
{ {
if(mPtr.getClass().isNpc() && mJumpState == JumpState_InAir && !flying) if(mPtr.getClass().isNpc() && mJumpState == JumpState_InAir && !flying && solid)
playLandingSound = true; playLandingSound = true;
jumpstate = mAnimation->isPlaying(mCurrentJump) ? JumpState_Landing : JumpState_None; 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 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); osg::Vec3f traced = mPhysics->traceDown(ptr, pos, Constants::CellSizeInUnits);
if (traced.z() < pos.z()) if (traced.z() < pos.z())
@ -2229,11 +2229,11 @@ namespace MWWorld
bool World::isFlying(const MWWorld::Ptr &ptr) const bool World::isFlying(const MWWorld::Ptr &ptr) const
{ {
const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
if(!ptr.getClass().isActor()) if(!ptr.getClass().isActor())
return false; return false;
const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
if (stats.isDead()) if (stats.isDead())
return false; return false;
@ -2245,7 +2245,7 @@ namespace MWWorld
return true; return true;
const MWPhysics::Actor* actor = mPhysics->getActor(ptr); const MWPhysics::Actor* actor = mPhysics->getActor(ptr);
if(!actor || !actor->getCollisionMode()) if(!actor)
return true; return true;
return false; return false;

Loading…
Cancel
Save