From 3660d5cc4cf6d2984d203fe459a63d6d690f8bf0 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Mon, 1 Nov 2021 19:33:29 +0100 Subject: [PATCH] Reduce code duplication in getting the shield model --- apps/openmw/mwrender/actoranimation.cpp | 38 +++++++++++++------- apps/openmw/mwrender/actoranimation.hpp | 3 +- apps/openmw/mwrender/creatureanimation.cpp | 15 +------- apps/openmw/mwrender/npcanimation.cpp | 42 ++-------------------- apps/openmw/mwrender/npcanimation.hpp | 2 +- 5 files changed, 32 insertions(+), 68 deletions(-) diff --git a/apps/openmw/mwrender/actoranimation.cpp b/apps/openmw/mwrender/actoranimation.cpp index 24ca0aa4f3..e820eb5672 100644 --- a/apps/openmw/mwrender/actoranimation.cpp +++ b/apps/openmw/mwrender/actoranimation.cpp @@ -84,30 +84,42 @@ PartHolderPtr ActorAnimation::attachMesh(const std::string& model, const std::st return PartHolderPtr(new PartHolder(instance)); } -std::string ActorAnimation::getShieldMesh(const MWWorld::ConstPtr& shield) const +std::string ActorAnimation::getShieldMesh(const MWWorld::ConstPtr& shield, bool female) const { - std::string mesh = shield.getClass().getModel(shield); const ESM::Armor *armor = shield.get()->mBase; const std::vector& bodyparts = armor->mParts.mParts; + // Try to recover the body part model, use ground model as a fallback otherwise. if (!bodyparts.empty()) { const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); const MWWorld::Store &partStore = store.get(); - - // Try to get shield model from bodyparts first, with ground model as fallback for (const auto& part : bodyparts) { - // Assume all creatures use the male mesh. - if (part.mPart != ESM::PRT_Shield || part.mMale.empty()) + if (part.mPart != ESM::PRT_Shield) continue; - const ESM::BodyPart *bodypart = partStore.search(part.mMale); - if (bodypart && bodypart->mData.mType == ESM::BodyPart::MT_Armor && !bodypart->mModel.empty()) + + std::string bodypartName; + if (female && !part.mFemale.empty()) + bodypartName = part.mFemale; + else if (!part.mMale.empty()) + bodypartName = part.mMale; + + if (!bodypartName.empty()) { - mesh = "meshes\\" + bodypart->mModel; - break; + const ESM::BodyPart *bodypart = partStore.search(bodypartName); + if (bodypart == nullptr || bodypart->mData.mType != ESM::BodyPart::MT_Armor) + return std::string(); + if (!bodypart->mModel.empty()) + return "meshes\\" + bodypart->mModel; } } } + return shield.getClass().getModel(shield); +} + +std::string ActorAnimation::getSheathedShieldMesh(const MWWorld::ConstPtr& shield) const +{ + std::string mesh = getShieldMesh(shield, false); if (mesh.empty()) return mesh; @@ -143,7 +155,7 @@ bool ActorAnimation::updateCarriedLeftVisible(const int weaptype) const 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 && !getShieldMesh(*shield).empty()) + if (shield != inv.end() && shield->getType() == ESM::Armor::sRecordId && !getSheathedShieldMesh(*shield).empty()) { if(stats.getDrawState() != MWMechanics::DrawState_Weapon) return false; @@ -201,7 +213,7 @@ void ActorAnimation::updateHolsteredShield(bool showCarriedLeft) return; } - std::string mesh = getShieldMesh(*shield); + std::string mesh = getSheathedShieldMesh(*shield); if (mesh.empty()) return; @@ -255,7 +267,7 @@ bool ActorAnimation::useShieldAnimations() const const MWWorld::ConstContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); if (weapon != inv.end() && shield != inv.end() && shield->getType() == ESM::Armor::sRecordId && - !getShieldMesh(*shield).empty()) + !getSheathedShieldMesh(*shield).empty()) { auto type = weapon->getType(); if(type == ESM::Weapon::sRecordId) diff --git a/apps/openmw/mwrender/actoranimation.hpp b/apps/openmw/mwrender/actoranimation.hpp index 61ad1ca235..c68ce4dfe2 100644 --- a/apps/openmw/mwrender/actoranimation.hpp +++ b/apps/openmw/mwrender/actoranimation.hpp @@ -45,7 +45,8 @@ class ActorAnimation : public Animation, public MWWorld::ContainerStoreListener virtual void updateHolsteredWeapon(bool showHolsteredWeapons); virtual void updateHolsteredShield(bool showCarriedLeft); virtual void updateQuiver(); - virtual std::string getShieldMesh(const MWWorld::ConstPtr& shield) const; + std::string getShieldMesh(const MWWorld::ConstPtr& shield, bool female) const; + virtual std::string getSheathedShieldMesh(const MWWorld::ConstPtr& shield) const; virtual std::string getHolsteredWeaponBoneName(const MWWorld::ConstPtr& weapon); virtual PartHolderPtr attachMesh(const std::string& model, const std::string& bonename, bool enchantedGlow, osg::Vec4f* glowColor); virtual PartHolderPtr attachMesh(const std::string& model, const std::string& bonename) diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index 657179db75..7dea8173b6 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -139,20 +139,7 @@ void CreatureWeaponAnimation::updatePart(PartHolderPtr& scene, int slot) bonename = "Shield Bone"; if (item.getType() == ESM::Armor::sRecordId) { - // Shield body part model should be used if possible. - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - for (const auto& part : item.get()->mBase->mParts.mParts) - { - // Assume all creatures use the male mesh. - if (part.mPart != ESM::PRT_Shield || part.mMale.empty()) - continue; - const ESM::BodyPart *bodypart = store.get().search(part.mMale); - if (bodypart && bodypart->mData.mType == ESM::BodyPart::MT_Armor && !bodypart->mModel.empty()) - { - itemModel = "meshes\\" + bodypart->mModel; - break; - } - } + itemModel = getShieldMesh(item, false); } } diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index f3d026ad3c..16cf4cee69 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -82,34 +82,6 @@ std::string getVampireHead(const std::string& race, bool female) return "meshes\\" + bodyPart->mModel; } -std::string getShieldBodypartMesh(const std::vector& bodyparts, bool female) -{ - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - const MWWorld::Store &partStore = store.get(); - for (const auto& part : bodyparts) - { - if (part.mPart != ESM::PRT_Shield) - continue; - - std::string bodypartName; - if (female && !part.mFemale.empty()) - bodypartName = part.mFemale; - else if (!part.mMale.empty()) - bodypartName = part.mMale; - - if (!bodypartName.empty()) - { - const ESM::BodyPart *bodypart = partStore.search(bodypartName); - if (bodypart == nullptr || bodypart->mData.mType != ESM::BodyPart::MT_Armor) - return std::string(); - if (!bodypart->mModel.empty()) - return "meshes\\" + bodypart->mModel; - } - } - - return std::string(); -} - } @@ -547,14 +519,9 @@ void NpcAnimation::updateNpcBase() mWeaponAnimationTime->updateStartTime(); } -std::string NpcAnimation::getShieldMesh(const MWWorld::ConstPtr& shield) const +std::string NpcAnimation::getSheathedShieldMesh(const MWWorld::ConstPtr& shield) const { - std::string mesh = shield.getClass().getModel(shield); - const ESM::Armor *armor = shield.get()->mBase; - const std::vector& bodyparts = armor->mParts.mParts; - // Try to recover the body part model, use ground model as a fallback otherwise. - if (!bodyparts.empty()) - mesh = getShieldBodypartMesh(bodyparts, !mNpc->isMale()); + std::string mesh = getShieldMesh(shield, !mNpc->isMale()); if (mesh.empty()) return std::string(); @@ -1011,10 +978,7 @@ void NpcAnimation::showCarriedLeft(bool show) // For shields we must try to use the body part model if (iter->getType() == ESM::Armor::sRecordId) { - const ESM::Armor *armor = iter->get()->mBase; - const std::vector& bodyparts = armor->mParts.mParts; - if (!bodyparts.empty()) - mesh = getShieldBodypartMesh(bodyparts, !mNpc->isMale()); + mesh = getShieldMesh(*iter, !mNpc->isMale()); } if (mesh.empty() || addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1, mesh, !iter->getClass().getEnchantment(*iter).empty(), &glowColor)) diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index b511a52f37..d0d9a26fdc 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -105,7 +105,7 @@ private: protected: void addControllers() override; bool isArrowAttached() const override; - std::string getShieldMesh(const MWWorld::ConstPtr& shield) const override; + std::string getSheathedShieldMesh(const MWWorld::ConstPtr& shield) const override; public: /**