Add clothing/armor part reference table to dialogue subview.

This commit is contained in:
cc9cii 2015-04-13 21:08:23 +10:00
parent 526b53fce0
commit 513c3a47cb
6 changed files with 222 additions and 33 deletions

View file

@ -250,7 +250,7 @@ namespace CSMWorld
{ ColumnId_AiPackageList, "Ai Packages"}, { ColumnId_AiPackageList, "Ai Packages"},
{ ColumnId_AiPackage, "Package"}, { ColumnId_AiPackage, "Package"},
{ ColumnId_AiWanderDist, "Wander Dist"}, { ColumnId_AiWanderDist, "Wander Dist"},
{ ColumnId_AiWanderDuration, "Wander Duration"}, { ColumnId_AiDuration, "Duration"},
{ ColumnId_AiWanderToD, "Wander ToD"}, { ColumnId_AiWanderToD, "Wander ToD"},
{ ColumnId_AiWanderIdle, "Wander Idle"}, { ColumnId_AiWanderIdle, "Wander Idle"},
{ ColumnId_AiWanderRepeat, "Wander Repeat"}, { ColumnId_AiWanderRepeat, "Wander Repeat"},
@ -258,6 +258,11 @@ namespace CSMWorld
{ ColumnId_AiTargetId, "Target ID"}, { ColumnId_AiTargetId, "Target ID"},
{ ColumnId_AiTargetCell, "Target Cell"}, { ColumnId_AiTargetCell, "Target Cell"},
{ ColumnId_PartRefList, "Part Reference"},
{ ColumnId_PartRefType, "Type"},
{ ColumnId_PartRefMale, "Male"},
{ ColumnId_PartRefFemale, "Female"},
{ ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue1, "Use value 1" },
{ ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue2, "Use value 2" },
{ ColumnId_UseValue3, "Use value 3" }, { ColumnId_UseValue3, "Use value 3" },

View file

@ -239,7 +239,7 @@ namespace CSMWorld
ColumnId_AiPackageList = 219, ColumnId_AiPackageList = 219,
ColumnId_AiPackage = 220, ColumnId_AiPackage = 220,
ColumnId_AiWanderDist = 221, ColumnId_AiWanderDist = 221,
ColumnId_AiWanderDuration = 222, ColumnId_AiDuration = 222,
ColumnId_AiWanderToD = 223, ColumnId_AiWanderToD = 223,
ColumnId_AiWanderIdle = 224, ColumnId_AiWanderIdle = 224,
ColumnId_AiWanderRepeat = 225, ColumnId_AiWanderRepeat = 225,
@ -248,6 +248,11 @@ namespace CSMWorld
ColumnId_AiTargetId = 227, ColumnId_AiTargetId = 227,
ColumnId_AiTargetCell = 228, ColumnId_AiTargetCell = 228,
ColumnId_PartRefList = 229,
ColumnId_PartRefType = 230,
ColumnId_PartRefMale = 231,
ColumnId_PartRefFemale = 232,
// Allocated to a separate value range, so we don't get a collision should we ever need // Allocated to a separate value range, so we don't get a collision should we ever need
// to extend the number of use values. // to extend the number of use values.
ColumnId_UseValue1 = 0x10000, ColumnId_UseValue1 = 0x10000,

View file

