From dda4273349cb79ceafedd8a18678478aafc49f19 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 1 Feb 2016 23:13:43 +0100 Subject: [PATCH] Actors that start the game as dead do not float to the surface (Fixes #3177) This has a minor bug (can you spot it?) that affects the vanilla engine as well, unfortunately not so simple to fix. --- apps/openmw/mwmechanics/character.cpp | 7 ++++++- apps/openmw/mwmechanics/character.hpp | 1 + apps/openmw/mwphysics/physicssystem.cpp | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index db1b82ba6..67707d028 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -668,6 +668,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim , mHasMovedInXY(false) , mMovementAnimationControlled(true) , mDeathState(CharState_None) + , mFloatToSurface(true) , mHitState(CharState_None) , mUpperBodyState(UpperCharState_Nothing) , mJumpState(JumpState_None) @@ -716,6 +717,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim // Set the death state, but don't play it yet // We will play it in the first frame, but only if no script set the skipAnim flag mDeathState = static_cast(CharState_Death1 + mPtr.getClass().getCreatureStats(mPtr).getDeathAnimation()); + mFloatToSurface = false; } } else @@ -1864,7 +1866,7 @@ void CharacterController::update(float duration) { playDeath(1.f, mDeathState); } - + // We must always queue movement, even if there is none, to apply gravity. world->queueMovement(mPtr, osg::Vec3f(0.f, 0.f, 0.f)); } @@ -1897,6 +1899,9 @@ void CharacterController::update(float duration) if (mSkipAnim) mAnimation->updateEffects(duration); + if (mFloatToSurface && cls.isActor() && cls.getCreatureStats(mPtr).isDead()) + moved.z() = 1.0; + // Update movement if(mMovementAnimationControlled && mPtr.getClass().isActor()) world->queueMovement(mPtr, moved); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 5e43bc2b7..6db661ca5 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -160,6 +160,7 @@ class CharacterController : public MWRender::Animation::TextKeyListener CharacterState mDeathState; std::string mCurrentDeath; + bool mFloatToSurface; CharacterState mHitState; std::string mCurrentHit; diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 57bf7919a..c99456ae5 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -289,8 +289,8 @@ namespace MWPhysics } } - // dead actors underwater will float to the surface - if (ptr.getClass().getCreatureStats(ptr).isDead() && position.z() < swimlevel) + // dead actors underwater will float to the surface, if the CharacterController tells us to do so + if (movement.z() > 0 && ptr.getClass().getCreatureStats(ptr).isDead() && position.z() < swimlevel) velocity = osg::Vec3f(0,0,1) * 25; ptr.getClass().getMovementSettings(ptr).mPosition[2] = 0;