mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 20:56:39 +00:00 
			
		
		
		
	Add the remaining NPC data for editing with dialogue subview. Should resolve Bug #2547.
This commit is contained in:
		
							parent
							
								
									7b207a7954
								
							
						
					
					
						commit
						7494340b66
					
				
					 6 changed files with 535 additions and 2 deletions
				
			
		|  | @ -281,6 +281,21 @@ namespace CSMWorld | |||
|             { ColumnId_InfoCondValue, "Value" }, | ||||
|             { ColumnId_OriginalCell, "Original Cell" }, | ||||
| 
 | ||||
|             { ColumnId_NpcAttributes, "Attributes" }, | ||||
|             { ColumnId_NpcSkills, "Skills" }, | ||||
|             { ColumnId_UChar, "Value [0..255]" }, | ||||
|             { ColumnId_NpcMisc, "Misc" }, | ||||
|             { ColumnId_NpcLevel, "Level" }, | ||||
|             { ColumnId_NpcFactionID, "Faction ID" }, | ||||
|             { ColumnId_NpcHealth, "Health" }, | ||||
|             { ColumnId_NpcMana, "Mana" }, | ||||
|             { ColumnId_NpcFatigue, "Fatigue" }, | ||||
|             { ColumnId_NpcDisposition, "Disposition" }, | ||||
|             { ColumnId_NpcReputation, "Reputation" }, | ||||
|             { ColumnId_NpcRank, "Rank" }, | ||||
|             { ColumnId_NpcGold, "Gold" }, | ||||
|             { ColumnId_NpcPersistence, "Persistent" }, | ||||
| 
 | ||||
|             { ColumnId_UseValue1, "Use value 1" }, | ||||
|             { ColumnId_UseValue2, "Use value 2" }, | ||||
|             { ColumnId_UseValue3, "Use value 3" }, | ||||
|  |  | |||
|  | @ -272,6 +272,21 @@ namespace CSMWorld | |||
| 
 | ||||
|             ColumnId_OriginalCell = 247, | ||||
| 
 | ||||
|             ColumnId_NpcAttributes = 248, | ||||
|             ColumnId_NpcSkills = 249, | ||||
|             ColumnId_UChar = 250, | ||||
|             ColumnId_NpcMisc = 251, | ||||
|             ColumnId_NpcLevel = 252, | ||||
|             ColumnId_NpcFactionID = 253, | ||||
|             ColumnId_NpcHealth = 254, | ||||
|             ColumnId_NpcMana = 255, | ||||
|             ColumnId_NpcFatigue = 256, | ||||
|             ColumnId_NpcDisposition = 257, | ||||
|             ColumnId_NpcReputation = 258, | ||||
|             ColumnId_NpcRank = 259, | ||||
|             ColumnId_NpcGold = 260, | ||||
|             ColumnId_NpcPersistence = 261, | ||||
| 
 | ||||
|             // Allocated to a separate value range, so we don't get a collision should we ever need
 | ||||
|             // to extend the number of use values.
 | ||||
|             ColumnId_UseValue1 = 0x10000, | ||||
|  |  | |||
|  | @ -468,7 +468,10 @@ CSMWorld::NpcColumns::NpcColumns (const ActorColumns& actorColumns) | |||
|   mClass(NULL), | ||||
|   mFaction(NULL), | ||||
|   mHair(NULL), | ||||
|   mHead(NULL) | ||||
|   mHead(NULL), | ||||
|   mAttributes(NULL), | ||||
|   mSkills(NULL), | ||||
|   mMisc(NULL) | ||||
| {} | ||||
| 
 | ||||
| CSMWorld::NpcRefIdAdapter::NpcRefIdAdapter (const NpcColumns& columns) | ||||
|  | @ -496,6 +499,17 @@ QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const Re | |||
|     if (column==mColumns.mHead) | ||||
|         return QString::fromUtf8 (record.get().mHead.c_str()); | ||||
| 
 | ||||
