From ba88c94d585235d651a7a38fad8a53d8afd3e2c8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 29 Oct 2013 13:18:22 +0100 Subject: [PATCH] first attempt at an info record collection --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/data.cpp | 34 ++++++++++ apps/opencs/model/world/data.hpp | 11 ++++ apps/opencs/model/world/infocollection.cpp | 72 ++++++++++++++++++++++ apps/opencs/model/world/infocollection.hpp | 20 ++++++ apps/opencs/model/world/universalid.cpp | 4 ++ apps/opencs/model/world/universalid.hpp | 4 ++ apps/opencs/view/doc/view.cpp | 18 ++++++ apps/opencs/view/doc/view.hpp | 4 ++ apps/opencs/view/world/subviews.cpp | 2 + components/esm/loadinfo.cpp | 24 ++++++++ components/esm/loadinfo.hpp | 3 + 12 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 apps/opencs/model/world/infocollection.cpp create mode 100644 apps/opencs/model/world/infocollection.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 541b3b5a2..f4846675e 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -24,7 +24,7 @@ opencs_units (model/world opencs_units_noqt (model/world universalid record commands columnbase scriptcontext cell refidcollection - refidadapter refiddata refidadapterimp ref collectionbase refcollection columns + refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection ) opencs_hdrs_noqt (model/world diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 130ce334f..2947b2b8f 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -149,6 +149,12 @@ CSMWorld::Data::Data() : mRefs (mCells) mJournals.addColumn (new RecordStateColumn); mJournals.addColumn (new DialogueTypeColumn (true)); + mTopicInfos.addColumn (new StringIdColumn); + mTopicInfos.addColumn (new RecordStateColumn); + + mJournalInfos.addColumn (new StringIdColumn); + mJournalInfos.addColumn (new RecordStateColumn); + mCells.addColumn (new StringIdColumn); mCells.addColumn (new RecordStateColumn); mCells.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Cell)); @@ -206,6 +212,8 @@ CSMWorld::Data::Data() : mRefs (mCells) addModel (new IdTable (&mSpells), UniversalId::Type_Spells, UniversalId::Type_Spell); addModel (new IdTable (&mTopics), UniversalId::Type_Topics, UniversalId::Type_Topic); addModel (new IdTable (&mJournals), UniversalId::Type_Journals, UniversalId::Type_Journal); + addModel (new IdTable (&mTopicInfos), UniversalId::Type_TopicInfos, UniversalId::Type_TopicInfo); + addModel (new IdTable (&mJournalInfos), UniversalId::Type_JournalInfos, UniversalId::Type_JournalInfo); addModel (new IdTable (&mCells), UniversalId::Type_Cells, UniversalId::Type_Cell); addModel (new IdTable (&mReferenceables), UniversalId::Type_Referenceables, UniversalId::Type_Referenceable); @@ -350,6 +358,25 @@ CSMWorld::IdCollection& CSMWorld::Data::getJournals() return mJournals; } +const CSMWorld::InfoCollection& CSMWorld::Data::getTopicInfos() const +{ + return mTopicInfos; +} + +CSMWorld::InfoCollection& CSMWorld::Data::getTopicInfos() +{ + return mTopicInfos; +} + +const CSMWorld::InfoCollection& CSMWorld::Data::getJournalInfos() const +{ + return mJournalInfos; +} + +CSMWorld::InfoCollection& CSMWorld::Data::getJournalInfos() +{ + return mJournalInfos; +} const CSMWorld::IdCollection& CSMWorld::Data::getCells() const { @@ -514,6 +541,13 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base) break; } + case ESM::REC_INFO: + { + /// \todo associate info record with last loaded dialogue record + mJournalInfos.load (reader, base); + break; + } + default: /// \todo throw an exception instead, once all records are implemented diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index cf31c9494..2b278fd6f 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -29,6 +29,7 @@ #include "cell.hpp" #include "refidcollection.hpp" #include "refcollection.hpp" +#include "infocollection.hpp" class QAbstractItemModel; @@ -51,6 +52,8 @@ namespace CSMWorld IdCollection mSpells; IdCollection mTopics; IdCollection mJournals; + InfoCollection mTopicInfos; + InfoCollection mJournalInfos; IdCollection mCells; RefIdCollection mReferenceables; RefCollection mRefs; @@ -127,6 +130,14 @@ namespace CSMWorld IdCollection& getJournals(); + const InfoCollection& getTopicInfos() const; + + InfoCollection& getTopicInfos(); + + const InfoCollection& getJournalInfos() const; + + InfoCollection& getJournalInfos(); + const IdCollection& getCells() const; IdCollection& getCells(); diff --git a/apps/opencs/model/world/infocollection.cpp b/apps/opencs/model/world/infocollection.cpp new file mode 100644 index 000000000..858f788fa --- /dev/null +++ b/apps/opencs/model/world/infocollection.cpp @@ -0,0 +1,72 @@ + +#include "infocollection.hpp" + +#include + +void CSMWorld::InfoCollection::load (const ESM::DialInfo& record, bool base) +{ + int index = searchId (record.mId); + + if (index==-1) + { + // new record + Record record2; + record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; + (base ? record2.mBase : record2.mModified) = record; + + appendRecord (record2); + } + else + { + // old record + Record record2 = getRecord (index); + + if (base) + record2.mBase = record; + else + record2.setModified (record); + + setRecord (index, record2); + } +} + +void CSMWorld::InfoCollection::load (ESM::ESMReader& reader, bool base) +{ + /// \todo put records into proper order + /// \todo adjust ID + std::string id = reader.getHNOString ("NAME"); + + if (reader.isNextSub ("DELE")) + { + int index = searchId (id); + + reader.skipRecord(); + + if (index==-1) + { + // deleting a record that does not exist + + // ignore it for now + + /// \todo report the problem to the user + } + else if (base) + { + removeRows (index, 1); + } + else + { + Record record = getRecord (index); + record.mState = RecordBase::State_Deleted; + setRecord (index, record); + } + } + else + { + ESM::DialInfo record; + record.mId = id; + record.load (reader); + + load (record, base); + } +} diff --git a/apps/opencs/model/world/infocollection.hpp b/apps/opencs/model/world/infocollection.hpp new file mode 100644 index 000000000..8dca2b219 --- /dev/null +++ b/apps/opencs/model/world/infocollection.hpp @@ -0,0 +1,20 @@ +#ifndef CSM_WOLRD_INFOCOLLECTION_H +#define CSM_WOLRD_INFOCOLLECTION_H + +#include + +#include "collection.hpp" + +namespace CSMWorld +{ + class InfoCollection : public Collection > + { + void load (const ESM::DialInfo& record, bool base); + + public: + + void load (ESM::ESMReader& reader, bool base); + }; +} + +#endif \ No newline at end of file diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index 6201a3cda..e633f4f69 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -31,6 +31,8 @@ namespace { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Spells, "Spells", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Topics, "Topics", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Journals, "Journals", 0 }, + { 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_Referenceables, "Referenceables", 0 }, @@ -58,6 +60,8 @@ namespace { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell", ":./spell.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Topic, "Topic", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Journal, "Journal", 0 }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_TopicInfo, "TopicInfo", 0 }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_JournalInfo, "JournalInfo", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", ":./cell.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Referenceables", 0 }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Activator, "Activator", ":./activator.png" }, diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index ffd99e572..0c17da03b 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -91,6 +91,10 @@ namespace CSMWorld Type_Topic, Type_Journals, Type_Journal, + Type_TopicInfos, + Type_TopicInfo, + Type_JournalInfos, + Type_JournalInfo, Type_Scene }; diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 733f5b2bb..533ca7f57 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -176,6 +176,14 @@ void CSVDoc::View::setupCharacterMenu() QAction *journals = new QAction (tr ("Journals"), this); connect (journals, SIGNAL (triggered()), this, SLOT (addJournalsSubView())); characters->addAction (journals); + + QAction *topicInfos = new QAction (tr ("Topic Infos"), this); + connect (topicInfos, SIGNAL (triggered()), this, SLOT (addTopicInfosSubView())); + characters->addAction (topicInfos); + + QAction *journalInfos = new QAction (tr ("Journal Infos"), this); + connect (journalInfos, SIGNAL (triggered()), this, SLOT (addJournalInfosSubView())); + characters->addAction (journalInfos); } void CSVDoc::View::setupAssetsMenu() @@ -436,6 +444,16 @@ void CSVDoc::View::addJournalsSubView() addSubView (CSMWorld::UniversalId::Type_Journals); } +void CSVDoc::View::addTopicInfosSubView() +{ + addSubView (CSMWorld::UniversalId::Type_TopicInfos); +} + +void CSVDoc::View::addJournalInfosSubView() +{ + addSubView (CSMWorld::UniversalId::Type_JournalInfos); +} + 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 7c13e374f..13c15ec9b 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -172,6 +172,10 @@ namespace CSVDoc void addJournalsSubView(); + void addTopicInfosSubView(); + + void addJournalInfosSubView(); + void toggleShowStatusBar (bool show); }; } diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 3d98cf73c..66e5806ba 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -37,6 +37,8 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_Regions, CSMWorld::UniversalId::Type_Birthsigns, CSMWorld::UniversalId::Type_Spells, + CSMWorld::UniversalId::Type_TopicInfos, + CSMWorld::UniversalId::Type_JournalInfos, CSMWorld::UniversalId::Type_None // end marker }; diff --git a/components/esm/loadinfo.cpp b/components/esm/loadinfo.cpp index 90f8fcf35..f248e0784 100644 --- a/components/esm/loadinfo.cpp +++ b/components/esm/loadinfo.cpp @@ -153,4 +153,28 @@ void DialInfo::save(ESMWriter &esm) } } + void DialInfo::blank() + { + mData.mUnknown1 = 0; + mData.mDisposition = 0; + mData.mRank = 0; + mData.mGender = 0; + mData.mPCrank = 0; + mData.mUnknown2 = 0; + + mSelects.clear(); + mPrev.clear(); + mNext.clear(); + mActor.clear(); + mRace.clear(); + mClass.clear(); + mNpcFaction.clear(); + mPcFaction.clear(); + mCell.clear(); + mSound.clear(); + mResponse.clear(); + mResultScript.clear(); + mFactionLess = false; + mQuestStatus = QS_None; + } } diff --git a/components/esm/loadinfo.hpp b/components/esm/loadinfo.hpp index 2361ed9eb..badb85c38 100644 --- a/components/esm/loadinfo.hpp +++ b/components/esm/loadinfo.hpp @@ -100,6 +100,9 @@ struct DialInfo void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; }