Implement wearing priority for editor

pull/1944/head
Andrei Kortunov 6 years ago
parent ac848b0902
commit 35abf7367c

@ -132,6 +132,7 @@
Bug #4653: Length of non-ASCII strings is handled incorrectly in ESM reader Bug #4653: Length of non-ASCII strings is handled incorrectly in ESM reader
Bug #4654: Editor: UpdateVisitor does not initialize skeletons for animated objects Bug #4654: Editor: UpdateVisitor does not initialize skeletons for animated objects
Feature #912: Editor: Add missing icons to UniversalId tables Feature #912: Editor: Add missing icons to UniversalId tables
Feature #1221: Editor: Creature/NPC rendering
Feature #1617: Editor: Enchantment effect record verifier Feature #1617: Editor: Enchantment effect record verifier
Feature #1645: Casting effects from objects Feature #1645: Casting effects from objects
Feature #2606: Editor: Implemented (optional) case sensitive global search Feature #2606: Editor: Implemented (optional) case sensitive global search

@ -112,7 +112,8 @@ namespace CSMWorld
const std::string ActorAdapter::ActorData::getPart(ESM::PartReferenceType index) const const std::string ActorAdapter::ActorData::getPart(ESM::PartReferenceType index) const
{ {
if (mParts[index].empty() && mRaceData && mRaceData->handlesPart(index)) auto it = mParts.find(index);
if (it == mParts.end() && mRaceData && mRaceData->handlesPart(index))
{ {
if (mFemale) if (mFemale)
{ {
@ -124,7 +125,9 @@ namespace CSMWorld
return mRaceData->getMalePart(index); return mRaceData->getMalePart(index);
} }
return mParts[index];
const std::string& partName = it->second.first;
return partName;
} }
bool ActorAdapter::ActorData::hasDependency(const std::string& id) const bool ActorAdapter::ActorData::hasDependency(const std::string& id) const
@ -132,9 +135,16 @@ namespace CSMWorld
return mDependencies.find(id) != mDependencies.end(); return mDependencies.find(id) != mDependencies.end();
} }
void ActorAdapter::ActorData::setPart(ESM::PartReferenceType index, const std::string& partId) void ActorAdapter::ActorData::setPart(ESM::PartReferenceType index, const std::string& partId, int priority)
{ {
mParts[index] = partId; auto it = mParts.find(index);
if (it != mParts.end())
{
if (it->second.second >= priority)
return;
}
mParts[index] = std::make_pair(partId, priority);
addOtherDependency(partId); addOtherDependency(partId);
} }
@ -150,8 +160,7 @@ namespace CSMWorld
mFemale = isFemale; mFemale = isFemale;
mSkeletonOverride = skeleton; mSkeletonOverride = skeleton;
mRaceData = raceData; mRaceData = raceData;
for (auto& str : mParts) mParts.clear();
str.clear();
mDependencies.clear(); mDependencies.clear();
// Mark self and race as a dependency // Mark self and race as a dependency
@ -514,8 +523,8 @@ namespace CSMWorld
} }
// Add head and hair // Add head and hair
data->setPart(ESM::PRT_Head, npc.mHead); data->setPart(ESM::PRT_Head, npc.mHead, 0);
data->setPart(ESM::PRT_Hair, npc.mHair); data->setPart(ESM::PRT_Hair, npc.mHair, 0);
} }
void ActorAdapter::addNpcItem(const std::string& itemId, ActorDataPtr data) void ActorAdapter::addNpcItem(const std::string& itemId, ActorDataPtr data)
@ -537,8 +546,8 @@ namespace CSMWorld
} }
// Convenience function to add a parts list to actor data // Convenience function to add a parts list to actor data
auto addParts = [&](const ESM::PartReferenceList& list) { auto addParts = [&](const std::vector<ESM::PartReference>& list, int priority) {
for (auto& part : list.mParts) for (auto& part : list)
{ {
std::string partId; std::string partId;
auto partType = (ESM::PartReferenceType) part.mPart; auto partType = (ESM::PartReferenceType) part.mPart;
@ -548,7 +557,7 @@ namespace CSMWorld
if (partId.empty()) if (partId.empty())
partId = part.mMale; partId = part.mMale;
if (!partId.empty()) data->setPart(partType, partId); data->setPart(partType, partId, priority);
} }
}; };
@ -557,15 +566,63 @@ namespace CSMWorld
if (type == UniversalId::Type_Armor) if (type == UniversalId::Type_Armor)
{ {
auto& armor = dynamic_cast<const Record<ESM::Armor>&>(record).get(); auto& armor = dynamic_cast<const Record<ESM::Armor>&>(record).get();
addParts(armor.mParts); addParts(armor.mParts.mParts, 1);
// Changing parts could affect what is picked for rendering // Changing parts could affect what is picked for rendering
data->addOtherDependency(itemId); data->addOtherDependency(itemId);
} }
else if (type == UniversalId::Type_Clothing) else if (type == UniversalId::Type_Clothing)
{ {
int priority = 0;
// TODO: reserve bodyparts for robes and skirts
auto& clothing = dynamic_cast<const Record<ESM::Clothing>&>(record).get(); auto& clothing = dynamic_cast<const Record<ESM::Clothing>&>(record).get();
addParts(clothing.mParts);
if (clothing.mData.mType == ESM::Clothing::Robe)
{
auto reservedList = std::vector<ESM::PartReference>();
ESM::PartReference pr;
pr.mMale = "";
pr.mFemale = "";
ESM::PartReferenceType parts[] = {
ESM::PRT_Groin, ESM::PRT_Skirt, ESM::PRT_RLeg, ESM::PRT_LLeg,
ESM::PRT_RUpperarm, ESM::PRT_LUpperarm, ESM::PRT_RKnee, ESM::PRT_LKnee,
ESM::PRT_RForearm, ESM::PRT_LForearm
};
size_t parts_size = sizeof(parts)/sizeof(parts[0]);
for(size_t p = 0;p < parts_size;++p)
{
pr.mPart = parts[p];
reservedList.push_back(pr);
}
priority = parts_size;
addParts(reservedList, priority);
}
else if (clothing.mData.mType == ESM::Clothing::Skirt)
{
auto reservedList = std::vector<ESM::PartReference>();
ESM::PartReference pr;
pr.mMale = "";
pr.mFemale = "";
ESM::PartReferenceType parts[] = {
ESM::PRT_Groin, ESM::PRT_RLeg, ESM::PRT_LLeg
};
size_t parts_size = sizeof(parts)/sizeof(parts[0]);
for(size_t p = 0;p < parts_size;++p)
{
pr.mPart = parts[p];
reservedList.push_back(pr);
}
priority = parts_size;
addParts(reservedList, priority);
}
addParts(clothing.mParts.mParts, priority);
// Changing parts could affect what is picked for rendering // Changing parts could affect what is picked for rendering
data->addOtherDependency(itemId); data->addOtherDependency(itemId);

@ -2,6 +2,7 @@
#define CSM_WOLRD_ACTORADAPTER_H #define CSM_WOLRD_ACTORADAPTER_H
#include <array> #include <array>
#include <map>
#include <unordered_set> #include <unordered_set>
#include <QObject> #include <QObject>
@ -31,7 +32,7 @@ namespace CSMWorld
public: public:
/// A list indexed by ESM::PartReferenceType /// A list indexed by ESM::PartReferenceType
using ActorPartList = std::array<std::string, ESM::PRT_Count>; using ActorPartList = std::map<ESM::PartReferenceType, std::pair<std::string, int>>;
/// A list indexed by ESM::BodyPart::MeshPart /// A list indexed by ESM::BodyPart::MeshPart
using RacePartList = std::array<std::string, ESM::BodyPart::MP_Count>; using RacePartList = std::array<std::string, ESM::BodyPart::MP_Count>;
/// Tracks unique strings /// Tracks unique strings
@ -93,7 +94,7 @@ namespace CSMWorld
bool hasDependency(const std::string& id) const; bool hasDependency(const std::string& id) const;
/// Sets the actor part used and marks a dependency /// Sets the actor part used and marks a dependency
void setPart(ESM::PartReferenceType partIndex, const std::string& partId); void setPart(ESM::PartReferenceType partIndex, const std::string& partId, int priority);
/// Marks an additional dependency for the actor /// Marks an additional dependency for the actor
void addOtherDependency(const std::string& id); void addOtherDependency(const std::string& id);
/// Clears race, parts, and dependencies /// Clears race, parts, and dependencies

Loading…
Cancel
Save