|     if (column==mColumns.mAttributes || column==mColumns.mSkills) | ||||
|     { | ||||
|         if ((record.get().mFlags & ESM::NPC::Autocalc) != 0) | ||||
|             return QVariant(); | ||||
|         else | ||||
|             return true; | ||||
|     } | ||||
| 
 | ||||
|     if (column==mColumns.mMisc) | ||||
|         return true; | ||||
| 
 | ||||
|     std::map<const RefIdColumn *, unsigned int>::const_iterator iter = | ||||
|         mColumns.mFlags.find (column); | ||||
| 
 | ||||
|  | @ -538,6 +552,340 @@ void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& d | |||
|     } | ||||
| } | ||||
| 
 | ||||
| CSMWorld::NpcAttributesRefIdAdapter::NpcAttributesRefIdAdapter () | ||||
| {} | ||||
| 
 | ||||
| void CSMWorld::NpcAttributesRefIdAdapter::addNestedRow (const RefIdColumn *column, | ||||
|         RefIdData& data, int index, int position) const | ||||
| { | ||||
|     // Do nothing, this table cannot be changed by the user
 | ||||
| } | ||||
| 
 | ||||
| void CSMWorld::NpcAttributesRefIdAdapter::removeNestedRow (const RefIdColumn *column, | ||||
|         RefIdData& data, int index, int rowToRemove) const | ||||
| { | ||||
|     // Do nothing, this table cannot be changed by the user
 | ||||
| } | ||||
| 
 | ||||
| void CSMWorld::NpcAttributesRefIdAdapter::setNestedTable (const RefIdColumn* column, | ||||
|         RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const | ||||
| { | ||||
|     Record<ESM::NPC>& record = | ||||
|         static_cast<Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); | ||||
|     ESM::NPC npc = record.get(); | ||||
| 
 | ||||
|     // store the whole struct
 | ||||
|     npc.mNpdt52 = | ||||
|         static_cast<const NestedTableWrapper<std::vector<typename ESM::NPC::NPDTstruct52> > &>(nestedTable).mNestedTable.at(0); | ||||
| 
 | ||||
|     record.setModified (npc); | ||||
| } | ||||
| 
 | ||||
| CSMWorld::NestedTableWrapperBase* CSMWorld::NpcAttributesRefIdAdapter::nestedTable (const RefIdColumn* column, | ||||
|         const RefIdData& data, int index) const | ||||
| { | ||||
|     const Record<ESM::NPC>& record = | ||||
|         static_cast<const Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); | ||||
| 
 | ||||
|     // return the whole struct
 | ||||
|     std::vector<typename ESM::NPC::NPDTstruct52> wrap; | ||||
|     wrap.push_back(record.get().mNpdt52); | ||||
|     // deleted by dtor of NestedTableStoring
 | ||||
|     return new NestedTableWrapper<std::vector<typename ESM::NPC::NPDTstruct52> >(wrap); | ||||
| } | ||||
| 
 | ||||
| QVariant CSMWorld::NpcAttributesRefIdAdapter::getNestedData (const RefIdColumn *column, | ||||
|         const RefIdData& data, int index, int subRowIndex, int subColIndex) const | ||||
| { | ||||
|     const Record<ESM::NPC>& record = | ||||
|         static_cast<const Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); | ||||
| 
 | ||||
|     const ESM::NPC::NPDTstruct52& npcStruct = record.get().mNpdt52; | ||||
| 
 | ||||
|     if (subColIndex == 0) | ||||
|         switch (subRowIndex) | ||||
|         { | ||||
|             case 0: return QString("Strength"); | ||||
|             case 1: return QString("Intelligence"); | ||||
|             case 2: return QString("Willpower"); | ||||
|             case 3: return QString("Agility"); | ||||
|             case 4: return QString("Speed"); | ||||
|             case 5: return QString("Endurance"); | ||||
|             case 6: return QString("Personality"); | ||||
|             case 7: return QString("Luck"); | ||||
|             default: return QVariant(); // throw an exception here?
 | ||||
|         } | ||||
|     else if (subColIndex == 1) | ||||
|         switch (subRowIndex) | ||||
|         { | ||||
|             case 0: return static_cast<int>(npcStruct.mStrength); | ||||
|             case 1: return static_cast<int>(npcStruct.mIntelligence); | ||||
|             case 2: return static_cast<int>(npcStruct.mWillpower); | ||||
|             case 3: return static_cast<int>(npcStruct.mAgility); | ||||
|             case 4: return static_cast<int>(npcStruct.mSpeed); | ||||
|             case 5: return static_cast<int>(npcStruct.mEndurance); | ||||
|             case 6: return static_cast<int>(npcStruct.mPersonality); | ||||
|             case 7: return static_cast<int>(npcStruct.mLuck); | ||||
|             default: return QVariant(); // throw an exception here?
 | ||||
|         } | ||||
|     else | ||||
|         return QVariant(); // throw an exception here?
 | ||||
