From 32e73c3debf67f5cfb64671daca1c32b8d12dd4a Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 17 Apr 2015 11:50:19 +1000 Subject: [PATCH] Add creature/item levelled lists (non table items) to dialogue subview. --- apps/opencs/model/world/columns.cpp | 88 ++++++------- apps/opencs/model/world/columns.hpp | 2 + apps/opencs/model/world/refidadapterimp.hpp | 131 +++++++++++++++++++- apps/opencs/model/world/refidcollection.cpp | 14 +++ 4 files changed, 191 insertions(+), 44 deletions(-) diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 83d6ceb57..81968d114 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -223,49 +223,51 @@ namespace CSMWorld { ColumnId_AreaSound, "Area Sound" }, { ColumnId_BoltSound, "Bolt Sound" }, - { ColumnId_PathgridPoints, "Points"}, - { ColumnId_PathgridIndex, "Index"}, - { ColumnId_PathgridPosX, "X"}, - { ColumnId_PathgridPosY, "Y"}, - { ColumnId_PathgridPosZ, "Z"}, - { ColumnId_PathgridEdges, "Edges"}, - { ColumnId_PathgridEdgeIndex, "Index"}, - { ColumnId_PathgridEdge0, "Point 0"}, - { ColumnId_PathgridEdge1, "Point 1"}, - - { ColumnId_RegionSounds, "Sounds"}, - { ColumnId_SoundName, "Name"}, - { ColumnId_SoundChance, "Chance"}, - - { ColumnId_FactionReactions, "Reactions"}, - //{ ColumnId_FactionID, "Faction ID"}, - { ColumnId_FactionReaction, "Reaction"}, - - { ColumnId_EffectList, "Effects"}, - { ColumnId_EffectId, "Effect"}, - //{ ColumnId_EffectAttribute, "Attrib"}, - { ColumnId_EffectRange, "Range"}, - { ColumnId_EffectArea, "Area"}, - - { ColumnId_AiPackageList, "Ai Packages"}, - { ColumnId_AiPackage, "Package"}, - { ColumnId_AiWanderDist, "Wander Dist"}, - { ColumnId_AiDuration, "Duration"}, - { ColumnId_AiWanderToD, "Wander ToD"}, - { ColumnId_AiWanderIdle, "Wander Idle"}, - { ColumnId_AiWanderRepeat, "Wander Repeat"}, - { ColumnId_AiActivateName, "Activate"}, - { ColumnId_AiTargetId, "Target ID"}, - { ColumnId_AiTargetCell, "Target Cell"}, - - { ColumnId_PartRefList, "Part Reference"}, - { ColumnId_PartRefType, "Type"}, - { ColumnId_PartRefMale, "Male"}, - { ColumnId_PartRefFemale, "Female"}, - - { ColumnId_LevelledList,"Levelled List"}, - { ColumnId_LevelledItemId,"Item ID"}, - { ColumnId_LevelledItemLevel,"Level"}, + { ColumnId_PathgridPoints, "Points" }, + { ColumnId_PathgridIndex, "Index" }, + { ColumnId_PathgridPosX, "X" }, + { ColumnId_PathgridPosY, "Y" }, + { ColumnId_PathgridPosZ, "Z" }, + { ColumnId_PathgridEdges, "Edges" }, + { ColumnId_PathgridEdgeIndex, "Index" }, + { ColumnId_PathgridEdge0, "Point 0" }, + { ColumnId_PathgridEdge1, "Point 1" }, + + { ColumnId_RegionSounds, "Sounds" }, + { ColumnId_SoundName, "Name" }, + { ColumnId_SoundChance, "Chance" }, + + { ColumnId_FactionReactions, "Reactions" }, + //{ ColumnId_FactionID, "Faction ID" }, + { ColumnId_FactionReaction, "Reaction" }, + + { ColumnId_EffectList, "Effects" }, + { ColumnId_EffectId, "Effect" }, + //{ ColumnId_EffectAttribute, "Attrib" }, + { ColumnId_EffectRange, "Range" }, + { ColumnId_EffectArea, "Area" }, + + { ColumnId_AiPackageList, "Ai Packages" }, + { ColumnId_AiPackage, "Package" }, + { ColumnId_AiWanderDist, "Wander Dist" }, + { ColumnId_AiDuration, "Duration" }, + { ColumnId_AiWanderToD, "Wander ToD" }, + { ColumnId_AiWanderIdle, "Wander Idle" }, + { ColumnId_AiWanderRepeat, "Wander Repeat" }, + { ColumnId_AiActivateName, "Activate" }, + { ColumnId_AiTargetId, "Target ID" }, + { ColumnId_AiTargetCell, "Target Cell" }, + + { ColumnId_PartRefList, "Part Reference" }, + { ColumnId_PartRefType, "Type" }, + { ColumnId_PartRefMale, "Male" }, + { ColumnId_PartRefFemale, "Female" }, + + { ColumnId_LevelledList,"Levelled List" }, + { ColumnId_LevelledItemId,"Item ID" }, + { ColumnId_LevelledItemLevel,"Level" }, + { ColumnId_LevelledItemType, "Type" }, + { ColumnId_LevelledItemChanceNone, "Chance None" }, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 81cae5e36..986b90df5 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -256,6 +256,8 @@ namespace CSMWorld ColumnId_LevelledList = 233, ColumnId_LevelledItemId = 234, ColumnId_LevelledItemLevel = 235, + ColumnId_LevelledItemType = 236, + ColumnId_LevelledItemChanceNone = 237, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index d09aaaa45..2b2b189e0 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -1829,9 +1829,11 @@ namespace CSMWorld } }; + struct LevListColumns : public BaseColumns { const RefIdColumn *mLevList; + const RefIdColumn *mNestedListLevList; LevListColumns (const BaseColumns& base) : BaseColumns (base) {} }; @@ -1863,7 +1865,7 @@ namespace CSMWorld QVariant LevelledListRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, int index) const { - if (column==mLevList.mLevList) + if (column==mLevList.mLevList || column == mLevList.mNestedListLevList) return true; // to show nested tables in dialogue subview, see IdTree::hasChildren() return BaseRefIdAdapter::getData (column, data, index); @@ -1877,6 +1879,133 @@ namespace CSMWorld return; } + + template + class NestedListLevListRefIdAdapter : public NestedRefIdAdapterBase + { + + UniversalId::Type mType; + + // not implemented + NestedListLevListRefIdAdapter (const NestedListLevListRefIdAdapter&); + NestedListLevListRefIdAdapter& operator= (const NestedListLevListRefIdAdapter&); + + public: + + NestedListLevListRefIdAdapter(UniversalId::Type type) + :mType(type) {} + + virtual ~NestedListLevListRefIdAdapter() {} + + virtual void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const + { + throw std::logic_error ("cannot add a row to a fixed table"); + } + + virtual void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const + { + throw std::logic_error ("cannot remove a row to a fixed table"); + } + + virtual void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + { + throw std::logic_error ("table operation not supported"); + } + + virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const + { + throw std::logic_error ("table operation not supported"); + } + + virtual QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + switch (subColIndex) + { + case 0: + { + if (mType == CSMWorld::UniversalId::Type_CreatureLevelledList && + record.get().mFlags == 0x01) + { + return QString("All Levels"); + } + else if(mType == CSMWorld::UniversalId::Type_ItemLevelledList && + record.get().mFlags == 0x01) + { + return QString("Each"); + } + else if(mType == CSMWorld::UniversalId::Type_ItemLevelledList && + record.get().mFlags == 0x02) + { + return QString("All Levels"); + } + else + throw std::runtime_error("unknown leveled list type"); + } + case 1: return static_cast (record.get().mChanceNone); + 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& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + ESXRecordT leveled = record.get(); + + switch(subColIndex) + { + case 0: + { + if (mType == CSMWorld::UniversalId::Type_CreatureLevelledList && + value.toString().toStdString() == "All Levels") + { + leveled.mFlags = 0x01; + break; + } + else if(mType == CSMWorld::UniversalId::Type_ItemLevelledList && + value.toString().toStdString() == "Each") + { + leveled.mFlags = 0x01; + break; + } + else if(mType == CSMWorld::UniversalId::Type_ItemLevelledList && + value.toString().toStdString() == "All Levels") + { + leveled.mFlags = 0x02; + break; + } + else + return; // return without saving + } + case 1: leveled.mChanceNone = static_cast(value.toInt()); break; + default: + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + } + + record.setModified (leveled); + } + + virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + { + return 2; + } + + virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + { + return 1; // fixed at size 1 + } + }; + template class NestedLevListRefIdAdapter : public NestedRefIdAdapterBase { diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index be5d67766..02d876df8 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -503,6 +503,20 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_LevelledItemLevel, CSMWorld::ColumnBase::Display_Integer)); + // Nested list + mColumns.push_back(RefIdColumn (Columns::ColumnId_LevelledList, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List)); + levListColumns.mNestedListLevList = &mColumns.back(); + std::map nestedListLevListMap; + nestedListLevListMap.insert(std::make_pair(UniversalId::Type_CreatureLevelledList, + new NestedListLevListRefIdAdapter (UniversalId::Type_CreatureLevelledList))); + nestedListLevListMap.insert(std::make_pair(UniversalId::Type_ItemLevelledList, + new NestedListLevListRefIdAdapter (UniversalId::Type_ItemLevelledList))); + mNestedAdapters.push_back (std::make_pair(&mColumns.back(), nestedListLevListMap)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_LevelledItemType, CSMWorld::ColumnBase::Display_String)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_LevelledItemChanceNone, CSMWorld::ColumnBase::Display_Integer)); mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns)));