mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-28 11:39:42 +00:00
Use shield body part model for creatures (bug #5250)
This commit is contained in:
parent
2bed25a5e8
commit
bbe5adb860
4 changed files with 61 additions and 7 deletions
|
@ -191,6 +191,7 @@
|
|||
Bug #5239: OpenMW-CS does not support non-ASCII characters in path names
|
||||
Bug #5241: On-self absorb spells cannot be detected
|
||||
Bug #5242: ExplodeSpell behavior differs from Cast behavior
|
||||
Bug #5250: Creatures display shield ground mesh instead of shield body part
|
||||
Feature #1774: Handle AvoidNode
|
||||
Feature #2229: Improve pathfinding AI
|
||||
Feature #3025: Analogue gamepad movement controls
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
#include "../mwmechanics/actorutil.hpp"
|
||||
#include "../mwmechanics/weapontype.hpp"
|
||||
|
||||
|
@ -87,6 +88,31 @@ PartHolderPtr ActorAnimation::attachMesh(const std::string& model, const std::st
|
|||
std::string ActorAnimation::getShieldMesh(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;
|
||||
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())
|
||||
continue;
|
||||
const ESM::BodyPart *bodypart = partStore.search(part.mMale);
|
||||
if (bodypart && bodypart->mData.mType == ESM::BodyPart::MT_Armor && !bodypart->mModel.empty())
|
||||
{
|
||||
mesh = "meshes\\" + bodypart->mModel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mesh.empty())
|
||||
return mesh;
|
||||
|
||||
std::string holsteredName = mesh;
|
||||
holsteredName = holsteredName.replace(holsteredName.size()-4, 4, "_sh.nif");
|
||||
if(mResourceSystem->getVFS()->exists(holsteredName))
|
||||
|
|
|
@ -13,11 +13,13 @@
|
|||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "../mwmechanics/weapontype.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
|
@ -114,6 +116,7 @@ void CreatureWeaponAnimation::updatePart(PartHolderPtr& scene, int slot)
|
|||
MWWorld::ConstPtr item = *it;
|
||||
|
||||
std::string bonename;
|
||||
std::string itemModel = item.getClass().getModel(item);
|
||||
if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
|
||||
{
|
||||
if(item.getTypeName() == typeid(ESM::Weapon).name())
|
||||
|
@ -132,11 +135,30 @@ void CreatureWeaponAnimation::updatePart(PartHolderPtr& scene, int slot)
|
|||
bonename = "Weapon Bone";
|
||||
}
|
||||
else
|
||||
{
|
||||
bonename = "Shield Bone";
|
||||
if (item.getTypeName() == typeid(ESM::Armor).name())
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->getInstance(item.getClass().getModel(item));
|
||||
osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->getInstance(itemModel);
|
||||
|
||||
const NodeMap& nodeMap = getNodeMap();
|
||||
NodeMap::const_iterator found = nodeMap.find(Misc::StringUtils::lowerCase(bonename));
|
||||
|
|
|
@ -518,14 +518,14 @@ std::string NpcAnimation::getShieldMesh(MWWorld::ConstPtr shield) const
|
|||
{
|
||||
std::string mesh = shield.getClass().getModel(shield);
|
||||
const ESM::Armor *armor = shield.get<ESM::Armor>()->mBase;
|
||||
std::vector<ESM::PartReference> bodyparts = armor->mParts.mParts;
|
||||
const std::vector<ESM::PartReference>& bodyparts = armor->mParts.mParts;
|
||||
if (!bodyparts.empty())
|
||||
{
|
||||
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
||||
const MWWorld::Store<ESM::BodyPart> &partStore = store.get<ESM::BodyPart>();
|
||||
|
||||
// For NPCs try to get shield model from bodyparts first, with ground model as fallback
|
||||
for (auto & part : bodyparts)
|
||||
// Try to get shield model from bodyparts first, with ground model as fallback
|
||||
for (const auto& part : bodyparts)
|
||||
{
|
||||
if (part.mPart != ESM::PRT_Shield)
|
||||
continue;
|
||||
|
@ -538,16 +538,21 @@ std::string NpcAnimation::getShieldMesh(MWWorld::ConstPtr shield) const
|
|||
|
||||
if (!bodypartName.empty())
|
||||
{
|
||||
const ESM::BodyPart *bodypart = 0;
|
||||
bodypart = partStore.search(bodypartName);
|
||||
const ESM::BodyPart *bodypart = partStore.search(bodypartName);
|
||||
if (bodypart == nullptr || bodypart->mData.mType != ESM::BodyPart::MT_Armor)
|
||||
return "";
|
||||
return std::string();
|
||||
else if (!bodypart->mModel.empty())
|
||||
{
|
||||
mesh = "meshes\\" + bodypart->mModel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mesh.empty())
|
||||
return std::string();
|
||||
|
||||
std::string holsteredName = mesh;
|
||||
holsteredName = holsteredName.replace(holsteredName.size()-4, 4, "_sh.nif");
|
||||
if(mResourceSystem->getVFS()->exists(holsteredName))
|
||||
|
|
Loading…
Reference in a new issue