| } | ||||
| 
 | ||||
| void CSMWorld::NpcAttributesRefIdAdapter::setNestedData (const RefIdColumn *column, | ||||
|         RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const | ||||
| { | ||||
|     Record<ESM::NPC>& record = | ||||
|         static_cast<Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Npc))); | ||||
|     ESM::NPC npc = record.get(); | ||||
|     ESM::NPC::NPDTstruct52& npcStruct = npc.mNpdt52; | ||||
| 
 | ||||
|     if (subColIndex == 1) | ||||
|         switch(subRowIndex) | ||||
|         { | ||||
|             case 0: npcStruct.mStrength = static_cast<unsigned char>(value.toInt()); break; | ||||
|             case 1: npcStruct.mIntelligence = static_cast<unsigned char>(value.toInt()); break; | ||||
|             case 2: npcStruct.mWillpower = static_cast<unsigned char>(value.toInt()); break; | ||||
|             case 3: npcStruct.mAgility = static_cast<unsigned char>(value.toInt()); break; | ||||
|             case 4: npcStruct.mSpeed = static_cast<unsigned char>(value.toInt()); break; | ||||
|             case 5: npcStruct.mEndurance = static_cast<unsigned char>(value.toInt()); break; | ||||
|             case 6: npcStruct.mPersonality = static_cast<unsigned char>(value.toInt()); break; | ||||
|             case 7: npcStruct.mLuck = static_cast<unsigned char>(value.toInt()); break; | ||||
|             default: return; // throw an exception here?
 | ||||
|         } | ||||
|     else | ||||
|         return; // throw an exception here?
 | ||||
| 
 | ||||
|     record.setModified (npc); | ||||
| } | ||||
| 
 | ||||
| int CSMWorld::NpcAttributesRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const | ||||
| { | ||||
|     return 2; | ||||
| } | ||||
| 
 | ||||
| int CSMWorld::NpcAttributesRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const | ||||
| { | ||||
|     // There are 8 attributes
 | ||||
|     return 8; | ||||
| } | ||||
| 
 | ||||
| CSMWorld::NpcSkillsRefIdAdapter::NpcSkillsRefIdAdapter () | ||||
| {} | ||||
| 
 | ||||
| void CSMWorld::NpcSkillsRefIdAdapter::addNestedRow (const RefIdColumn *column, | ||||
|         RefIdData& data, int index, int position) const | ||||
| { | ||||
|     // Do nothing, this table cannot be changed by the user
 | ||||
| } | ||||
| 
 | ||||
| void CSMWorld::NpcSkillsRefIdAdapter::removeNestedRow (const RefIdColumn *column, | ||||
|         RefIdData& data, int index, int rowToRemove) const | ||||
| { | ||||
|     // Do nothing, this table cannot be changed by the user
 | ||||
| } | ||||
| 
 | ||||
| void CSMWorld::NpcSkillsRefIdAdapter::setNestedTable (const RefIdColumn* column, | ||||
|         RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const | ||||
| { | ||||
|     Record<ESM::NPC>& record = | ||||
|         static_cast<Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); | ||||
|     ESM::NPC npc = record.get(); | ||||
| 
 | ||||
|     // store the whole struct
 | ||||
|     npc.mNpdt52 = | ||||
|         static_cast<const NestedTableWrapper<std::vector<typename ESM::NPC::NPDTstruct52> > &>(nestedTable).mNestedTable.at(0); | ||||
| 
 | ||||
|     record.setModified (npc); | ||||
| } | ||||
| 
 | ||||