@ -175,7 +175,7 @@ namespace CSMWorld
{ {
ESXRecordT raceOrBthSgn = record.get(); ESXRecordT raceOrBthSgn = record.get();
raceOrBthSgn.mPowers.mList = raceOrBthSgn.mPowers.mList =
static_cast<const NestedTableWrapper<std::vector<std::string> >&>(nestedTable).mNestedTable; static_cast<const NestedTableWrapper<std::vector<std::string> >&>(nestedTable).mNestedTable;
record.setModified (raceOrBthSgn); record.setModified (raceOrBthSgn);

View file

@ -81,9 +81,10 @@ void CSMWorld::ApparatusRefIdAdapter::setData (const RefIdColumn *column, RefIdD
CSMWorld::ArmorRefIdAdapter::ArmorRefIdAdapter (const EnchantableColumns& columns, CSMWorld::ArmorRefIdAdapter::ArmorRefIdAdapter (const EnchantableColumns& columns,
const RefIdColumn *type, const RefIdColumn *health, const RefIdColumn *armor) const RefIdColumn *type, const RefIdColumn *health, const RefIdColumn *armor,
const RefIdColumn *partRef)
: EnchantableRefIdAdapter<ESM::Armor> (UniversalId::Type_Armor, columns), : EnchantableRefIdAdapter<ESM::Armor> (UniversalId::Type_Armor, columns),
mType (type), mHealth (health), mArmor (armor) mType (type), mHealth (health), mArmor (armor), mPartRef(partRef)
{} {}
QVariant CSMWorld::ArmorRefIdAdapter::getData (const RefIdColumn *column, QVariant CSMWorld::ArmorRefIdAdapter::getData (const RefIdColumn *column,
@ -101,6 +102,9 @@ QVariant CSMWorld::ArmorRefIdAdapter::getData (const RefIdColumn *column,
if (column==mArmor) if (column==mArmor)
return record.get().mData.mArmor; return record.get().mData.mArmor;
if (column==mPartRef)
return true; // to show nested tables in dialogue subview, see IdTree::hasChildren()
return EnchantableRefIdAdapter<ESM::Armor>::getData (column, data, index); return EnchantableRefIdAdapter<ESM::Armor>::getData (column, data, index);
} }
@ -156,8 +160,9 @@ void CSMWorld::BookRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
} }
CSMWorld::ClothingRefIdAdapter::ClothingRefIdAdapter (const EnchantableColumns& columns, CSMWorld::ClothingRefIdAdapter::ClothingRefIdAdapter (const EnchantableColumns& columns,
const RefIdColumn *type) const RefIdColumn *type, const RefIdColumn *partRef)
: EnchantableRefIdAdapter<ESM::Clothing> (UniversalId::Type_Clothing, columns), mType (type) : EnchantableRefIdAdapter<ESM::Clothing> (UniversalId::Type_Clothing, columns), mType (type),
mPartRef(partRef)
{} {}
QVariant CSMWorld::ClothingRefIdAdapter::getData (const RefIdColumn *column, QVariant CSMWorld::ClothingRefIdAdapter::getData (const RefIdColumn *column,
@ -169,6 +174,9 @@ QVariant CSMWorld::ClothingRefIdAdapter::getData (const RefIdColumn *column,
if (column==mType) if (column==mType)
return record.get().mData.mType; return record.get().mData.mType;
if (column==mPartRef)
return true; // to show nested tables in dialogue subview, see IdTree::hasChildren()
return EnchantableRefIdAdapter<ESM::Clothing>::getData (column, data, index); return EnchantableRefIdAdapter<ESM::Clothing>::getData (column, data, index);
} }

View file

@ -622,11 +622,12 @@ namespace CSMWorld
const RefIdColumn *mType; const RefIdColumn *mType;
const RefIdColumn *mHealth; const RefIdColumn *mHealth;
const RefIdColumn *mArmor; const RefIdColumn *mArmor;
const RefIdColumn *mPartRef;
public: public:
ArmorRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *type, ArmorRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *type,
const RefIdColumn *health, const RefIdColumn *armor); const RefIdColumn *health, const RefIdColumn *armor, const RefIdColumn *partRef);
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
const; const;
@ -657,10 +658,12 @@ namespace CSMWorld
class ClothingRefIdAdapter : public EnchantableRefIdAdapter<ESM::Clothing> class ClothingRefIdAdapter : public EnchantableRefIdAdapter<ESM::Clothing>
{ {
const RefIdColumn *mType; const RefIdColumn *mType;
const RefIdColumn *mPartRef;
public: public:
ClothingRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *type); ClothingRefIdAdapter (const EnchantableColumns& columns,
const RefIdColumn *type, const RefIdColumn *partRef);
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
const; const;
@ -1290,27 +1293,13 @@ namespace CSMWorld
switch (subColIndex) switch (subColIndex)
{ {
case 0: case 0: return QString::fromUtf8(content.mCellName.c_str());
return QString::fromUtf8(content.mCellName.c_str()); case 1: return content.mPos.pos[0];
case 2: return content.mPos.pos[1];
case 1: case 3: return content.mPos.pos[2];
return content.mPos.pos[0]; case 4: return content.mPos.rot[0];
case 5: return content.mPos.rot[1];
case 2: case 6: return content.mPos.rot[2];
return content.mPos.pos[1];
case 3:
return content.mPos.pos[2];
case 4:
return content.mPos.rot[0];
case 5:
return content.mPos.rot[1];
case 6:
return content.mPos.rot[2];
default: default:
throw std::runtime_error("Trying to access non-existing column in the nested table!"); throw std::runtime_error("Trying to access non-existing column in the nested table!");
} }
@ -1675,6 +1664,170 @@ namespace CSMWorld
return static_cast<int>(record.get().mAiPackage.mList.size()); return static_cast<int>(record.get().mAiPackage.mList.size());
} }
}; };
static const char *sPartRefs[ESM::PRT_Count] =
{
"Head", "Hair", "Neck", "Cuirass", "Groin",
"Skirt", "Right Hand", "Left Hand", "Right Wrist", "Left Wrist",
"Shield", "Right Forearm", "Left Forearm", "Right Upperarm", "Left Upperarm",
"Right Foot", "Left Foot", "Right Ankle", "Left Ankle", "Right Knee",
"Left Knee", "Right Leg", "Left Leg", "Right Pauldron", "Left Pauldron",
"Weapon", "Tail"
};
template <typename ESXRecordT>
class BodyPartRefIdAdapter : public NestedRefIdAdapterBase
{
UniversalId::Type mType;
// not implemented
BodyPartRefIdAdapter (const BodyPartRefIdAdapter&);
BodyPartRefIdAdapter& operator= (const BodyPartRefIdAdapter&);
public:
BodyPartRefIdAdapter(UniversalId::Type type) :mType(type) {}
virtual ~BodyPartRefIdAdapter() {}
virtual void addNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int position) const
{
Record<ESXRecordT>& record =
static_cast<Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
ESXRecordT apparel = record.get();
std::vector<ESM::PartReference>& list = apparel.mParts.mParts;
ESM::PartReference newPart;
newPart.mPart = 0; // 0 == head
newPart.mMale = "";
newPart.mFemale = "";
if (position >= (int)list.size())
list.push_back(newPart);
else
list.insert(list.begin()+position, newPart);
record.setModified (apparel);
}
virtual void removeNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int rowToRemove) const
{
Record<ESXRecordT>& record =
static_cast<Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
ESXRecordT apparel = record.get();
std::vector<ESM::PartReference>& list = apparel.mParts.mParts;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (list.size()))
throw std::runtime_error ("index out of range");
list.erase (list.begin () + rowToRemove);
record.setModified (apparel);
}
virtual void setNestedTable (const RefIdColumn* column,
RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const
{
Record<ESXRecordT>& record =
static_cast<Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
ESXRecordT apparel = record.get();
apparel.mParts.mParts =
static_cast<const NestedTableWrapper<std::vector<typename ESM::PartReference> >&>(nestedTable).mNestedTable;
record.setModified (apparel);
}
virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column,
const RefIdData& data, int index) const
{
const Record<ESXRecordT>& record =
static_cast<const Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<typename ESM::PartReference> >(record.get().mParts.mParts);
}
virtual QVariant getNestedData (const RefIdColumn *column,
const RefIdData& data, int index, int subRowIndex, int subColIndex) const
{
const Record<ESXRecordT>& record =
static_cast<const Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
const std::vector<ESM::PartReference>& list = record.get().mParts.mParts;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (list.size()))
throw std::runtime_error ("index out of range");
const ESM::PartReference& content = list.at(subRowIndex);
switch (subColIndex)
{
case 0: return QString(sPartRefs[content.mPart]);
case 1: return QString(content.mMale.c_str());
case 2: return QString(content.mFemale.c_str());
default:
throw std::runtime_error("Trying to access non-existing column in the nested table!");
}
}
virtual void setNestedData (const RefIdColumn *column,
RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const
{
Record<ESXRecordT>& record =
static_cast<Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (row, mType)));
ESXRecordT apparel = record.get();
std::vector<ESM::PartReference>& list = apparel.mParts.mParts;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (list.size()))
throw std::runtime_error ("index out of range");
switch(subColIndex)
{
case 0:
{
std::string part = value.toString().toStdString();
bool found = false;
for (unsigned int i = 0; i < ESM::PRT_Count; ++i)
{
if (part == sPartRefs[i])
{
list.at(subRowIndex).mPart = static_cast<unsigned char>(i);
found = true;
break;
}
}
if (!found)
return; // return without saving
else
break;
}
case 1: list.at(subRowIndex).mMale = value.toString().toStdString(); break;
case 2: list.at(subRowIndex).mFemale = value.toString().toStdString(); break;
default:
throw std::runtime_error("Trying to access non-existing column in the nested table!");
}
record.setModified (apparel);
}
virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const
{
return 3;
}
virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const
{
const Record<ESXRecordT>& record =
static_cast<const Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
return static_cast<int>(record.get().mParts.mParts.size());
}
};
} }
#endif #endif

