Merge branch 'distractions' into 'master'

Reduce code duplication in getting the shield model

See merge request OpenMW/openmw!1337
pull/3212/head
psi29a 3 years ago
commit d3b2503111

@ -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<ESM::Armor>()->mBase;
const std::vector<ESM::PartReference>& 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<ESM::BodyPart> &partStore = store.get<ESM::BodyPart>();
// 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)

@ -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)

@ -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<ESM::Armor>()->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<ESM::BodyPart>().search(part.mMale);
if (bodypart && bodypart->mData.mType == ESM::BodyPart::MT_Armor && !bodypart->mModel.empty())
{
itemModel = "meshes\\" + bodypart->mModel;
break;
}
}
itemModel = getShieldMesh(item, false);
}
}

@ -82,34 +82,6 @@ std::string getVampireHead(const std::string& race, bool female)
return "meshes\\" + bodyPart->mModel;
}
std::string getShieldBodypartMesh(const std::vector<ESM::PartReference>& bodyparts, bool female)
{
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const MWWorld::Store<ESM::BodyPart> &partStore = store.get<ESM::BodyPart>();
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<ESM::Armor>()->mBase;
const std::vector<ESM::PartReference>& 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<ESM::Armor>()->mBase;
const std::vector<ESM::PartReference>& 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))

@ -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:
/**

Loading…
Cancel
Save