| CSMWorld::NestedTableWrapperBase* CSMWorld::NpcSkillsRefIdAdapter::nestedTable (const RefIdColumn* column, | ||||
|         const RefIdData& data, int index) const | ||||
| { | ||||
|     const Record<ESM::NPC>& record = | ||||
|         static_cast<const Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); | ||||
| 
 | ||||
|     // return the whole struct
 | ||||
|     std::vector<typename ESM::NPC::NPDTstruct52> wrap; | ||||
|     wrap.push_back(record.get().mNpdt52); | ||||
|     // deleted by dtor of NestedTableStoring
 | ||||
|     return new NestedTableWrapper<std::vector<typename ESM::NPC::NPDTstruct52> >(wrap); | ||||
| } | ||||
| 
 | ||||
| QVariant CSMWorld::NpcSkillsRefIdAdapter::getNestedData (const RefIdColumn *column, | ||||
|         const RefIdData& data, int index, int subRowIndex, int subColIndex) const | ||||
| { | ||||
|     const Record<ESM::NPC>& record = | ||||
|         static_cast<const Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); | ||||
| 
 | ||||
|     const ESM::NPC::NPDTstruct52& npcStruct = record.get().mNpdt52; | ||||
| 
 | ||||
|     if (subRowIndex < 0 || subRowIndex >= ESM::Skill::Length) | ||||
|         std::cout << "getNestedDatat index" << std::endl; | ||||
|         //throw std::runtime_error ("index out of range");
 | ||||
| 
 | ||||
|     if (subColIndex == 0) | ||||
|         return QString(ESM::Skill::sSkillNames[subRowIndex].c_str()); | ||||
|     else if (subColIndex == 1) | ||||
|         return static_cast<int>(npcStruct.mSkills[subRowIndex]); | ||||
|     else | ||||
|         return QVariant(); // throw an exception here?
 | ||||
| } | ||||
| 
 | ||||
| void CSMWorld::NpcSkillsRefIdAdapter::setNestedData (const RefIdColumn *column, | ||||
|         RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const | ||||
| { | ||||
|     Record<ESM::NPC>& record = | ||||
|         static_cast<Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Npc))); | ||||
|     ESM::NPC npc = record.get(); | ||||
|     ESM::NPC::NPDTstruct52& npcStruct = npc.mNpdt52; | ||||
| 
 | ||||
|     if (subRowIndex < 0 || subRowIndex >= ESM::Skill::Length) | ||||
|         std::cout << "setNestedDatat index" << std::endl; | ||||
|         //throw std::runtime_error ("index out of range");
 | ||||
| 
 | ||||
|     if (subColIndex == 1) | ||||
|         npcStruct.mSkills[subRowIndex] = static_cast<unsigned char>(value.toInt()); | ||||
|     else | ||||
|         return; // throw an exception here?
 | ||||
| 
 | ||||
|     record.setModified (npc); | ||||
| } | ||||
| 
 | ||||
| int CSMWorld::NpcSkillsRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const | ||||
| { | ||||
|     return 2; | ||||
| } | ||||
| 
 | ||||
| int CSMWorld::NpcSkillsRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const | ||||
| { | ||||
|     // There are 27 skills
 | ||||
|     return ESM::Skill::Length; | ||||
| } | ||||
| 
 | ||||
| CSMWorld::NpcMiscRefIdAdapter::NpcMiscRefIdAdapter () | ||||
| {} | ||||
| 
 | ||||
| CSMWorld::NpcMiscRefIdAdapter::~NpcMiscRefIdAdapter() | ||||
| {} | ||||
| 
 | ||||
| void CSMWorld::NpcMiscRefIdAdapter::addNestedRow (const RefIdColumn *column, | ||||
|         RefIdData& data, int index, int position) const | ||||
| { | ||||
|     throw std::logic_error ("cannot add a row to a fixed table"); | ||||
| } | ||||
| 
 | ||||