View file

@ -196,7 +196,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_AiWanderDist, CSMWorld::ColumnBase::Display_Integer)); new RefIdColumn (Columns::ColumnId_AiWanderDist, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_AiWanderDuration, CSMWorld::ColumnBase::Display_Integer)); new RefIdColumn (Columns::ColumnId_AiDuration, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_AiWanderToD, CSMWorld::ColumnBase::Display_Integer)); new RefIdColumn (Columns::ColumnId_AiWanderToD, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn( mColumns.back().addColumn(
@ -475,6 +475,24 @@ CSMWorld::RefIdCollection::RefIdCollection()
weaponColumns.mFlags.insert (std::make_pair (&mColumns.back(), sWeaponFlagTable[i].mFlag)); weaponColumns.mFlags.insert (std::make_pair (&mColumns.back(), sWeaponFlagTable[i].mFlag));
} }
// Nested table
mColumns.push_back(RefIdColumn (Columns::ColumnId_PartRefList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
const RefIdColumn *partRef = &mColumns.back();
std::map<UniversalId::Type, NestedRefIdAdapterBase*> partMap;
partMap.insert(
std::make_pair(UniversalId::Type_Armor, new BodyPartRefIdAdapter<ESM::Armor> (UniversalId::Type_Armor)));
partMap.insert(
std::make_pair(UniversalId::Type_Clothing, new BodyPartRefIdAdapter<ESM::Clothing> (UniversalId::Type_Clothing)));
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), partMap));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_PartRefType, CSMWorld::ColumnBase::Display_String));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_PartRefMale, CSMWorld::ColumnBase::Display_String));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_PartRefFemale, CSMWorld::ColumnBase::Display_String));
mAdapters.insert (std::make_pair (UniversalId::Type_Activator, mAdapters.insert (std::make_pair (UniversalId::Type_Activator,
new NameRefIdAdapter<ESM::Activator> (UniversalId::Type_Activator, nameColumns))); new NameRefIdAdapter<ESM::Activator> (UniversalId::Type_Activator, nameColumns)));
mAdapters.insert (std::make_pair (UniversalId::Type_Potion, mAdapters.insert (std::make_pair (UniversalId::Type_Potion,
@ -482,11 +500,11 @@ CSMWorld::RefIdCollection::RefIdCollection()
mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus,
new ApparatusRefIdAdapter (inventoryColumns, apparatusType, toolsColumns.mQuality))); new ApparatusRefIdAdapter (inventoryColumns, apparatusType, toolsColumns.mQuality)));
mAdapters.insert (std::make_pair (UniversalId::Type_Armor, mAdapters.insert (std::make_pair (UniversalId::Type_Armor,
new ArmorRefIdAdapter (enchantableColumns, armorType, health, armor))); new ArmorRefIdAdapter (enchantableColumns, armorType, health, armor, partRef)));
mAdapters.insert (std::make_pair (UniversalId::Type_Book, mAdapters.insert (std::make_pair (UniversalId::Type_Book,
new BookRefIdAdapter (enchantableColumns, scroll, attribute))); new BookRefIdAdapter (enchantableColumns, scroll, attribute)));
mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, mAdapters.insert (std::make_pair (UniversalId::Type_Clothing,
new ClothingRefIdAdapter (enchantableColumns, clothingType))); new ClothingRefIdAdapter (enchantableColumns, clothingType, partRef)));
mAdapters.insert (std::make_pair (UniversalId::Type_Container, mAdapters.insert (std::make_pair (UniversalId::Type_Container,
new ContainerRefIdAdapter (nameColumns, weightCapacity, organic, respawn, content))); new ContainerRefIdAdapter (nameColumns, weightCapacity, organic, respawn, content)));
mAdapters.insert (std::make_pair (UniversalId::Type_Creature, mAdapters.insert (std::make_pair (UniversalId::Type_Creature,