From 71bcc11ba5b73b0bdc6d2d4aef055b544c8740f3 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 17 Jul 2018 20:59:05 +0400 Subject: [PATCH 1/3] Apply only crossbow reload animation to upper body --- apps/openmw/mwmechanics/character.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index f5d6f8584..b63704e76 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1215,6 +1215,7 @@ bool CharacterController::updateWeaponState() MWRender::Animation::AnimPriority priorityWeapon(Priority_Weapon); priorityWeapon[MWRender::Animation::BoneGroup_LowerBody] = Priority_WeaponLowerBody; + bool forcestateupdate = false; // We should not play equipping animation and sound during weapon->weapon transition @@ -1663,18 +1664,22 @@ bool CharacterController::updateWeaponState() break; } - // Note: apply reload animations only for upper body since blending with movement animations can give weird result. - // Especially noticable with crossbow reload animation. + // Note: apply crossbow reload animation only for upper body + // since blending with movement animations can give weird result. if(!start.empty()) { + int mask = MWRender::Animation::BlendMask_All; + if (mWeaponType == WeapType_Crossbow) + mask = MWRender::Animation::BlendMask_UpperBody; + mAnimation->disable(mCurrentWeapon); if (mUpperBodyState == UpperCharState_FollowStartToFollowStop) mAnimation->play(mCurrentWeapon, priorityWeapon, - MWRender::Animation::BlendMask_UpperBody, true, + mask, true, weapSpeed, start, stop, 0.0f, 0); else mAnimation->play(mCurrentWeapon, priorityWeapon, - MWRender::Animation::BlendMask_UpperBody, false, + mask, false, weapSpeed, start, stop, 0.0f, 0); } } From df577babe9d794e510af2425d52faa65a0cc6747 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 17 Jul 2018 21:00:13 +0400 Subject: [PATCH 2/3] Increase priority of 1st-person weapon animations to avoid issues with animation blending --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/character.cpp | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a6621bf2..a2014e6be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,6 +83,7 @@ Bug #4563: Fast travel price logic checks destination cell instead of service actor cell Bug #4565: Underwater view distance should be limited Bug #4573: Player uses headtracking in the 1st-person mode + Bug #4575: Weird result of attack animation blending with movement animations Feature #2606: Editor: Implemented (optional) case sensitive global search Feature #3083: Play animation when NPC is casting spell via script Feature #3103: Provide option for disposition to get increased by successful trade diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index b63704e76..11056c674 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1212,9 +1212,10 @@ bool CharacterController::updateWeaponState() mWeapon = weapon != inv.end() ? *weapon : MWWorld::Ptr(); } + // Apply 1st-person weapon animations only for upper body MWRender::Animation::AnimPriority priorityWeapon(Priority_Weapon); - priorityWeapon[MWRender::Animation::BoneGroup_LowerBody] = Priority_WeaponLowerBody; - + if (mPtr != MWMechanics::getPlayer() || !MWBase::Environment::get().getWorld()->isFirstPerson()) + priorityWeapon[MWRender::Animation::BoneGroup_LowerBody] = Priority_WeaponLowerBody; bool forcestateupdate = false; From 780648b584df25c3becbe81dd6166479b3099c67 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 25 Jul 2018 18:50:45 +0400 Subject: [PATCH 3/3] Do not reset idle animations if we do not have ammo --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/character.cpp | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2014e6be..1e516eaf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,6 +84,7 @@ Bug #4565: Underwater view distance should be limited Bug #4573: Player uses headtracking in the 1st-person mode Bug #4575: Weird result of attack animation blending with movement animations + Bug #4576: Reset of idle animations when attack can not be started Feature #2606: Editor: Implemented (optional) case sensitive global search Feature #3083: Play animation when NPC is casting spell via script Feature #3103: Provide option for disposition to get increased by successful trade diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 11056c674..9a6026cc3 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1360,14 +1360,7 @@ bool CharacterController::updateWeaponState() { MWWorld::Ptr player = getPlayer(); - // We should reset player's idle animation in the first-person mode. - if (mPtr == player && MWBase::Environment::get().getWorld()->isFirstPerson()) - mIdleState = CharState_None; - - // In other cases we should not break swim and sneak animations - if (mIdleState != CharState_IdleSneak && mIdleState != CharState_IdleSwim) - mIdleState = CharState_None; - + bool resetIdle = ammunition; if(mUpperBodyState == UpperCharState_WeapEquiped && (mHitState == CharState_None || mHitState == CharState_Block)) { MWBase::Environment::get().getWorld()->breakInvisibility(mPtr); @@ -1432,6 +1425,11 @@ bool CharacterController::updateWeaponState() 0.0f, 0); mUpperBodyState = UpperCharState_CastingSpell; } + else + { + resetIdle = false; + } + if (mPtr.getClass().hasInventoryStore(mPtr)) { MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); @@ -1502,6 +1500,14 @@ bool CharacterController::updateWeaponState() } } + // We should reset player's idle animation in the first-person mode. + if (resetIdle && mPtr == player && MWBase::Environment::get().getWorld()->isFirstPerson()) + mIdleState = CharState_None; + + // In other cases we should not break swim and sneak animations + if (resetIdle && mIdleState != CharState_IdleSneak && mIdleState != CharState_IdleSwim) + mIdleState = CharState_None; + animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); if(mUpperBodyState == UpperCharState_MinAttackToMaxAttack && !isKnockedDown()) mAttackStrength = complete;