| void CSMWorld::NpcMiscRefIdAdapter::removeNestedRow (const RefIdColumn *column, | ||||
|         RefIdData& data, int index, int rowToRemove) const | ||||
| { | ||||
|     throw std::logic_error ("cannot remove a row to a fixed table"); | ||||
| } | ||||
| 
 | ||||
| void CSMWorld::NpcMiscRefIdAdapter::setNestedTable (const RefIdColumn* column, | ||||
|         RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const | ||||
| { | ||||
|     throw std::logic_error ("table operation not supported"); | ||||
| } | ||||
| 
 | ||||
| CSMWorld::NestedTableWrapperBase* CSMWorld::NpcMiscRefIdAdapter::nestedTable (const RefIdColumn* column, | ||||
|         const RefIdData& data, int index) const | ||||
| { | ||||
|     throw std::logic_error ("table operation not supported"); | ||||
| } | ||||
| 
 | ||||
| QVariant CSMWorld::NpcMiscRefIdAdapter::getNestedData (const RefIdColumn *column, | ||||
|         const RefIdData& data, int index, int subRowIndex, int subColIndex) const | ||||
| { | ||||
|     const Record<ESM::NPC>& record = | ||||
|         static_cast<const Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); | ||||
| 
 | ||||
|     bool autoCalc = (record.get().mFlags & ESM::NPC::Autocalc) != 0; | ||||
| 
 | ||||
|     if (autoCalc) | ||||
|         switch (subColIndex) | ||||
|         { | ||||
|             case 0: return static_cast<int>(record.get().mNpdt12.mLevel); | ||||
|             case 1: return QVariant(); | ||||
|             case 2: return QVariant(); | ||||
|             case 3: return QVariant(); | ||||
|             case 4: return QVariant(); | ||||
|             case 5: return static_cast<int>(record.get().mNpdt12.mDisposition); | ||||
|             case 6: return static_cast<int>(record.get().mNpdt12.mReputation); | ||||
|             case 7: return static_cast<int>(record.get().mNpdt12.mRank); | ||||
|             case 8: return record.get().mNpdt12.mGold; | ||||
|             case 9: return record.get().mPersistent == true; | ||||
|             default: return QVariant(); // throw an exception here?
 | ||||
|         } | ||||
|     else | ||||
|         switch (subColIndex) | ||||
|         { | ||||
|             case 0: return static_cast<int>(record.get().mNpdt52.mLevel); | ||||
|             case 1: return static_cast<int>(record.get().mNpdt52.mFactionID); | ||||
|             case 2: return static_cast<int>(record.get().mNpdt52.mHealth); | ||||
|             case 3: return static_cast<int>(record.get().mNpdt52.mMana); | ||||
|             case 4: return static_cast<int>(record.get().mNpdt52.mFatigue); | ||||
|             case 5: return static_cast<int>(record.get().mNpdt52.mDisposition); | ||||
|             case 6: return static_cast<int>(record.get().mNpdt52.mReputation); | ||||
|             case 7: return static_cast<int>(record.get().mNpdt52.mRank); | ||||
|             case 8: return record.get().mNpdt52.mGold; | ||||
|             case 9: return record.get().mPersistent == true; | ||||
|             default: return QVariant(); // throw an exception here?
 | ||||
|         } | ||||
| } | ||||
| 
 | ||||
| void CSMWorld::NpcMiscRefIdAdapter::setNestedData (const RefIdColumn *column, | ||||
|         RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const | ||||
| { | ||||
|     Record<ESM::NPC>& record = | ||||
|         static_cast<Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Npc))); | ||||
|     ESM::NPC npc = record.get(); | ||||
| 
 | ||||
|     bool autoCalc = (record.get().mFlags & ESM::NPC::Autocalc) != 0; | ||||
| 
 | ||||
