From 1ae402476dc6583c40f1ef8e618bd819579b9d4e Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Mon, 22 Feb 2016 17:01:15 -0500 Subject: [PATCH] Journal verifier --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/tools/journalcheck.cpp | 79 ++++++++++++++++++++++++ apps/opencs/model/tools/journalcheck.hpp | 35 +++++++++++ apps/opencs/model/tools/tools.cpp | 3 + 4 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 apps/opencs/model/tools/journalcheck.cpp create mode 100644 apps/opencs/model/tools/journalcheck.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index a657bade2..cbf89a7e5 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -42,7 +42,7 @@ opencs_units_noqt (model/tools mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck birthsigncheck spellcheck referencecheck referenceablecheck scriptcheck bodypartcheck startscriptcheck search searchoperation searchstage pathgridcheck soundgencheck magiceffectcheck - mergestages gmstcheck topicinfocheck + mergestages gmstcheck topicinfocheck journalcheck ) opencs_hdrs_noqt (model/tools diff --git a/apps/opencs/model/tools/journalcheck.cpp b/apps/opencs/model/tools/journalcheck.cpp new file mode 100644 index 000000000..bdd14ddf0 --- /dev/null +++ b/apps/opencs/model/tools/journalcheck.cpp @@ -0,0 +1,79 @@ +#include "journalcheck.hpp" + +#include +#include + +CSMTools::JournalCheckStage::JournalCheckStage(const CSMWorld::IdCollection &journals, + const CSMWorld::InfoCollection& journalInfos) + : mJournals(journals), mJournalInfos(journalInfos) +{} + +int CSMTools::JournalCheckStage::setup() +{ + return mJournals.getSize(); +} + +void CSMTools::JournalCheckStage::perform(int stage, CSMDoc::Messages& messages) +{ + const CSMWorld::Record &journalRecord = mJournals.getRecord(stage); + + if (journalRecord.isDeleted()) + return; + + const ESM::Dialogue &journal = journalRecord.get(); + int statusNamedCount = 0; + int totalInfoCount = 0; + std::set questIndices; + + CSMWorld::InfoCollection::Range range = mJournalInfos.getTopicRange(journal.mId); + + for (CSMWorld::InfoCollection::RecordConstIterator it = range.first; it != range.second; ++it) + { + const CSMWorld::Record infoRecord = (*it); + + if (infoRecord.isDeleted()) + continue; + + const CSMWorld::Info& journalInfo = infoRecord.get(); + + totalInfoCount += 1; + + if (journalInfo.mQuestStatus == ESM::DialInfo::QS_Name) + { + statusNamedCount += 1; + } + + if (journalInfo.mResponse.empty()) + { + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_JournalInfo, journalInfo.mId); + + messages.add(id, "Journal Info: missing description", "", CSMDoc::Message::Severity_Warning); + } + + std::pair::iterator, bool> result = questIndices.insert(journalInfo.mData.mJournalIndex); + + // Duplicate index + if (result.second == false) + { + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_JournalInfo, journalInfo.mId); + + std::ostringstream stream; + stream << "Journal: duplicated quest index " << journalInfo.mData.mJournalIndex; + + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); + } + } + + if (totalInfoCount == 0) + { + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Journal, journal.mId); + + messages.add(id, "Journal: no defined Journal Infos", "", CSMDoc::Message::Severity_Warning); + } + else if (statusNamedCount > 1) + { + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Journal, journal.mId); + + messages.add(id, "Journal: multiple infos with quest status \"Named\"", "", CSMDoc::Message::Severity_Error); + } +} diff --git a/apps/opencs/model/tools/journalcheck.hpp b/apps/opencs/model/tools/journalcheck.hpp new file mode 100644 index 000000000..c9f619698 --- /dev/null +++ b/apps/opencs/model/tools/journalcheck.hpp @@ -0,0 +1,35 @@ +#ifndef CSM_TOOLS_JOURNALCHECK_H +#define CSM_TOOLS_JOURNALCHECK_H + +#include + +#include "../world/idcollection.hpp" +#include "../world/infocollection.hpp" + +#include "../doc/stage.hpp" + +namespace CSMTools +{ + /// \brief VerifyStage: make sure that journal infos are good + class JournalCheckStage : public CSMDoc::Stage + { + public: + + JournalCheckStage(const CSMWorld::IdCollection& journals, + const CSMWorld::InfoCollection& journalInfos); + + virtual int setup(); + ///< \return number of steps + + virtual void perform(int stage, CSMDoc::Messages& messages); + ///< Messages resulting from this stage will be appended to \a messages + + private: + + const CSMWorld::IdCollection& mJournals; + const CSMWorld::InfoCollection& mJournalInfos; + + }; +} + +#endif diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index b6a04a236..f538a716e 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -31,6 +31,7 @@ #include "mergeoperation.hpp" #include "gmstcheck.hpp" #include "topicinfocheck.hpp" +#include "journalcheck.hpp" CSMDoc::OperationHolder *CSMTools::Tools::get (int type) { @@ -128,6 +129,8 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier() mData.getReferenceables().getDataSet(), mData.getResources (CSMWorld::UniversalId::Type_SoundsRes))); + mVerifierOperation->appendStage (new JournalCheckStage(mData.getJournals(), mData.getJournalInfos())); + mVerifier.setOperation (mVerifierOperation); }