diff --git a/apps/openmw/mwrender/actoranimation.cpp b/apps/openmw/mwrender/actoranimation.cpp index c238664ae5..3d5daf74e0 100644 --- a/apps/openmw/mwrender/actoranimation.cpp +++ b/apps/openmw/mwrender/actoranimation.cpp @@ -158,33 +158,16 @@ bool ActorAnimation::updateCarriedLeftVisible(const int weaptype) const { const MWWorld::Class &cls = mPtr.getClass(); MWMechanics::CreatureStats &stats = cls.getCreatureStats(mPtr); - if (cls.hasInventoryStore(mPtr) && weaptype != ESM::Weapon::Spell) + if (cls.hasInventoryStore(mPtr) && stats.getDrawState() == MWMechanics::DrawState::Nothing) { SceneUtil::FindByNameVisitor findVisitor ("Bip01 AttachShield"); mObjectRoot->accept(findVisitor); - if (findVisitor.mFoundNode || (mPtr == MWMechanics::getPlayer() && mPtr.isInCell() && MWBase::Environment::get().getWorld()->isFirstPerson())) + if (findVisitor.mFoundNode) { const MWWorld::InventoryStore& inv = cls.getInventoryStore(mPtr); - const MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); const MWWorld::ConstContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); if (shield != inv.end() && shield->getType() == ESM::Armor::sRecordId && !getSheathedShieldMesh(*shield).empty()) - { - if(stats.getDrawState() != MWMechanics::DrawState::Weapon) - return false; - - if (weapon != inv.end()) - { - auto type = weapon->getType(); - if(type == ESM::Weapon::sRecordId) - { - const MWWorld::LiveCellRef *ref = weapon->get(); - ESM::Weapon::Type weaponType = (ESM::Weapon::Type)ref->mBase->mData.mType; - return !(MWMechanics::getWeaponType(weaponType)->mFlags & ESM::WeaponType::TwoHanded); - } - else if (type == ESM::Lockpick::sRecordId || type == ESM::Probe::sRecordId) - return true; - } - } + return false; } } } diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index bd9fe543c4..a7c48864dd 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -295,13 +295,23 @@ void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode) assert(viewMode != VM_HeadOnly); if(mViewMode == viewMode) return; - + // FIXME: sheathing state must be consistent if the third person skeleton doesn't have the necessary node, but + // third person skeleton is unavailable in first person view. This is a hack to avoid cosmetic issues. + bool viewChange = mViewMode == VM_FirstPerson || viewMode == VM_FirstPerson; mViewMode = viewMode; MWBase::Environment::get().getWorld()->scaleObject(mPtr, mPtr.getCellRef().getScale(), true); // apply race height after view change mAmmunition.reset(); rebuild(); setRenderBin(); + + static const bool shieldSheathing = Settings::Manager::getBool("shield sheathing", "Game"); + if (viewChange && shieldSheathing) + { + int weaptype = ESM::Weapon::None; + MWMechanics::getActiveWeapon(mPtr, &weaptype); + showCarriedLeft(updateCarriedLeftVisible(weaptype)); + } } /// @brief A RenderBin callback to clear the depth buffer before rendering. @@ -983,6 +993,30 @@ void NpcAnimation::showWeapons(bool showWeapon) updateQuiver(); } +bool NpcAnimation::updateCarriedLeftVisible(const int weaptype) const +{ + static const bool shieldSheathing = Settings::Manager::getBool("shield sheathing", "Game"); + if (shieldSheathing) + { + const MWWorld::Class &cls = mPtr.getClass(); + MWMechanics::CreatureStats &stats = cls.getCreatureStats(mPtr); + if (stats.getDrawState() == MWMechanics::DrawState::Nothing) + { + SceneUtil::FindByNameVisitor findVisitor ("Bip01 AttachShield"); + mObjectRoot->accept(findVisitor); + if (findVisitor.mFoundNode || mViewMode == VM_FirstPerson) + { + const MWWorld::InventoryStore& inv = cls.getInventoryStore(mPtr); + const MWWorld::ConstContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); + if (shield != inv.end() && shield->getType() == ESM::Armor::sRecordId && !getSheathedShieldMesh(*shield).empty()) + return false; + } + } + } + + return !(MWMechanics::getWeaponType(weaptype)->mFlags & ESM::WeaponType::TwoHanded); +} + void NpcAnimation::showCarriedLeft(bool show) { mShowCarriedLeft = show; diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 2dcfac3036..d16b339ec6 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -137,6 +137,7 @@ public: void showWeapons(bool showWeapon) override; + bool updateCarriedLeftVisible(const int weaptype) const override; bool getCarriedLeftShown() const override { return mShowCarriedLeft; } void showCarriedLeft(bool show) override;