|     if (autoCalc) | ||||
|         switch(subColIndex) | ||||
|         { | ||||
|             case 0: npc.mNpdt12.mLevel = static_cast<short>(value.toInt()); break; | ||||
|             case 1: return; | ||||
|             case 2: return; | ||||
|             case 3: return; | ||||
|             case 4: return; | ||||
|             case 5: npc.mNpdt12.mDisposition = static_cast<signed char>(value.toInt()); break; | ||||
|             case 6: npc.mNpdt12.mReputation = static_cast<signed char>(value.toInt()); break; | ||||
|             case 7: npc.mNpdt12.mRank = static_cast<signed char>(value.toInt()); break; | ||||
|             case 8: npc.mNpdt12.mGold = value.toInt(); break; | ||||
|             case 9: npc.mPersistent = value.toBool(); break; | ||||
|             default: return; // throw an exception here?
 | ||||
|         } | ||||
|     else | ||||
|         switch(subColIndex) | ||||
|         { | ||||
|             case 0: npc.mNpdt52.mLevel = static_cast<short>(value.toInt()); break; | ||||
|             case 1: npc.mNpdt52.mFactionID = static_cast<char>(value.toInt()); break; | ||||
|             case 2: npc.mNpdt52.mHealth = static_cast<unsigned short>(value.toInt()); break; | ||||
|             case 3: npc.mNpdt52.mMana = static_cast<unsigned short>(value.toInt()); break; | ||||
|             case 4: npc.mNpdt52.mFatigue = static_cast<unsigned short>(value.toInt()); break; | ||||
|             case 5: npc.mNpdt52.mDisposition = static_cast<signed char>(value.toInt()); break; | ||||
|             case 6: npc.mNpdt52.mReputation = static_cast<signed char>(value.toInt()); break; | ||||
|             case 7: npc.mNpdt52.mRank = static_cast<signed char>(value.toInt()); break; | ||||
|             case 8: npc.mNpdt52.mGold = value.toInt(); break; | ||||
|             case 9: npc.mPersistent = value.toBool(); break; | ||||
|             default: return; // throw an exception here?
 | ||||
|         } | ||||
| 
 | ||||
|     record.setModified (npc); | ||||
| } | ||||
| 
 | ||||
| int CSMWorld::NpcMiscRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const | ||||
| { | ||||
|     return 10; // Level, FactionID, Health, Mana, Fatigue, Disposition, Reputation, Rank, Gold, Persist
 | ||||
| } | ||||
| 
 | ||||
| int CSMWorld::NpcMiscRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const | ||||
| { | ||||
|     return 1; // fixed at size 1
 | ||||
| } | ||||
| 
 | ||||
| CSMWorld::WeaponColumns::WeaponColumns (const EnchantableColumns& columns) | ||||
| : EnchantableColumns (columns) {} | ||||
| 
 | ||||
|  |  | |||
|  | @ -792,6 +792,9 @@ namespace CSMWorld | |||
|         const RefIdColumn *mFaction; | ||||
|         const RefIdColumn *mHair; | ||||
|         const RefIdColumn *mHead; | ||||
|         const RefIdColumn *mAttributes; // depends on npc type
 | ||||
|         const RefIdColumn *mSkills;     // depends on npc type
 | ||||
|         const RefIdColumn *mMisc;       // may depend on npc type, e.g. FactionID
 | ||||
| 
 | ||||
|         NpcColumns (const ActorColumns& actorColumns); | ||||
|     }; | ||||
|  | @ -842,8 +845,100 @@ namespace CSMWorld | |||
|             ///< If the data type does not match an exception is thrown.
 | ||||
|     }; | ||||
| 
 | ||||
| 
 | ||||
|     class NestedRefIdAdapterBase; | ||||
| 
 | ||||
