From e97fd35ae6d9d50e65866182dcd84cee91452570 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 30 Jun 2014 20:40:34 +0200 Subject: [PATCH 1/6] added enchantments table --- apps/opencs/model/doc/saving.cpp | 3 +++ apps/opencs/model/world/data.cpp | 22 ++++++++++++++++++++++ apps/opencs/model/world/data.hpp | 6 ++++++ apps/opencs/model/world/universalid.cpp | 3 ++- apps/opencs/model/world/universalid.hpp | 6 ++++-- apps/opencs/view/doc/view.cpp | 9 +++++++++ apps/opencs/view/doc/view.hpp | 2 ++ apps/opencs/view/world/subviews.cpp | 1 + components/esm/loadench.cpp | 9 +++++++++ components/esm/loadench.hpp | 3 +++ 10 files changed, 61 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index 45b53f4fe8..ef753bb4b6 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -59,6 +59,9 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje appendStage (new WriteCollectionStage > (mDocument.getData().getSpells(), mState)); + appendStage (new WriteCollectionStage > + (mDocument.getData().getEnchantments(), mState)); + appendStage (new WriteDialogueCollectionStage (mDocument, mState, false)); appendStage (new WriteDialogueCollectionStage (mDocument, mState, true)); diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 0319d71acc..35b658ada7 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -198,6 +198,13 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding) mCells.addColumn (new FlagColumn (Columns::ColumnId_InteriorSky, ESM::Cell::QuasiEx)); mCells.addColumn (new RegionColumn); + mEnchantments.addColumn (new StringIdColumn); + mEnchantments.addColumn (new RecordStateColumn); + mEnchantments.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Enchantment)); + + mEnchantments.addColumn (new CostColumn); + + mRefs.addColumn (new StringIdColumn (true)); mRefs.addColumn (new RecordStateColumn); mRefs.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Reference)); @@ -252,6 +259,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding) addModel (new IdTable (&mTopicInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_TopicInfo); addModel (new IdTable (&mJournalInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_JournalInfo); addModel (new IdTable (&mCells, IdTable::Feature_ViewId), UniversalId::Type_Cell); + addModel (new IdTable (&mEnchantments), UniversalId::Type_Enchantment); addModel (new IdTable (&mReferenceables, IdTable::Feature_Preview), UniversalId::Type_Referenceable); addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference); @@ -457,6 +465,16 @@ CSMWorld::IdCollection& CSMWorld::Data::getFilters() return mFilters; } +const CSMWorld::IdCollection& CSMWorld::Data::getEnchantments() const +{ + return mEnchantments; +} + +CSMWorld::IdCollection& CSMWorld::Data::getEnchantments() +{ + return mEnchantments; +} + QAbstractItemModel *CSMWorld::Data::getTableModel (const CSMWorld::UniversalId& id) { std::map::iterator iter = mModelIndex.find (id.getType()); @@ -534,6 +552,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages) case ESM::REC_REGN: mRegions.load (*mReader, mBase); break; case ESM::REC_BSGN: mBirthsigns.load (*mReader, mBase); break; case ESM::REC_SPEL: mSpells.load (*mReader, mBase); break; + case ESM::REC_ENCH: mEnchantments.load (*mReader, mBase); break; case ESM::REC_CELL: { @@ -668,6 +687,7 @@ bool CSMWorld::Data::hasId (const std::string& id) const getTopics().searchId (id)!=-1 || getJournals().searchId (id)!=-1 || getCells().searchId (id)!=-1 || + getEnchantments().searchId (id)!=-1 || getReferenceables().searchId (id)!=-1; } @@ -686,6 +706,7 @@ int CSMWorld::Data::count (RecordBase::State state) const count (state, mBirthsigns) + count (state, mSpells) + count (state, mCells) + + count (state, mEnchantments) + count (state, mReferenceables); } @@ -726,6 +747,7 @@ std::vector CSMWorld::Data::getIds (bool listDeleted) const appendIds (ids, mTopics, listDeleted); appendIds (ids, mJournals, listDeleted); appendIds (ids, mCells, listDeleted); + appendIds (ids, mEnchantments, listDeleted); appendIds (ids, mReferenceables, listDeleted); std::sort (ids.begin(), ids.end()); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index edca9fdbcf..758354450d 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -63,6 +64,7 @@ namespace CSMWorld IdCollection mSpells; IdCollection mTopics; IdCollection mJournals; + IdCollection mEnchantments; InfoCollection mTopicInfos; InfoCollection mJournalInfos; IdCollection mCells; @@ -174,6 +176,10 @@ namespace CSMWorld IdCollection& getFilters(); + const IdCollection& getEnchantments() const; + + IdCollection& getEnchantments(); + QAbstractItemModel *getTableModel (const UniversalId& id); ///< If no table model is available for \a id, an exception is thrown. /// diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index 88e649ace4..79273a8311 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -35,6 +35,7 @@ namespace { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_TopicInfos, "Topic Infos", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_JournalInfos, "Journal Infos", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Cells, "Cells", 0 }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Enchantments, "Enchantments", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Referenceables, "Referenceables", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_References, @@ -92,8 +93,8 @@ namespace { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Reference, "Reference", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" }, { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 }, - { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Preview, "Preview", 0 }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Enchantment, "Enchantment", 0 }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker }; diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index 3bef71c75f..f92ad0bcb7 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -100,10 +100,12 @@ namespace CSMWorld Type_JournalInfo, Type_Scene, Type_Preview, - Type_LoadErrorLog + Type_LoadErrorLog, + Type_Enchantments, + Type_Enchantment }; - enum { NumberOfTypes = Type_LoadErrorLog+1 }; + enum { NumberOfTypes = Type_Enchantment+1 }; private: diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index e71b8435ab..a356721f60 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -146,6 +146,10 @@ void CSVDoc::View::setupMechanicsMenu() QAction *spells = new QAction (tr ("Spells"), this); connect (spells, SIGNAL (triggered()), this, SLOT (addSpellsSubView())); mechanics->addAction (spells); + + QAction *enchantments = new QAction (tr ("Enchantments"), this); + connect (enchantments, SIGNAL (triggered()), this, SLOT (addEnchantmentsSubView())); + mechanics->addAction (enchantments); } void CSVDoc::View::setupCharacterMenu() @@ -469,6 +473,11 @@ void CSVDoc::View::addJournalInfosSubView() addSubView (CSMWorld::UniversalId::Type_JournalInfos); } +void CSVDoc::View::addEnchantmentsSubView() +{ + addSubView (CSMWorld::UniversalId::Type_Enchantments); +} + void CSVDoc::View::abortOperation (int type) { mDocument->abortOperation (type); diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 686c001dc1..1ba73c56de 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -178,6 +178,8 @@ namespace CSVDoc void addJournalInfosSubView(); + void addEnchantmentsSubView(); + void toggleShowStatusBar (bool show); void loadErrorLog(); diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 022d5d02e4..8d62466968 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -39,6 +39,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_Regions, CSMWorld::UniversalId::Type_Birthsigns, CSMWorld::UniversalId::Type_Spells, + CSMWorld::UniversalId::Type_Enchantments, CSMWorld::UniversalId::Type_None // end marker }; diff --git a/components/esm/loadench.cpp b/components/esm/loadench.cpp index a1e885f23b..2438038337 100644 --- a/components/esm/loadench.cpp +++ b/components/esm/loadench.cpp @@ -20,4 +20,13 @@ void Enchantment::save(ESMWriter &esm) const mEffects.save(esm); } + void Enchantment::blank() + { + mData.mType = 0; + mData.mCost = 0; + mData.mCharge = 0; + mData.mAutocalc = 0; + + mEffects.mList.clear(); + } } diff --git a/components/esm/loadench.hpp b/components/esm/loadench.hpp index f6ba8c6ab3..3b7746812a 100644 --- a/components/esm/loadench.hpp +++ b/components/esm/loadench.hpp @@ -42,6 +42,9 @@ struct Enchantment void load(ESMReader &esm); void save(ESMWriter &esm) const; + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif From ab8bee4d1a8110abef85babeaa6637431f948426 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 1 Jul 2014 09:42:56 +0200 Subject: [PATCH 2/6] added enchantment type column to enchantment table --- apps/opencs/model/world/columnbase.hpp | 1 + apps/opencs/model/world/columnimp.hpp | 27 ++++++++++++++++++++++++++ apps/opencs/model/world/columns.cpp | 7 +++++++ apps/opencs/model/world/columns.hpp | 1 + apps/opencs/model/world/data.cpp | 1 + apps/opencs/view/doc/viewmanager.cpp | 1 + 6 files changed, 38 insertions(+) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index fe310d0aa4..3de610320c 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -89,6 +89,7 @@ namespace CSMWorld Display_RefRecordType, Display_DialogueType, Display_QuestStatusType, + Display_EnchantmentType, Display_Gender }; diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 6976b454d9..8e73cc2447 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -1682,6 +1682,33 @@ namespace CSMWorld return true; } }; + + template + struct EnchantmentTypeColumn : public Column + { + EnchantmentTypeColumn() + : Column (Columns::ColumnId_EnchantmentType, ColumnBase::Display_EnchantmentType) + {} + + virtual QVariant get (const Record& record) const + { + return static_cast (record.get().mData.mType); + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + record2.mData.mType = data.toInt(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; } #endif diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 7a2e93edfa..0292b2c5ec 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -177,6 +177,7 @@ namespace CSMWorld { ColumnId_CombatState, "Combat" }, { ColumnId_MagicState, "Magic" }, { ColumnId_StealthState, "Stealth" }, + { ColumnId_EnchantmentType, "Enchantment Type" }, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, @@ -302,6 +303,11 @@ namespace "Male", "Female", 0 }; + static const char *sEnchantmentTypes[] = + { + "Cast Once", "When Strikes", "When Used", "Constant Effect", 0 + }; + const char **getEnumNames (CSMWorld::Columns::ColumnId column) { switch (column) @@ -319,6 +325,7 @@ namespace case CSMWorld::Columns::ColumnId_DialogueType: return sDialogueTypeEnums; case CSMWorld::Columns::ColumnId_QuestStatusType: return sQuestStatusTypes; case CSMWorld::Columns::ColumnId_Gender: return sGenderEnums; + case CSMWorld::Columns::ColumnId_EnchantmentType: return sEnchantmentTypes; default: return 0; } diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index db31113e1d..0b65b2932c 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -170,6 +170,7 @@ namespace CSMWorld ColumnId_CombatState = 157, ColumnId_MagicState = 158, ColumnId_StealthState = 159, + ColumnId_EnchantmentType = 160, // 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/data.cpp b/apps/opencs/model/world/data.cpp index 35b658ada7..bc2d5287e8 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -201,6 +201,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding) mEnchantments.addColumn (new StringIdColumn); mEnchantments.addColumn (new RecordStateColumn); mEnchantments.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Enchantment)); + mEnchantments.addColumn (new EnchantmentTypeColumn); mEnchantments.addColumn (new CostColumn); diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index f4d6fc6cb5..14607b49ea 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -78,6 +78,7 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) { CSMWorld::ColumnBase::Display_WeaponType, CSMWorld::Columns::ColumnId_WeaponType, false }, { CSMWorld::ColumnBase::Display_DialogueType, CSMWorld::Columns::ColumnId_DialogueType, false }, { CSMWorld::ColumnBase::Display_QuestStatusType, CSMWorld::Columns::ColumnId_QuestStatusType, false }, + { CSMWorld::ColumnBase::Display_EnchantmentType, CSMWorld::Columns::ColumnId_EnchantmentType, false }, { CSMWorld::ColumnBase::Display_Gender, CSMWorld::Columns::ColumnId_Gender, true } }; From 5649552f1805a130c9915549e9fa40e7e7e4397b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 1 Jul 2014 09:50:43 +0200 Subject: [PATCH 3/6] added other missing columns for enchantment table; fixed dialogue subviews for enchantment records --- apps/opencs/model/world/columnimp.hpp | 49 +++++++++++++++++++++++++++ apps/opencs/model/world/columns.cpp | 1 + apps/opencs/model/world/data.cpp | 4 +-- apps/opencs/view/world/subviews.cpp | 1 + 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 8e73cc2447..d31d7cf294 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -1709,6 +1709,55 @@ namespace CSMWorld return true; } }; + + template + struct ChargesColumn2 : public Column + { + ChargesColumn2() : Column (Columns::ColumnId_Charges, ColumnBase::Display_Integer) {} + + virtual QVariant get (const Record& record) const + { + return record.get().mData.mCharge; + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + record2.mData.mCharge = data.toInt(); + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; + + template + struct AutoCalcColumn : public Column + { + AutoCalcColumn() : Column (Columns::ColumnId_AutoCalc, ColumnBase::Display_Boolean) + {} + + virtual QVariant get (const Record& record) const + { + return record.get().mData.mAutocalc!=0; + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + record2.mData.mAutocalc = data.toInt(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; } #endif diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 0292b2c5ec..4f88e7b1b9 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -178,6 +178,7 @@ namespace CSMWorld { ColumnId_MagicState, "Magic" }, { ColumnId_StealthState, "Stealth" }, { ColumnId_EnchantmentType, "Enchantment Type" }, + { ColumnId_AutoCalc, "Auto Calc" }, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index bc2d5287e8..12de19a828 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -202,9 +202,9 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding) mEnchantments.addColumn (new RecordStateColumn); mEnchantments.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Enchantment)); mEnchantments.addColumn (new EnchantmentTypeColumn); - mEnchantments.addColumn (new CostColumn); - + mEnchantments.addColumn (new ChargesColumn2); + mEnchantments.addColumn (new AutoCalcColumn); mRefs.addColumn (new StringIdColumn (true)); mRefs.addColumn (new RecordStateColumn); diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 8d62466968..c1b5393d30 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -93,6 +93,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_Filter, CSMWorld::UniversalId::Type_Sound, CSMWorld::UniversalId::Type_Faction, + CSMWorld::UniversalId::Type_Enchantment, CSMWorld::UniversalId::Type_None // end marker }; From d96ed38d498a7b03be4d6725ed23bf52c4af3184 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 1 Jul 2014 12:37:22 +0200 Subject: [PATCH 4/6] added body part table --- apps/opencs/model/doc/saving.cpp | 3 ++ apps/opencs/model/world/columnimp.hpp | 67 +++++++++++++++++++++++-- apps/opencs/model/world/columns.cpp | 2 +- apps/opencs/model/world/columns.hpp | 1 + apps/opencs/model/world/data.cpp | 24 +++++++++ apps/opencs/model/world/data.hpp | 6 +++ apps/opencs/model/world/universalid.cpp | 2 + apps/opencs/model/world/universalid.hpp | 6 ++- apps/opencs/view/doc/view.cpp | 9 ++++ apps/opencs/view/doc/view.hpp | 2 + apps/opencs/view/world/subviews.cpp | 2 + components/esm/loadbody.cpp | 10 ++++ components/esm/loadbody.hpp | 3 ++ 13 files changed, 130 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index ef753bb4b6..95631eea9c 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -62,6 +62,9 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje appendStage (new WriteCollectionStage > (mDocument.getData().getEnchantments(), mState)); + appendStage (new WriteCollectionStage > + (mDocument.getData().getBodyParts(), mState)); + appendStage (new WriteDialogueCollectionStage (mDocument, mState, false)); appendStage (new WriteDialogueCollectionStage (mDocument, mState, true)); diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index d31d7cf294..5844e97a7b 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -463,14 +463,21 @@ namespace CSMWorld struct FlagColumn : public Column { int mMask; + bool mInverted; - FlagColumn (int columnId, int mask) - : Column (columnId, ColumnBase::Display_Boolean), mMask (mask) + FlagColumn (int columnId, int mask, bool inverted = false) + : Column (columnId, ColumnBase::Display_Boolean), mMask (mask), + mInverted (inverted) {} virtual QVariant get (const Record& record) const { - return (record.get().mData.mFlags & mMask)!=0; + bool flag = (record.get().mData.mFlags & mMask)!=0; + + if (mInverted) + flag = !flag; + + return flag; } virtual void set (Record& record, const QVariant& data) @@ -479,7 +486,7 @@ namespace CSMWorld int flags = record2.mData.mFlags & ~mMask; - if (data.toInt()) + if ((data.toInt()!=0)!=mInverted) flags |= mMask; record2.mData.mFlags = flags; @@ -1758,6 +1765,58 @@ namespace CSMWorld return true; } }; + + template + struct ModelColumn : public Column + { + ModelColumn() : Column (Columns::ColumnId_Model, ColumnBase::Display_String) {} + + virtual QVariant get (const Record& record) const + { + return QString::fromUtf8 (record.get().mModel.c_str()); + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + record2.mModel = data.toString().toUtf8().constData(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; + + template + struct VampireColumn : public Column + { + VampireColumn() : Column (Columns::ColumnId_Vampire, ColumnBase::Display_Boolean) + {} + + virtual QVariant get (const Record& record) const + { + return record.get().mData.mVampire!=0; + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + record2.mData.mVampire = data.toInt(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; + } #endif diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 4f88e7b1b9..3d363aac4b 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -178,7 +178,7 @@ namespace CSMWorld { ColumnId_MagicState, "Magic" }, { ColumnId_StealthState, "Stealth" }, { ColumnId_EnchantmentType, "Enchantment Type" }, - { ColumnId_AutoCalc, "Auto Calc" }, + { ColumnId_Vampire, "Vampire" }, { 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 0b65b2932c..bb6c0e4531 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -171,6 +171,7 @@ namespace CSMWorld ColumnId_MagicState = 158, ColumnId_StealthState = 159, ColumnId_EnchantmentType = 160, + ColumnId_Vampire = 161, // 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/data.cpp b/apps/opencs/model/world/data.cpp index 12de19a828..0353d21426 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -206,6 +206,18 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding) mEnchantments.addColumn (new ChargesColumn2); mEnchantments.addColumn (new AutoCalcColumn); + mBodyParts.addColumn (new StringIdColumn); + mBodyParts.addColumn (new RecordStateColumn); + mBodyParts.addColumn (new FixedRecordTypeColumn (UniversalId::Type_BodyPart)); + + mBodyParts.addColumn (new VampireColumn); + mBodyParts.addColumn (new FlagColumn (Columns::ColumnId_Female, ESM::BodyPart::BPF_Female)); + mBodyParts.addColumn (new FlagColumn (Columns::ColumnId_Playable, ESM::BodyPart::BPF_NotPlayable, true)); + + mBodyParts.addColumn (new ModelColumn); + mBodyParts.addColumn (new RaceColumn); + + mRefs.addColumn (new StringIdColumn (true)); mRefs.addColumn (new RecordStateColumn); mRefs.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Reference)); @@ -261,6 +273,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding) addModel (new IdTable (&mJournalInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_JournalInfo); addModel (new IdTable (&mCells, IdTable::Feature_ViewId), UniversalId::Type_Cell); addModel (new IdTable (&mEnchantments), UniversalId::Type_Enchantment); + addModel (new IdTable (&mBodyParts), UniversalId::Type_BodyPart); addModel (new IdTable (&mReferenceables, IdTable::Feature_Preview), UniversalId::Type_Referenceable); addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference); @@ -476,6 +489,16 @@ CSMWorld::IdCollection& CSMWorld::Data::getEnchantments() return mEnchantments; } +const CSMWorld::IdCollection& CSMWorld::Data::getBodyParts() const +{ + return mBodyParts; +} + +CSMWorld::IdCollection& CSMWorld::Data::getBodyParts() +{ + return mBodyParts; +} + QAbstractItemModel *CSMWorld::Data::getTableModel (const CSMWorld::UniversalId& id) { std::map::iterator iter = mModelIndex.find (id.getType()); @@ -554,6 +577,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages) case ESM::REC_BSGN: mBirthsigns.load (*mReader, mBase); break; case ESM::REC_SPEL: mSpells.load (*mReader, mBase); break; case ESM::REC_ENCH: mEnchantments.load (*mReader, mBase); break; + case ESM::REC_BODY: mBodyParts.load (*mReader, mBase); break; case ESM::REC_CELL: { diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 758354450d..9bdb449e0a 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -65,6 +66,7 @@ namespace CSMWorld IdCollection mTopics; IdCollection mJournals; IdCollection mEnchantments; + IdCollection mBodyParts; InfoCollection mTopicInfos; InfoCollection mJournalInfos; IdCollection mCells; @@ -180,6 +182,10 @@ namespace CSMWorld IdCollection& getEnchantments(); + const IdCollection& getBodyParts() const; + + IdCollection& getBodyParts(); + QAbstractItemModel *getTableModel (const UniversalId& id); ///< If no table model is available for \a id, an exception is thrown. /// diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index 79273a8311..3a5f3f0439 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -36,6 +36,7 @@ namespace { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_JournalInfos, "Journal Infos", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Cells, "Cells", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Enchantments, "Enchantments", 0 }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_BodyParts, "Body Parts", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Referenceables, "Referenceables", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_References, @@ -95,6 +96,7 @@ namespace { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 }, { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Preview, "Preview", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Enchantment, "Enchantment", 0 }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_BodyPart, "Body Part", 0 }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker }; diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index f92ad0bcb7..c7514336f1 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -102,10 +102,12 @@ namespace CSMWorld Type_Preview, Type_LoadErrorLog, Type_Enchantments, - Type_Enchantment + Type_Enchantment, + Type_BodyParts, + Type_BodyPart }; - enum { NumberOfTypes = Type_Enchantment+1 }; + enum { NumberOfTypes = Type_BodyPart+1 }; private: diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index a356721f60..6a807f086a 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -191,6 +191,10 @@ void CSVDoc::View::setupCharacterMenu() QAction *journalInfos = new QAction (tr ("Journal Infos"), this); connect (journalInfos, SIGNAL (triggered()), this, SLOT (addJournalInfosSubView())); characters->addAction (journalInfos); + + QAction *bodyParts = new QAction (tr ("Body Parts"), this); + connect (bodyParts, SIGNAL (triggered()), this, SLOT (addBodyPartsSubView())); + characters->addAction (bodyParts); } void CSVDoc::View::setupAssetsMenu() @@ -478,6 +482,11 @@ void CSVDoc::View::addEnchantmentsSubView() addSubView (CSMWorld::UniversalId::Type_Enchantments); } +void CSVDoc::View::addBodyPartsSubView() +{ + addSubView (CSMWorld::UniversalId::Type_BodyParts); +} + void CSVDoc::View::abortOperation (int type) { mDocument->abortOperation (type); diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 1ba73c56de..a227997c21 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -180,6 +180,8 @@ namespace CSVDoc void addEnchantmentsSubView(); + void addBodyPartsSubView(); + void toggleShowStatusBar (bool show); void loadErrorLog(); diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index c1b5393d30..8c666c1fed 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -40,6 +40,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_Birthsigns, CSMWorld::UniversalId::Type_Spells, CSMWorld::UniversalId::Type_Enchantments, + CSMWorld::UniversalId::Type_BodyParts, CSMWorld::UniversalId::Type_None // end marker }; @@ -94,6 +95,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_Sound, CSMWorld::UniversalId::Type_Faction, CSMWorld::UniversalId::Type_Enchantment, + CSMWorld::UniversalId::Type_BodyPart, CSMWorld::UniversalId::Type_None // end marker }; diff --git a/components/esm/loadbody.cpp b/components/esm/loadbody.cpp index c45f8d252d..9a1164d041 100644 --- a/components/esm/loadbody.cpp +++ b/components/esm/loadbody.cpp @@ -22,4 +22,14 @@ void BodyPart::save(ESMWriter &esm) const esm.writeHNT("BYDT", mData, 4); } + void BodyPart::blank() + { + mData.mPart = 0; + mData.mVampire = 0; + mData.mFlags = 0; + mData.mType = 0; + + mModel.clear(); + mRace.clear(); + } } diff --git a/components/esm/loadbody.hpp b/components/esm/loadbody.hpp index 9623caa31e..286e3f96e3 100644 --- a/components/esm/loadbody.hpp +++ b/components/esm/loadbody.hpp @@ -60,6 +60,9 @@ struct BodyPart void load(ESMReader &esm); void save(ESMWriter &esm) const; + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif From 37a2b48fa285eea3b0060a4b4afb2b67e004f474 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 1 Jul 2014 14:28:12 +0200 Subject: [PATCH 5/6] added missing type columns to body part table --- apps/opencs/model/world/columnbase.hpp | 2 + apps/opencs/model/world/columnimp.hpp | 53 ++++++++++++++++++++++++++ apps/opencs/model/world/columns.cpp | 15 ++++++++ apps/opencs/model/world/columns.hpp | 2 + apps/opencs/model/world/data.cpp | 5 +-- apps/opencs/view/doc/viewmanager.cpp | 2 + 6 files changed, 76 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 3de610320c..39c700fa14 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -90,6 +90,8 @@ namespace CSMWorld Display_DialogueType, Display_QuestStatusType, Display_EnchantmentType, + Display_BodyPartType, + Display_MeshType, Display_Gender }; diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 5844e97a7b..72f2099fae 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -1817,6 +1817,59 @@ namespace CSMWorld } }; + template + struct BodyPartTypeColumn : public Column + { + BodyPartTypeColumn() + : Column (Columns::ColumnId_BodyPartType, ColumnBase::Display_BodyPartType) + {} + + virtual QVariant get (const Record& record) const + { + return static_cast (record.get().mData.mPart); + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + record2.mData.mPart = data.toInt(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; + + template + struct MeshTypeColumn : public Column + { + MeshTypeColumn() + : Column (Columns::ColumnId_MeshType, ColumnBase::Display_MeshType) + {} + + virtual QVariant get (const Record& record) const + { + return static_cast (record.get().mData.mType); + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + record2.mData.mType = data.toInt(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; } #endif diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 3d363aac4b..05df0b7358 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -179,6 +179,8 @@ namespace CSMWorld { ColumnId_StealthState, "Stealth" }, { ColumnId_EnchantmentType, "Enchantment Type" }, { ColumnId_Vampire, "Vampire" }, + { ColumnId_BodyPartType, "Bodypart Type" }, + { ColumnId_MeshType, "Mesh Type" }, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, @@ -309,6 +311,17 @@ namespace "Cast Once", "When Strikes", "When Used", "Constant Effect", 0 }; + static const char *sBodyPartTypes[] = + { + "Head", "Hair", "Neck", "Chest", "Groin", "Hand", "Wrist", "Forearm", "Upper Arm", + "Foot", "Ankle", "Knee", "Upper Leg", "Clavicle", "Tail", 0 + }; + + static const char *sMeshTypes[] = + { + "Skin", "Clothing", "Armour", 0 + }; + const char **getEnumNames (CSMWorld::Columns::ColumnId column) { switch (column) @@ -327,6 +340,8 @@ namespace case CSMWorld::Columns::ColumnId_QuestStatusType: return sQuestStatusTypes; case CSMWorld::Columns::ColumnId_Gender: return sGenderEnums; case CSMWorld::Columns::ColumnId_EnchantmentType: return sEnchantmentTypes; + case CSMWorld::Columns::ColumnId_BodyPartType: return sBodyPartTypes; + case CSMWorld::Columns::ColumnId_MeshType: return sMeshTypes; default: return 0; } diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index bb6c0e4531..326a025965 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -172,6 +172,8 @@ namespace CSMWorld ColumnId_StealthState = 159, ColumnId_EnchantmentType = 160, ColumnId_Vampire = 161, + ColumnId_BodyPartType = 162, + ColumnId_MeshType = 163, // 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/data.cpp b/apps/opencs/model/world/data.cpp index 0353d21426..aad5d3fa2e 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -209,15 +209,14 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding) mBodyParts.addColumn (new StringIdColumn); mBodyParts.addColumn (new RecordStateColumn); mBodyParts.addColumn (new FixedRecordTypeColumn (UniversalId::Type_BodyPart)); - + mBodyParts.addColumn (new BodyPartTypeColumn); mBodyParts.addColumn (new VampireColumn); mBodyParts.addColumn (new FlagColumn (Columns::ColumnId_Female, ESM::BodyPart::BPF_Female)); mBodyParts.addColumn (new FlagColumn (Columns::ColumnId_Playable, ESM::BodyPart::BPF_NotPlayable, true)); - + mBodyParts.addColumn (new MeshTypeColumn); mBodyParts.addColumn (new ModelColumn); mBodyParts.addColumn (new RaceColumn); - mRefs.addColumn (new StringIdColumn (true)); mRefs.addColumn (new RecordStateColumn); mRefs.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Reference)); diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 14607b49ea..6f4217aa8c 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -79,6 +79,8 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) { CSMWorld::ColumnBase::Display_DialogueType, CSMWorld::Columns::ColumnId_DialogueType, false }, { CSMWorld::ColumnBase::Display_QuestStatusType, CSMWorld::Columns::ColumnId_QuestStatusType, false }, { CSMWorld::ColumnBase::Display_EnchantmentType, CSMWorld::Columns::ColumnId_EnchantmentType, false }, + { CSMWorld::ColumnBase::Display_BodyPartType, CSMWorld::Columns::ColumnId_BodyPartType, false }, + { CSMWorld::ColumnBase::Display_MeshType, CSMWorld::Columns::ColumnId_MeshType, false }, { CSMWorld::ColumnBase::Display_Gender, CSMWorld::Columns::ColumnId_Gender, true } }; From 174533598214019a61406bdf568d9d4710145ea6 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 3 Jul 2014 10:56:05 +0200 Subject: [PATCH 6/6] body part table fix: forgot to include body parts in ID listings --- apps/opencs/model/world/data.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index aad5d3fa2e..d07e8784e3 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -712,6 +712,7 @@ bool CSMWorld::Data::hasId (const std::string& id) const getJournals().searchId (id)!=-1 || getCells().searchId (id)!=-1 || getEnchantments().searchId (id)!=-1 || + getBodyParts().searchId (id)!=-1 || getReferenceables().searchId (id)!=-1; } @@ -731,6 +732,7 @@ int CSMWorld::Data::count (RecordBase::State state) const count (state, mSpells) + count (state, mCells) + count (state, mEnchantments) + + count (state, mBodyParts) + count (state, mReferenceables); } @@ -772,6 +774,7 @@ std::vector CSMWorld::Data::getIds (bool listDeleted) const appendIds (ids, mJournals, listDeleted); appendIds (ids, mCells, listDeleted); appendIds (ids, mEnchantments, listDeleted); + appendIds (ids, mBodyParts, listDeleted); appendIds (ids, mReferenceables, listDeleted); std::sort (ids.begin(), ids.end());