|     class NpcAttributesRefIdAdapter : public NestedRefIdAdapterBase | ||||
|     { | ||||
|     public: | ||||
| 
 | ||||
|         NpcAttributesRefIdAdapter (); | ||||
| 
 | ||||
|         virtual void addNestedRow (const RefIdColumn *column, | ||||
|                 RefIdData& data, int index, int position) const; | ||||
| 
 | ||||
|         virtual void removeNestedRow (const RefIdColumn *column, | ||||
|                 RefIdData& data, int index, int rowToRemove) const; | ||||
| 
 | ||||
|         virtual void setNestedTable (const RefIdColumn* column, | ||||
|                 RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const; | ||||
| 
 | ||||
|         virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, | ||||
|                 const RefIdData& data, int index) const; | ||||
| 
 | ||||
|         virtual QVariant getNestedData (const RefIdColumn *column, | ||||
|                 const RefIdData& data, int index, int subRowIndex, int subColIndex) const; | ||||
| 
 | ||||
|         virtual void setNestedData (const RefIdColumn *column, | ||||
|                 RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const; | ||||
| 
 | ||||
|         virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; | ||||
| 
 | ||||
|         virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; | ||||
|     }; | ||||
| 
 | ||||
|     class NpcSkillsRefIdAdapter : public NestedRefIdAdapterBase | ||||
|     { | ||||
|     public: | ||||
| 
 | ||||
|         NpcSkillsRefIdAdapter (); | ||||
| 
 | ||||
|         virtual void addNestedRow (const RefIdColumn *column, | ||||
|                 RefIdData& data, int index, int position) const; | ||||
| 
 | ||||
|         virtual void removeNestedRow (const RefIdColumn *column, | ||||
|                 RefIdData& data, int index, int rowToRemove) const; | ||||
| 
 | ||||
|         virtual void setNestedTable (const RefIdColumn* column, | ||||
|                 RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const; | ||||
| 
 | ||||
|         virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, | ||||
|                 const RefIdData& data, int index) const; | ||||
| 
 | ||||
|         virtual QVariant getNestedData (const RefIdColumn *column, | ||||
|                 const RefIdData& data, int index, int subRowIndex, int subColIndex) const; | ||||
| 
 | ||||
|         virtual void setNestedData (const RefIdColumn *column, | ||||
|                 RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const; | ||||
| 
 | ||||
|         virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; | ||||
| 
 | ||||
|         virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; | ||||
|     }; | ||||
| 
 | ||||
|     class NpcMiscRefIdAdapter : public NestedRefIdAdapterBase | ||||
|     { | ||||
|         NpcMiscRefIdAdapter (const NpcMiscRefIdAdapter&); | ||||
|         NpcMiscRefIdAdapter& operator= (const NpcMiscRefIdAdapter&); | ||||
| 
 | ||||
|     public: | ||||
| 
 | ||||
|         NpcMiscRefIdAdapter (); | ||||
|         virtual ~NpcMiscRefIdAdapter(); | ||||
| 
 | ||||
|         virtual void addNestedRow (const RefIdColumn *column, | ||||
|                 RefIdData& data, int index, int position) const; | ||||
| 
 | ||||
|         virtual void removeNestedRow (const RefIdColumn *column, | ||||
|                 RefIdData& data, int index, int rowToRemove) const; | ||||
| 
 | ||||
|         virtual void setNestedTable (const RefIdColumn* column, | ||||
|                 RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const; | ||||
| 
 | ||||
|         virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, | ||||
|                 const RefIdData& data, int index) const; | ||||
| 
 | ||||
|         virtual QVariant getNestedData (const RefIdColumn *column, | ||||
|                 const RefIdData& data, int index, int subRowIndex, int subColIndex) const; | ||||
| 
 | ||||
|         virtual void setNestedData (const RefIdColumn *column, | ||||
|                 RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const; | ||||
| 
 | ||||
|         virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; | ||||
| 
 | ||||
|         virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; | ||||
|     }; | ||||
| 
 | ||||
|     template<typename ESXRecordT> | ||||
|     class EffectsListAdapter; | ||||
| 
 | ||||
|  |  | |||
|  | @ -427,6 +427,62 @@ CSMWorld::RefIdCollection::RefIdCollection() | |||
| 
 | ||||
|     npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal)); | ||||
| 
 | ||||
|     // Need a way to add a table of stats and values (rather than adding a long list of
 | ||||
|     // entries in the dialogue subview) E.g. attributes+stats(health, mana, fatigue), skills
 | ||||
|     // These needs to be driven from the autocalculated setting.
 | ||||
| 
 | ||||
|     // Nested table
 | ||||
|     mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcAttributes, | ||||
|             ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); | ||||
|     npcColumns.mAttributes = &mColumns.back(); | ||||
|     std::map<UniversalId::Type, NestedRefIdAdapterBase*> attrMap; | ||||
|     attrMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcAttributesRefIdAdapter())); | ||||
|     mNestedAdapters.push_back (std::make_pair(&mColumns.back(), attrMap)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_NpcAttributes, CSMWorld::ColumnBase::Display_String, false, false)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_UChar, CSMWorld::ColumnBase::Display_Integer)); | ||||
| 
 | ||||
|     // Nested table
 | ||||
|     mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcSkills, | ||||
|             ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); | ||||
|     npcColumns.mSkills = &mColumns.back(); | ||||
|     std::map<UniversalId::Type, NestedRefIdAdapterBase*> skillsMap; | ||||
|     skillsMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcSkillsRefIdAdapter())); | ||||
|     mNestedAdapters.push_back (std::make_pair(&mColumns.back(), skillsMap)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_NpcSkills, CSMWorld::ColumnBase::Display_String, false, false)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_UChar, CSMWorld::ColumnBase::Display_Integer)); | ||||
| 
 | ||||
|     // Nested list
 | ||||
|     mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcMisc, | ||||
|         ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List)); | ||||
|     npcColumns.mMisc = &mColumns.back(); | ||||
|     std::map<UniversalId::Type, NestedRefIdAdapterBase*> miscMap; | ||||
|     miscMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcMiscRefIdAdapter())); | ||||
|     mNestedAdapters.push_back (std::make_pair(&mColumns.back(), miscMap)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_NpcLevel, CSMWorld::ColumnBase::Display_Integer)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_NpcFactionID, CSMWorld::ColumnBase::Display_Integer)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_NpcHealth, CSMWorld::ColumnBase::Display_Integer)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_NpcMana, CSMWorld::ColumnBase::Display_Integer)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_NpcFatigue, CSMWorld::ColumnBase::Display_Integer)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_NpcDisposition, CSMWorld::ColumnBase::Display_Integer)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_NpcReputation, CSMWorld::ColumnBase::Display_Integer)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_NpcRank, CSMWorld::ColumnBase::Display_Integer)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_NpcGold, CSMWorld::ColumnBase::Display_Integer)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_NpcPersistence, CSMWorld::ColumnBase::Display_Boolean)); | ||||
| 
 | ||||
|     WeaponColumns weaponColumns (enchantableColumns); | ||||
| 
 | ||||
|     mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType)); | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
| #include <QPushButton> | ||||
| #include <QToolButton> | ||||
| #include <QHeaderView> | ||||
| #include <QScrollBar> | ||||
| 
 | ||||
| #include "../../model/world/nestedtableproxymodel.hpp" | ||||
| #include "../../model/world/columnbase.hpp" | ||||
|  | @ -511,7 +512,7 @@ void CSVWorld::EditWidget::remake(int row) | |||
|                 mNestedTableMapper->setModel(mNestedModels.back()); | ||||
|                 // FIXME: lack MIME support?
 | ||||
|                 mNestedTableDispatcher = | ||||
|                         new DialogueDelegateDispatcher (this, mTable, mCommandDispatcher, mDocument, mNestedModels.back()); | ||||
|                         new DialogueDelegateDispatcher (0/*this*/, mTable, mCommandDispatcher, mDocument, mNestedModels.back()); | ||||
|                 mNestedTableMapper->setItemDelegate(mNestedTableDispatcher); | ||||
| 
 | ||||
|                 int columnCount = | ||||
|  | @ -763,6 +764,9 @@ void CSVWorld::DialogueSubView::dataChanged (const QModelIndex & index) | |||
|         CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); | ||||
| 
 | ||||
|         mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || mLocked); | ||||
|         int y = mEditWidget->verticalScrollBar()->value(); | ||||
|         mEditWidget->remake (index.row()); | ||||
|         mEditWidget->verticalScrollBar()->setValue(y); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue