From d3aa5840ec380fcb029e795f31f7158f46d195a7 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 24 Aug 2018 16:57:32 +0300 Subject: [PATCH 01/35] Refactor magic effect record verifying --- apps/opencs/model/tools/magiceffectcheck.cpp | 89 +++++++------------- apps/opencs/model/tools/magiceffectcheck.hpp | 11 +-- 2 files changed, 34 insertions(+), 66 deletions(-) diff --git a/apps/opencs/model/tools/magiceffectcheck.cpp b/apps/opencs/model/tools/magiceffectcheck.cpp index 531bd9e1d..448e4d28c 100644 --- a/apps/opencs/model/tools/magiceffectcheck.cpp +++ b/apps/opencs/model/tools/magiceffectcheck.cpp @@ -9,7 +9,7 @@ namespace { - void addMessageIfNotEmpty(CSMDoc::Messages &messages, const CSMWorld::UniversalId &id, const std::string& text) + void addMessage(CSMDoc::Messages &messages, const CSMWorld::UniversalId &id, const std::string& text) { if (!text.empty()) { @@ -18,42 +18,34 @@ namespace } } -bool CSMTools::MagicEffectCheckStage::isTextureExists(const std::string &texture, bool isIcon) const +std::string CSMTools::MagicEffectCheckStage::checkTexture(const std::string &texture, bool isIcon) const { + if (texture.empty()) return (isIcon ? "Icon is not specified" : std::string()); + const CSMWorld::Resources &textures = isIcon ? mIcons : mTextures; - bool exists = false; + if (textures.searchId(texture) != -1) return std::string(); - if (textures.searchId(texture) != -1) - { - exists = true; - } - else - { - std::string ddsTexture = texture; - if (Misc::ResourceHelpers::changeExtensionToDds(ddsTexture) && textures.searchId(ddsTexture) != -1) - { - exists = true; - } - } + std::string ddsTexture = texture; + if (Misc::ResourceHelpers::changeExtensionToDds(ddsTexture) && textures.searchId(ddsTexture) != -1) return std::string(); - return exists; + return (isIcon ? "Icon '" : "Particle '") + texture + "' does not exist"; } -std::string CSMTools::MagicEffectCheckStage::checkReferenceable(const std::string &id, +std::string CSMTools::MagicEffectCheckStage::checkObject(const std::string &id, const CSMWorld::UniversalId &type, const std::string &column) const { std::string error; if (!id.empty()) { - CSMWorld::RefIdData::LocalIndex index = mReferenceables.getDataSet().searchId(id); + CSMWorld::RefIdData::LocalIndex index = mObjects.getDataSet().searchId(id); if (index.first == -1) { - error = "No such " + column + " '" + id + "'"; + error = column + " '" + id + "' " + "does not exist"; } else if (index.second != type.getType()) { - error = column + " is not of type " + type.getTypeName(); + error = column + " '" + id + "' " + "does not have " + type.getTypeName() + " type"; } } return error; @@ -64,19 +56,19 @@ std::string CSMTools::MagicEffectCheckStage::checkSound(const std::string &id, c std::string error; if (!id.empty() && mSounds.searchId(id) == -1) { - error = "No such " + column + " '" + id + "'"; + error = column + " '" + id + "' " + "does not exist"; } return error; } CSMTools::MagicEffectCheckStage::MagicEffectCheckStage(const CSMWorld::IdCollection &effects, const CSMWorld::IdCollection &sounds, - const CSMWorld::RefIdCollection &referenceables, + const CSMWorld::RefIdCollection &objects, const CSMWorld::Resources &icons, const CSMWorld::Resources &textures) : mMagicEffects(effects), mSounds(sounds), - mReferenceables(referenceables), + mObjects(objects), mIcons(icons), mTextures(textures) { @@ -100,46 +92,25 @@ void CSMTools::MagicEffectCheckStage::perform(int stage, CSMDoc::Messages &messa ESM::MagicEffect effect = record.get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_MagicEffect, effect.mId); - - if (effect.mData.mBaseCost < 0.0f) - { - messages.push_back(std::make_pair(id, "Base Cost is negative")); - } - if (effect.mIcon.empty()) - { - messages.push_back(std::make_pair(id, "Icon is not specified")); - } - else if (!isTextureExists(effect.mIcon, true)) + if (effect.mDescription.empty()) { - messages.push_back(std::make_pair(id, "No such Icon '" + effect.mIcon + "'")); + addMessage(messages, id, "Description is missing"); } - - if (!effect.mParticle.empty() && !isTextureExists(effect.mParticle, false)) + + if (effect.mData.mBaseCost < 0.0f) { - messages.push_back(std::make_pair(id, "No such Particle '" + effect.mParticle + "'")); + addMessage(messages, id, "Base cost is negative"); } - addMessageIfNotEmpty(messages, - id, - checkReferenceable(effect.mCasting, CSMWorld::UniversalId::Type_Static, "Casting Object")); - addMessageIfNotEmpty(messages, - id, - checkReferenceable(effect.mHit, CSMWorld::UniversalId::Type_Static, "Hit Object")); - addMessageIfNotEmpty(messages, - id, - checkReferenceable(effect.mArea, CSMWorld::UniversalId::Type_Static, "Area Object")); - addMessageIfNotEmpty(messages, - id, - checkReferenceable(effect.mBolt, CSMWorld::UniversalId::Type_Weapon, "Bolt Object")); - - addMessageIfNotEmpty(messages, id, checkSound(effect.mCastSound, "Casting Sound")); - addMessageIfNotEmpty(messages, id, checkSound(effect.mHitSound, "Hit Sound")); - addMessageIfNotEmpty(messages, id, checkSound(effect.mAreaSound, "Area Sound")); - addMessageIfNotEmpty(messages, id, checkSound(effect.mBoltSound, "Bolt Sound")); - - if (effect.mDescription.empty()) - { - messages.push_back(std::make_pair(id, "Description is empty")); - } + addMessage(messages, id, checkTexture(effect.mIcon, true)); + addMessage(messages, id, checkTexture(effect.mParticle, false)); + addMessage(messages, id, checkObject(effect.mCasting, CSMWorld::UniversalId::Type_Static, "Casting object")); + addMessage(messages, id, checkObject(effect.mHit, CSMWorld::UniversalId::Type_Static, "Hit object")); + addMessage(messages, id, checkObject(effect.mArea, CSMWorld::UniversalId::Type_Static, "Area object")); + addMessage(messages, id, checkObject(effect.mBolt, CSMWorld::UniversalId::Type_Weapon, "Bolt object")); + addMessage(messages, id, checkSound(effect.mCastSound, "Casting sound")); + addMessage(messages, id, checkSound(effect.mHitSound, "Hit sound")); + addMessage(messages, id, checkSound(effect.mAreaSound, "Area sound")); + addMessage(messages, id, checkSound(effect.mBoltSound, "Bolt sound")); } diff --git a/apps/opencs/model/tools/magiceffectcheck.hpp b/apps/opencs/model/tools/magiceffectcheck.hpp index 28a406283..3e45495c1 100644 --- a/apps/opencs/model/tools/magiceffectcheck.hpp +++ b/apps/opencs/model/tools/magiceffectcheck.hpp @@ -21,23 +21,20 @@ namespace CSMTools { const CSMWorld::IdCollection &mMagicEffects; const CSMWorld::IdCollection &mSounds; - const CSMWorld::RefIdCollection &mReferenceables; + const CSMWorld::RefIdCollection &mObjects; const CSMWorld::Resources &mIcons; const CSMWorld::Resources &mTextures; bool mIgnoreBaseRecords; private: - bool isTextureExists(const std::string &texture, bool isIcon) const; - - std::string checkReferenceable(const std::string &id, - const CSMWorld::UniversalId &type, - const std::string &column) const; + std::string checkTexture(const std::string &texture, bool isIcon) const; + std::string checkObject(const std::string &id, const CSMWorld::UniversalId &type, const std::string &column) const; std::string checkSound(const std::string &id, const std::string &column) const; public: MagicEffectCheckStage(const CSMWorld::IdCollection &effects, const CSMWorld::IdCollection &sounds, - const CSMWorld::RefIdCollection &referenceables, + const CSMWorld::RefIdCollection &objects, const CSMWorld::Resources &icons, const CSMWorld::Resources &textures); From 51fdb94e34427ca01a70228c41791f7e2e49684b Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 24 Aug 2018 17:37:07 +0300 Subject: [PATCH 02/35] Add texture check to birthsign verifier --- apps/opencs/model/tools/birthsigncheck.cpp | 42 +++++++++++++++++----- apps/opencs/model/tools/birthsigncheck.hpp | 14 ++++++-- apps/opencs/model/tools/tools.cpp | 2 +- 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/apps/opencs/model/tools/birthsigncheck.cpp b/apps/opencs/model/tools/birthsigncheck.cpp index fc2989307..4ef264f65 100644 --- a/apps/opencs/model/tools/birthsigncheck.cpp +++ b/apps/opencs/model/tools/birthsigncheck.cpp @@ -4,13 +4,41 @@ #include #include +#include #include "../prefs/state.hpp" +#include "../world/data.hpp" +#include "../world/resources.hpp" #include "../world/universalid.hpp" -CSMTools::BirthsignCheckStage::BirthsignCheckStage (const CSMWorld::IdCollection& birthsigns) -: mBirthsigns (birthsigns) +namespace +{ + void addMessage(CSMDoc::Messages &messages, const CSMWorld::UniversalId &id, const std::string& text) + { + if (!text.empty()) + { + messages.push_back(std::make_pair(id, text)); + } + } +} + + +std::string CSMTools::BirthsignCheckStage::checkTexture(const std::string &texture) const +{ + if (texture.empty()) return "Texture is missing"; + if (mTextures.searchId(texture) != -1) return std::string(); + + std::string ddsTexture = texture; + if (Misc::ResourceHelpers::changeExtensionToDds(ddsTexture) && mTextures.searchId(ddsTexture) != -1) return std::string(); + + return "Texture '" + texture + "' does not exist"; +} + +CSMTools::BirthsignCheckStage::BirthsignCheckStage (const CSMWorld::IdCollection& birthsigns, + const CSMWorld::Resources &textures) +: mBirthsigns(birthsigns), + mTextures(textures) { mIgnoreBaseRecords = false; } @@ -34,17 +62,13 @@ void CSMTools::BirthsignCheckStage::perform (int stage, CSMDoc::Messages& messag CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Birthsign, birthsign.mId); - // test for empty name, description and texture if (birthsign.mName.empty()) - messages.push_back (std::make_pair (id, birthsign.mId + " has an empty name")); + addMessage(messages, id, "Name is missing"); if (birthsign.mDescription.empty()) - messages.push_back (std::make_pair (id, birthsign.mId + " has an empty description")); - - if (birthsign.mTexture.empty()) - messages.push_back (std::make_pair (id, birthsign.mId + " is missing a texture")); + addMessage(messages, id, "Description is missing"); - /// \todo test if the texture exists + addMessage(messages, id, checkTexture(birthsign.mTexture)); /// \todo check data members that can't be edited in the table view } diff --git a/apps/opencs/model/tools/birthsigncheck.hpp b/apps/opencs/model/tools/birthsigncheck.hpp index a8a7a2c14..cd22fb6d0 100644 --- a/apps/opencs/model/tools/birthsigncheck.hpp +++ b/apps/opencs/model/tools/birthsigncheck.hpp @@ -7,17 +7,27 @@ #include "../doc/stage.hpp" +namespace CSMWorld +{ + class Resources; +} + namespace CSMTools { /// \brief VerifyStage: make sure that birthsign records are internally consistent class BirthsignCheckStage : public CSMDoc::Stage { - const CSMWorld::IdCollection& mBirthsigns; + const CSMWorld::IdCollection &mBirthsigns; + const CSMWorld::Resources &mTextures; bool mIgnoreBaseRecords; + private: + std::string checkTexture(const std::string &texture) const; + public: - BirthsignCheckStage (const CSMWorld::IdCollection& birthsigns); + BirthsignCheckStage (const CSMWorld::IdCollection &birthsigns, + const CSMWorld::Resources &textures); virtual int setup(); ///< \return number of steps diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index 445db53af..0946225cf 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -78,7 +78,7 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier() mVerifierOperation->appendStage (new RegionCheckStage (mData.getRegions())); - mVerifierOperation->appendStage (new BirthsignCheckStage (mData.getBirthsigns())); + mVerifierOperation->appendStage (new BirthsignCheckStage (mData.getBirthsigns(), mData.getResources (CSMWorld::UniversalId::Type_Textures))); mVerifierOperation->appendStage (new SpellCheckStage (mData.getSpells())); From 5249492a31f31f04d2acd16c691af82df61f3f05 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 24 Aug 2018 20:13:20 +0300 Subject: [PATCH 03/35] Update skill record verifier messages --- apps/opencs/model/tools/skillcheck.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/tools/skillcheck.cpp b/apps/opencs/model/tools/skillcheck.cpp index b34d18e2a..a2bf3ff03 100644 --- a/apps/opencs/model/tools/skillcheck.cpp +++ b/apps/opencs/model/tools/skillcheck.cpp @@ -38,11 +38,11 @@ void CSMTools::SkillCheckStage::perform (int stage, CSMDoc::Messages& messages) { std::ostringstream stream; - stream << "Use value #" << i << " of " << skill.mId << " is negative"; + stream << "Usage experience value #" << i << " is negative"; messages.push_back (std::make_pair (id, stream.str())); } if (skill.mDescription.empty()) - messages.push_back (std::make_pair (id, skill.mId + " has an empty description")); + messages.push_back (std::make_pair (id, "Description is missing")); } From cf7a8c5775a6dbf29536b6a1c1e7a9c91b6dc9a9 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 24 Aug 2018 20:20:27 +0300 Subject: [PATCH 04/35] Update soundgen record verifier messages --- apps/opencs/model/tools/soundgencheck.cpp | 12 ++++++------ apps/opencs/model/tools/soundgencheck.hpp | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/opencs/model/tools/soundgencheck.cpp b/apps/opencs/model/tools/soundgencheck.cpp index 3692259ce..99a8c184c 100644 --- a/apps/opencs/model/tools/soundgencheck.cpp +++ b/apps/opencs/model/tools/soundgencheck.cpp @@ -9,10 +9,10 @@ CSMTools::SoundGenCheckStage::SoundGenCheckStage(const CSMWorld::IdCollection &soundGens, const CSMWorld::IdCollection &sounds, - const CSMWorld::RefIdCollection &referenceables) + const CSMWorld::RefIdCollection &objects) : mSoundGens(soundGens), mSounds(sounds), - mReferenceables(referenceables) + mObjects(objects) { mIgnoreBaseRecords = false; } @@ -37,10 +37,10 @@ void CSMTools::SoundGenCheckStage::perform(int stage, CSMDoc::Messages &messages if (!soundGen.mCreature.empty()) { - CSMWorld::RefIdData::LocalIndex creatureIndex = mReferenceables.getDataSet().searchId(soundGen.mCreature); + CSMWorld::RefIdData::LocalIndex creatureIndex = mObjects.getDataSet().searchId(soundGen.mCreature); if (creatureIndex.first == -1) { - messages.push_back(std::make_pair(id, "No such creature '" + soundGen.mCreature + "'")); + messages.push_back(std::make_pair(id, "Creature '" + soundGen.mCreature + "' doesn't exist")); } else if (creatureIndex.second != CSMWorld::UniversalId::Type_Creature) { @@ -50,10 +50,10 @@ void CSMTools::SoundGenCheckStage::perform(int stage, CSMDoc::Messages &messages if (soundGen.mSound.empty()) { - messages.push_back(std::make_pair(id, "Sound is not specified")); + messages.push_back(std::make_pair(id, "Sound is missing")); } else if (mSounds.searchId(soundGen.mSound) == -1) { - messages.push_back(std::make_pair(id, "No such sound '" + soundGen.mSound + "'")); + messages.push_back(std::make_pair(id, "Sound '" + soundGen.mSound + "' doesn't exist")); } } diff --git a/apps/opencs/model/tools/soundgencheck.hpp b/apps/opencs/model/tools/soundgencheck.hpp index 19388cb91..3c2a7f071 100644 --- a/apps/opencs/model/tools/soundgencheck.hpp +++ b/apps/opencs/model/tools/soundgencheck.hpp @@ -12,13 +12,13 @@ namespace CSMTools { const CSMWorld::IdCollection &mSoundGens; const CSMWorld::IdCollection &mSounds; - const CSMWorld::RefIdCollection &mReferenceables; + const CSMWorld::RefIdCollection &mObjects; bool mIgnoreBaseRecords; public: SoundGenCheckStage(const CSMWorld::IdCollection &soundGens, const CSMWorld::IdCollection &sounds, - const CSMWorld::RefIdCollection &referenceables); + const CSMWorld::RefIdCollection &objects); virtual int setup(); ///< \return number of steps From fd1a3ad88d1922246e19e667a1a5aac789fff078 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 24 Aug 2018 21:02:42 +0300 Subject: [PATCH 05/35] Update object and script record verifier messages --- .../opencs/model/tools/referenceablecheck.cpp | 164 ++++++++---------- apps/opencs/model/tools/scriptcheck.cpp | 9 +- apps/opencs/model/tools/soundcheck.cpp | 2 +- 3 files changed, 80 insertions(+), 95 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 3e8dc1188..6d06cce12 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -272,7 +272,7 @@ void CSMTools::ReferenceableCheckStage::activatorCheck( //Checking for model, IIRC all activators should have a model if (activator.mModel.empty()) - messages.push_back (std::make_pair (id, activator.mId + " has no model")); + messages.push_back (std::make_pair (id, "Model is missing")); // ADD CHECK HERE // Check that mentioned scripts exist scriptCheck(activator, messages, id.toString()); @@ -340,11 +340,11 @@ void CSMTools::ReferenceableCheckStage::armorCheck( //checking for armor class, armor should have poistive armor class, but 0 is considered legal if (armor.mData.mArmor < 0) - messages.push_back (std::make_pair (id, armor.mId + " has negative armor class")); + messages.push_back (std::make_pair (id, "Armor class is negative")); //checking for health. Only positive numbers are allowed, or 0 is illegal if (armor.mData.mHealth <= 0) - messages.push_back (std::make_pair (id, armor.mId + " has non positive health")); + messages.push_back (std::make_pair (id, "Durability is non-positive")); // Check that mentioned scripts exist scriptCheck(armor, messages, id.toString()); @@ -385,16 +385,15 @@ void CSMTools::ReferenceableCheckStage::containerCheck( //Checking for model, IIRC all containers should have a model if (container.mModel.empty()) - messages.push_back (std::make_pair (id, container.mId + " has no model")); + messages.push_back (std::make_pair (id, "Model is missing")); // ADD CHECK HERE //Checking for capacity (weight) if (container.mWeight < 0) //0 is allowed - messages.push_back (std::make_pair (id, - container.mId + " has negative weight (capacity)")); + messages.push_back (std::make_pair (id, "Capacity is negative")); //checking for name if (container.mName.empty()) - messages.push_back (std::make_pair (id, container.mId + " has an empty name")); + messages.push_back (std::make_pair (id, "Name is missing")); //checking contained items inventoryListCheck(container.mInventory.mList, messages, id.toString()); @@ -417,61 +416,60 @@ void CSMTools::ReferenceableCheckStage::creatureCheck ( CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Creature, creature.mId); if (creature.mModel.empty()) - messages.push_back (std::make_pair (id, creature.mId + " has no model")); + messages.push_back (std::make_pair (id, "Model is missing")); // ADD CHECK HERE if (creature.mName.empty()) - messages.push_back (std::make_pair (id, creature.mId + " has an empty name")); + messages.push_back (std::make_pair (id, "Name is missing")); //stats checks if (creature.mData.mLevel < 1) - messages.push_back (std::make_pair (id, creature.mId + " has non-positive level")); + messages.push_back (std::make_pair (id, "Level is non-positive")); if (creature.mData.mStrength < 0) - messages.push_back (std::make_pair (id, creature.mId + " has negative strength")); + messages.push_back (std::make_pair (id, "Strength is negative")); if (creature.mData.mIntelligence < 0) - messages.push_back (std::make_pair (id, creature.mId + " has negative intelligence")); + messages.push_back (std::make_pair (id, "Intelligence is negative")); if (creature.mData.mWillpower < 0) - messages.push_back (std::make_pair (id, creature.mId + " has negative willpower")); + messages.push_back (std::make_pair (id, "Willpower is negative")); if (creature.mData.mAgility < 0) - messages.push_back (std::make_pair (id, creature.mId + " has negative agility")); + messages.push_back (std::make_pair (id, "Agility is negative")); if (creature.mData.mSpeed < 0) - messages.push_back (std::make_pair (id, creature.mId + " has negative speed")); + messages.push_back (std::make_pair (id, "Speed is negative")); if (creature.mData.mEndurance < 0) - messages.push_back (std::make_pair (id, creature.mId + " has negative endurance")); + messages.push_back (std::make_pair (id, "Endurance is negative")); if (creature.mData.mPersonality < 0) - messages.push_back (std::make_pair (id, creature.mId + " has negative personality")); + messages.push_back (std::make_pair (id, "Personality is negative")); if (creature.mData.mLuck < 0) - messages.push_back (std::make_pair (id, creature.mId + " has negative luck")); + messages.push_back (std::make_pair (id, "Luck is negative")); if (creature.mData.mHealth < 0) - messages.push_back (std::make_pair (id, creature.mId + " has negative health")); + messages.push_back (std::make_pair (id, "Health is negative")); if (creature.mData.mSoul < 0) - messages.push_back (std::make_pair (id, creature.mId + " has negative soul value")); + messages.push_back (std::make_pair (id, "Soul value is negative")); for (int i = 0; i < 6; ++i) { if (creature.mData.mAttack[i] < 0) { - messages.push_back (std::make_pair (id, - creature.mId + " has negative attack strength")); + messages.push_back (std::make_pair (id, "One of attacks has negative damage")); break; } } //TODO, find meaning of other values - if (creature.mData.mGold < 0) //It seems that this is for gold in merchant creatures - messages.push_back (std::make_pair (id, creature.mId + " has negative gold ")); + if (creature.mData.mGold < 0) + messages.push_back (std::make_pair (id, "Gold count is negative")); if (creature.mScale == 0) - messages.push_back (std::make_pair (id, creature.mId + " has zero scale value")); + messages.push_back (std::make_pair (id, "Scale is equal to zero")); // Check inventory inventoryListCheck(creature.mInventory.mList, messages, id.toString()); @@ -495,10 +493,10 @@ void CSMTools::ReferenceableCheckStage::doorCheck( //usual, name or model if (door.mName.empty()) - messages.push_back (std::make_pair (id, door.mId + " has an empty name")); + messages.push_back (std::make_pair (id, "Name is missing")); if (door.mModel.empty()) - messages.push_back (std::make_pair (id, door.mId + " has no model")); + messages.push_back (std::make_pair (id, "Model is missing")); // ADD CHECK HERE // Check that mentioned scripts exist scriptCheck(door, messages, id.toString()); @@ -572,7 +570,7 @@ void CSMTools::ReferenceableCheckStage::lightCheck( CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Light, light.mId); if (light.mData.mRadius < 0) - messages.push_back (std::make_pair (id, light.mId + " has negative light radius")); + messages.push_back (std::make_pair (id, "Light radius is negative")); if (light.mData.mFlags & ESM::Light::Carry) inventoryItemCheck(light, messages, id.toString()); @@ -667,71 +665,69 @@ void CSMTools::ReferenceableCheckStage::npcCheck ( else { if (npc.mNpdt.mAgility == 0) - messages.push_back (std::make_pair (id, npc.mId + " agility has zero value")); + messages.push_back (std::make_pair (id, "Agility is equal to zero")); if (npc.mNpdt.mEndurance == 0) - messages.push_back (std::make_pair (id, npc.mId + " endurance has zero value")); + messages.push_back (std::make_pair (id, "Endurance is equal to zero")); if (npc.mNpdt.mIntelligence == 0) - messages.push_back (std::make_pair (id, npc.mId + " intelligence has zero value")); + messages.push_back (std::make_pair (id, "Intelligence is equal to zero")); if (npc.mNpdt.mLuck == 0) - messages.push_back (std::make_pair (id, npc.mId + " luck has zero value")); + messages.push_back (std::make_pair (id, "Luck is equal to zero")); if (npc.mNpdt.mPersonality == 0) - messages.push_back (std::make_pair (id, npc.mId + " personality has zero value")); + messages.push_back (std::make_pair (id, "Personality is equal to zero")); if (npc.mNpdt.mStrength == 0) - messages.push_back (std::make_pair (id, npc.mId + " strength has zero value")); + messages.push_back (std::make_pair (id, "Strength is equal to zero")); if (npc.mNpdt.mSpeed == 0) - messages.push_back (std::make_pair (id, npc.mId + " speed has zero value")); + messages.push_back (std::make_pair (id, "Speed is equal to zero")); if (npc.mNpdt.mWillpower == 0) - messages.push_back (std::make_pair (id, npc.mId + " willpower has zero value")); + messages.push_back (std::make_pair (id, "Willpower is equal to zero")); } - if (level < 1) - messages.push_back (std::make_pair (id, npc.mId + " level is non positive")); + if (level <= 0) + messages.push_back (std::make_pair (id, "Level is non-positive")); if (gold < 0) - messages.push_back (std::make_pair (id, npc.mId + " gold has negative value")); + messages.push_back (std::make_pair (id, "Gold count is negative")); if (npc.mName.empty()) - messages.push_back (std::make_pair (id, npc.mId + " has any empty name")); + messages.push_back (std::make_pair (id, "Name is missing")); if (npc.mClass.empty()) - messages.push_back (std::make_pair (id, npc.mId + " has an empty class")); + messages.push_back (std::make_pair (id, "Class is missing")); else if (mClasses.searchId (npc.mClass) == -1) - messages.push_back (std::make_pair (id, npc.mId + " has invalid class")); + messages.push_back (std::make_pair (id, "Class '" + npc.mClass + "' does not exist")); if (npc.mRace.empty()) - messages.push_back (std::make_pair (id, npc.mId + " has an empty race")); + messages.push_back (std::make_pair (id, "Race is missing")); else if (mRaces.searchId (npc.mRace) == -1) - messages.push_back (std::make_pair (id, npc.mId + " has invalid race")); + messages.push_back (std::make_pair (id, "Race '" + npc.mRace + "' does not exist")); if (disposition < 0) - messages.push_back (std::make_pair (id, npc.mId + " has negative disposition")); + messages.push_back (std::make_pair (id, "Disposition is negative")); - if (reputation < 0) //It seems that no character in Morrowind.esm have negative reputation. I'm assuming that negative reputation is invalid - { - messages.push_back (std::make_pair (id, npc.mId + " has negative reputation")); - } + if (reputation < 0) + messages.push_back (std::make_pair (id, "Reputation is negative")); if (!npc.mFaction.empty()) { if (rank < 0) - messages.push_back (std::make_pair (id, npc.mId + " has negative rank")); + messages.push_back (std::make_pair (id, "Faction rank is negative")); if (mFactions.searchId(npc.mFaction) == -1) - messages.push_back (std::make_pair (id, npc.mId + " has invalid faction")); + messages.push_back (std::make_pair (id, "Faction '" + npc.mFaction + "' does not exist")); } if (npc.mHead.empty()) - messages.push_back (std::make_pair (id, npc.mId + " has no head")); + messages.push_back (std::make_pair (id, "Head is missing")); // ADD CHECK HERE if (npc.mHair.empty()) - messages.push_back (std::make_pair (id, npc.mId + " has no hair")); + messages.push_back (std::make_pair (id, "Hair is missing")); // ADD CHECK HERE //TODO: reputation, Disposition, rank, everything else @@ -793,28 +789,25 @@ void CSMTools::ReferenceableCheckStage::weaponCheck( weapon.mData.mType == ESM::Weapon::Bolt)) { if (weapon.mData.mSlash[0] > weapon.mData.mSlash[1]) - messages.push_back (std::make_pair (id, - weapon.mId + " has minimum slash damage higher than maximum")); + messages.push_back (std::make_pair (id, "Minimum slash damage higher than maximum")); if (weapon.mData.mThrust[0] > weapon.mData.mThrust[1]) - messages.push_back (std::make_pair (id, - weapon.mId + " has minimum thrust damage higher than maximum")); + messages.push_back (std::make_pair (id, "Minimum thrust damage is higher than maximum")); } if (weapon.mData.mChop[0] > weapon.mData.mChop[1]) - messages.push_back (std::make_pair (id, - weapon.mId + " has minimum chop damage higher than maximum")); + messages.push_back (std::make_pair (id, "Minimum chop damage is higher than maximum")); if (!(weapon.mData.mType == ESM::Weapon::Arrow || weapon.mData.mType == ESM::Weapon::Bolt || weapon.mData.mType == ESM::Weapon::MarksmanThrown)) { //checking of health - if (weapon.mData.mHealth <= 0) - messages.push_back (std::make_pair (id, weapon.mId + " has non-positive health")); + if (weapon.mData.mHealth == 0) + messages.push_back (std::make_pair (id, "Durability is equal to zero")); if (weapon.mData.mReach < 0) - messages.push_back (std::make_pair (id, weapon.mId + " has negative reach")); + messages.push_back (std::make_pair (id, "Reach is negative")); } } @@ -877,7 +870,7 @@ void CSMTools::ReferenceableCheckStage::staticCheck ( CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Static, staticElement.mId); if (staticElement.mModel.empty()) - messages.push_back (std::make_pair (id, staticElement.mId + " has no model")); + messages.push_back (std::make_pair (id, "Model is missing")); } //final check @@ -886,7 +879,7 @@ void CSMTools::ReferenceableCheckStage::finalCheck (CSMDoc::Messages& messages) { if (!mPlayerPresent) messages.push_back (std::make_pair (CSMWorld::UniversalId::Type_Referenceables, - "There is no player record")); + "Player record is missing")); } void CSMTools::ReferenceableCheckStage::inventoryListCheck( @@ -900,8 +893,7 @@ void CSMTools::ReferenceableCheckStage::inventoryListCheck( CSMWorld::RefIdData::LocalIndex localIndex = mReferencables.searchId(itemName); if (localIndex.first == -1) - messages.push_back (std::make_pair (id, - id + " contains non-existing item (" + itemName + ")")); + messages.push_back (std::make_pair (id, "Item '" + itemName + "' does not exist")); else { // Needs to accommodate containers, creatures, and NPCs @@ -922,8 +914,7 @@ void CSMTools::ReferenceableCheckStage::inventoryListCheck( case CSMWorld::UniversalId::Type_ItemLevelledList: break; default: - messages.push_back (std::make_pair(id, - id + " contains item of invalid type (" + itemName + ")")); + messages.push_back (std::make_pair(id, "'" + itemName + "' is not an item")); } } } @@ -935,67 +926,66 @@ template void CSMTools::ReferenceableCheckStage::inventoryItemChe const Item& someItem, CSMDoc::Messages& messages, const std::string& someID, bool enchantable) { if (someItem.mName.empty()) - messages.push_back (std::make_pair (someID, someItem.mId + " has an empty name")); + messages.push_back (std::make_pair (someID, "Name is missing")); //Checking for weight if (someItem.mData.mWeight < 0) - messages.push_back (std::make_pair (someID, someItem.mId + " has negative weight")); + messages.push_back (std::make_pair (someID, "Weight is negative")); //Checking for value if (someItem.mData.mValue < 0) - messages.push_back (std::make_pair (someID, someItem.mId + " has negative value")); + messages.push_back (std::make_pair (someID, "Value is negative")); //checking for model if (someItem.mModel.empty()) - messages.push_back (std::make_pair (someID, someItem.mId + " has no model")); + messages.push_back (std::make_pair (someID, "Model is missing")); // ADD CHECK HERE //checking for icon if (someItem.mIcon.empty()) - messages.push_back (std::make_pair (someID, someItem.mId + " has no icon")); + messages.push_back (std::make_pair (someID, "Icon is missing")); // ADD CHECK HERE if (enchantable && someItem.mData.mEnchant < 0) - messages.push_back (std::make_pair (someID, someItem.mId + " has negative enchantment")); + messages.push_back (std::make_pair (someID, "Enchantment points number is negative")); } template void CSMTools::ReferenceableCheckStage::inventoryItemCheck ( const Item& someItem, CSMDoc::Messages& messages, const std::string& someID) { if (someItem.mName.empty()) - messages.push_back (std::make_pair (someID, someItem.mId + " has an empty name")); + messages.push_back (std::make_pair (someID, "Name is missing")); //Checking for weight if (someItem.mData.mWeight < 0) - messages.push_back (std::make_pair (someID, someItem.mId + " has negative weight")); + messages.push_back (std::make_pair (someID, "Weight is negative")); //Checking for value if (someItem.mData.mValue < 0) - messages.push_back (std::make_pair (someID, someItem.mId + " has negative value")); + messages.push_back (std::make_pair (someID, "Value is negative")); //checking for model if (someItem.mModel.empty()) - messages.push_back (std::make_pair (someID, someItem.mId + " has no model")); + messages.push_back (std::make_pair (someID, "Model is missing")); // ADD CHECK HERE //checking for icon if (someItem.mIcon.empty()) - messages.push_back (std::make_pair (someID, someItem.mId + " has no icon")); + messages.push_back (std::make_pair (someID, "Icon is missing")); // ADD CHECK HERE } template void CSMTools::ReferenceableCheckStage::toolCheck ( const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID, bool canBeBroken) { if (someTool.mData.mQuality <= 0) - messages.push_back (std::make_pair (someID, someTool.mId + " has non-positive quality")); + messages.push_back (std::make_pair (someID, "Quality is non-positive")); if (canBeBroken && someTool.mData.mUses<=0) - messages.push_back (std::make_pair (someID, - someTool.mId + " has non-positive uses count")); + messages.push_back (std::make_pair (someID, "Number of uses is non-positive")); } template void CSMTools::ReferenceableCheckStage::toolCheck ( const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID) { if (someTool.mData.mQuality <= 0) - messages.push_back (std::make_pair (someID, someTool.mId + " has non-positive quality")); + messages.push_back (std::make_pair (someID, "Quality is non-positive")); } template void CSMTools::ReferenceableCheckStage::listCheck ( @@ -1004,12 +994,10 @@ template void CSMTools::ReferenceableCheckStage::listCheck ( for (unsigned i = 0; i < someList.mList.size(); ++i) { if (mReferencables.searchId(someList.mList[i].mId).first == -1) - messages.push_back (std::make_pair (someID, - someList.mId + " contains item without referencable")); + messages.push_back (std::make_pair (someID, "Object '" + someList.mList[i].mId + "' does not exist")); if (someList.mList[i].mLevel < 1) - messages.push_back (std::make_pair (someID, - someList.mId + " contains item with non-positive level")); + messages.push_back (std::make_pair (someID, "Level of item '" + someList.mList[i].mId + "' is non-positive")); } } @@ -1019,6 +1007,6 @@ template void CSMTools::ReferenceableCheckStage::scriptCheck ( if (!someTool.mScript.empty()) { if (mScripts.searchId(someTool.mScript) == -1) - messages.push_back (std::make_pair (someID, someTool.mId + " refers to an unknown script \""+someTool.mScript+"\"")); + messages.push_back (std::make_pair (someID, "Script '"+someTool.mScript+"' does not exist")); } } diff --git a/apps/opencs/model/tools/scriptcheck.cpp b/apps/opencs/model/tools/scriptcheck.cpp index d3c6221cd..e62f9eb88 100644 --- a/apps/opencs/model/tools/scriptcheck.cpp +++ b/apps/opencs/model/tools/scriptcheck.cpp @@ -30,10 +30,7 @@ void CSMTools::ScriptCheckStage::report (const std::string& message, const Compi CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId); - stream - << "script " << mFile - << ", line " << loc.mLine << ", column " << loc.mColumn - << " (" << loc.mLiteral << "): " << message; + stream << "Line " << loc.mLine << ", column " << loc.mColumn << " (" << loc.mLiteral << "): " << message; std::ostringstream hintStream; @@ -47,7 +44,7 @@ void CSMTools::ScriptCheckStage::report (const std::string& message, Type type) CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId); std::ostringstream stream; - stream << "script " << mFile << ": " << message; + stream << message; mMessages->add (id, stream.str(), "", getSeverity (type)); } @@ -128,7 +125,7 @@ void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages) CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId); std::ostringstream stream; - stream << "script " << mFile << ": " << error.what(); + stream << error.what(); messages.add (id, stream.str(), "", CSMDoc::Message::Severity_SeriousError); } diff --git a/apps/opencs/model/tools/soundcheck.cpp b/apps/opencs/model/tools/soundcheck.cpp index b84453b5c..3fdbcc3bc 100644 --- a/apps/opencs/model/tools/soundcheck.cpp +++ b/apps/opencs/model/tools/soundcheck.cpp @@ -36,5 +36,5 @@ void CSMTools::SoundCheckStage::perform (int stage, CSMDoc::Messages& messages) if (sound.mData.mMinRange>sound.mData.mMaxRange) messages.push_back (std::make_pair (id, "Minimum range larger than maximum range")); - /// \todo check, if the sound file exists + /// \todo check, if the sound file exists ADD CHECK HERE } From 7535daa94da38e1259c4aeb61b21bb98e9c4e786 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 24 Aug 2018 21:15:43 +0300 Subject: [PATCH 06/35] Update class and race record verifier messages --- apps/opencs/model/tools/classcheck.cpp | 15 +++++++-------- apps/opencs/model/tools/racecheck.cpp | 12 ++++++------ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/apps/opencs/model/tools/classcheck.cpp b/apps/opencs/model/tools/classcheck.cpp index 89923a398..157dfab7f 100644 --- a/apps/opencs/model/tools/classcheck.cpp +++ b/apps/opencs/model/tools/classcheck.cpp @@ -37,11 +37,11 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages) // A class should have a name if (class_.mName.empty()) - messages.push_back (std::make_pair (id, class_.mId + " doesn't have a name")); + messages.push_back (std::make_pair (id, "Name is missing")); // A playable class should have a description if (class_.mData.mIsPlayable != 0 && class_.mDescription.empty()) - messages.push_back (std::make_pair (id, class_.mId + " doesn't have a description and it's playable")); + messages.push_back (std::make_pair (id, "Description of a playable class is missing")); // test for invalid attributes for (int i=0; i<2; ++i) @@ -49,14 +49,14 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages) { std::ostringstream stream; - stream << "Attribute #" << i << " of " << class_.mId << " is not set"; + stream << "Attribute #" << i << " is not set"; messages.push_back (std::make_pair (id, stream.str())); } if (class_.mData.mAttribute[0]==class_.mData.mAttribute[1] && class_.mData.mAttribute[0]!=-1) { - messages.push_back (std::make_pair (id, "Class lists same attribute twice")); + messages.push_back (std::make_pair (id, "Same attribute is listed twice")); } // test for non-unique skill @@ -66,10 +66,9 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages) for (int i2=0; i2<2; ++i2) ++skills[class_.mData.mSkills[i][i2]]; - for (std::map::const_iterator iter (skills.begin()); iter!=skills.end(); ++iter) - if (iter->second>1) + for (auto &skill : skills) + if (skill.second>1) { - messages.push_back (std::make_pair (id, - ESM::Skill::indexToId (iter->first) + " is listed more than once")); + messages.push_back (std::make_pair (id, "Skill " + ESM::Skill::indexToId (skill.first) + " is listed more than once")); } } diff --git a/apps/opencs/model/tools/racecheck.cpp b/apps/opencs/model/tools/racecheck.cpp index 38abfef18..7ce9a8869 100644 --- a/apps/opencs/model/tools/racecheck.cpp +++ b/apps/opencs/model/tools/racecheck.cpp @@ -29,24 +29,24 @@ void CSMTools::RaceCheckStage::performPerRecord (int stage, CSMDoc::Messages& me // test for empty name and description if (race.mName.empty()) - messages.push_back (std::make_pair (id, race.mId + " has an empty name")); + messages.push_back (std::make_pair (id, "Name is missing")); if (race.mDescription.empty()) - messages.push_back (std::make_pair (id, race.mId + " has an empty description")); + messages.push_back (std::make_pair (id, "Description is missing")); // test for positive height if (race.mData.mHeight.mMale<=0) - messages.push_back (std::make_pair (id, "male " + race.mId + " has non-positive height")); + messages.push_back (std::make_pair (id, "Male height is non-positive")); if (race.mData.mHeight.mFemale<=0) - messages.push_back (std::make_pair (id, "female " + race.mId + " has non-positive height")); + messages.push_back (std::make_pair (id, "Female height is non-positive")); // test for non-negative weight if (race.mData.mWeight.mMale<0) - messages.push_back (std::make_pair (id, "male " + race.mId + " has negative weight")); + messages.push_back (std::make_pair (id, "Male weight is negative")); if (race.mData.mWeight.mFemale<0) - messages.push_back (std::make_pair (id, "female " + race.mId + " has negative weight")); + messages.push_back (std::make_pair (id, "Female weight is negative")); /// \todo check data members that can't be edited in the table view } From a9ce155a7bdacabf351e4a4ec394046a4f0a09ee Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 24 Aug 2018 21:41:10 +0300 Subject: [PATCH 07/35] Update faction and body part record verifier messages --- apps/opencs/model/tools/bodypartcheck.cpp | 15 +++++++-------- apps/opencs/model/tools/factioncheck.cpp | 11 +++++------ 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/apps/opencs/model/tools/bodypartcheck.cpp b/apps/opencs/model/tools/bodypartcheck.cpp index b5bd78f6c..d33705cf6 100644 --- a/apps/opencs/model/tools/bodypartcheck.cpp +++ b/apps/opencs/model/tools/bodypartcheck.cpp @@ -34,25 +34,24 @@ void CSMTools::BodyPartCheckStage::perform (int stage, CSMDoc::Messages &message // Check BYDT if (bodyPart.mData.mPart > 14 ) - messages.push_back(std::make_pair( id, bodyPart.mId + " has out of range part value." )); + messages.push_back(std::make_pair(id, "Invalid mesh part")); if (bodyPart.mData.mFlags > 3 ) - messages.push_back(std::make_pair( id, bodyPart.mId + " has out of range flags value." )); + messages.push_back(std::make_pair(id, "Invalid flags")); if (bodyPart.mData.mType > 2 ) - messages.push_back(std::make_pair( id, bodyPart.mId + " has out of range type value." )); + messages.push_back(std::make_pair(id, "Invalid type")); // Check MODL if ( bodyPart.mModel.empty() ) - messages.push_back(std::make_pair( id, bodyPart.mId + " has no model." )); + messages.push_back(std::make_pair(id, "Model is missing" )); else if ( mMeshes.searchId( bodyPart.mModel ) == -1 ) - messages.push_back(std::make_pair( id, bodyPart.mId + " has invalid model." )); + messages.push_back(std::make_pair(id, "Model '" + bodyPart.mModel + "' does not exist")); // Check FNAM - if ( bodyPart.mRace.empty() ) - messages.push_back(std::make_pair( id, bodyPart.mId + " has no race." )); + messages.push_back(std::make_pair(id, "Race is missing" )); else if ( mRaces.searchId( bodyPart.mRace ) == -1 ) - messages.push_back(std::make_pair( id, bodyPart.mId + " has invalid race." )); + messages.push_back(std::make_pair(id, "Race '" + bodyPart.mRace + " does not exist")); } diff --git a/apps/opencs/model/tools/factioncheck.cpp b/apps/opencs/model/tools/factioncheck.cpp index 39073db5f..d19c0ae52 100644 --- a/apps/opencs/model/tools/factioncheck.cpp +++ b/apps/opencs/model/tools/factioncheck.cpp @@ -37,12 +37,12 @@ void CSMTools::FactionCheckStage::perform (int stage, CSMDoc::Messages& messages // test for empty name if (faction.mName.empty()) - messages.push_back (std::make_pair (id, faction.mId + " has an empty name")); + messages.push_back (std::make_pair (id, "Name is missing")); // test for invalid attributes if (faction.mData.mAttribute[0]==faction.mData.mAttribute[1] && faction.mData.mAttribute[0]!=-1) { - messages.push_back (std::make_pair (id , "Faction lists same attribute twice")); + messages.push_back (std::make_pair (id, "Same attribute is listed twice")); } // test for non-unique skill @@ -52,11 +52,10 @@ void CSMTools::FactionCheckStage::perform (int stage, CSMDoc::Messages& messages if (faction.mData.mSkills[i]!=-1) ++skills[faction.mData.mSkills[i]]; - for (std::map::const_iterator iter (skills.begin()); iter!=skills.end(); ++iter) - if (iter->second>1) + for (auto &skill : skills) + if (skill.second>1) { - messages.push_back (std::make_pair (id, - ESM::Skill::indexToId (iter->first) + " is listed more than once")); + messages.push_back (std::make_pair (id, "Skill " + ESM::Skill::indexToId (skill.first) + " is listed more than once")); } /// \todo check data members that can't be edited in the table view From 14ef145b3b83691e00c2d2c433ab76e069b5e4a2 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 24 Aug 2018 22:01:08 +0300 Subject: [PATCH 08/35] Update region and pathgrid record verifier messages --- apps/opencs/model/tools/pathgridcheck.cpp | 37 +++++++++++------------ apps/opencs/model/tools/regioncheck.cpp | 2 +- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/apps/opencs/model/tools/pathgridcheck.cpp b/apps/opencs/model/tools/pathgridcheck.cpp index c25845885..e63e9122f 100644 --- a/apps/opencs/model/tools/pathgridcheck.cpp +++ b/apps/opencs/model/tools/pathgridcheck.cpp @@ -37,9 +37,9 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message // check the number of pathgrid points if (pathgrid.mData.mS2 < static_cast(pathgrid.mPoints.size())) - messages.add (id, pathgrid.mId + " has less points than expected", "", CSMDoc::Message::Severity_Error); + messages.add (id, "Less points than expected", "", CSMDoc::Message::Severity_Error); else if (pathgrid.mData.mS2 > static_cast(pathgrid.mPoints.size())) - messages.add (id, pathgrid.mId + " has more points than expected", "", CSMDoc::Message::Severity_Error); + messages.add (id, "More points than expected", "", CSMDoc::Message::Severity_Error); std::vector pointList(pathgrid.mPoints.size()); std::vector duplList; @@ -56,9 +56,9 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message if (pointList[pathgrid.mEdges[i].mV0].mOtherIndex[j] == pathgrid.mEdges[i].mV1) { std::ostringstream ss; - ss << "has a duplicate edge between points" << pathgrid.mEdges[i].mV0 - << " and " << pathgrid.mEdges[i].mV1; - messages.add (id, pathgrid.mId + ss.str(), "", CSMDoc::Message::Severity_Error); + ss << "Duplicate edge between points" + << pathgrid.mEdges[i].mV0 << " and " << pathgrid.mEdges[i].mV1; + messages.add (id, ss.str(), "", CSMDoc::Message::Severity_Error); break; } } @@ -70,8 +70,8 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message else { std::ostringstream ss; - ss << " has an edge connecting a non-existent point " << pathgrid.mEdges[i].mV0; - messages.add (id, pathgrid.mId + ss.str(), "", CSMDoc::Message::Severity_Error); + ss << "An edge is connected to a non-existent point " << pathgrid.mEdges[i].mV0; + messages.add (id, ss.str(), "", CSMDoc::Message::Severity_Error); } } @@ -93,8 +93,8 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message if (!foundReverse) { std::ostringstream ss; - ss << " has a missing edge between points " << i << " and " << pointList[i].mOtherIndex[j]; - messages.add (id, pathgrid.mId + ss.str(), "", CSMDoc::Message::Severity_Error); + ss << "Missing edge between points " << i << " and " << pointList[i].mOtherIndex[j]; + messages.add (id, ss.str(), "", CSMDoc::Message::Severity_Error); } } @@ -113,11 +113,9 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message if (it == duplList.end()) { std::ostringstream ss; - ss << " has a duplicated point (" << i - << ") x=" << pathgrid.mPoints[i].mX - << ", y=" << pathgrid.mPoints[i].mY - << ", z=" << pathgrid.mPoints[i].mZ; - messages.add (id, pathgrid.mId + ss.str(), "", CSMDoc::Message::Severity_Warning); + ss << "Point " << i << " duplicates point " << j + << " (" << pathgrid.mPoints[i].mX << ", " << pathgrid.mPoints[i].mY << ", " << pathgrid.mPoints[i].mZ << ")"; + messages.add (id, ss.str(), "", CSMDoc::Message::Severity_Warning); duplList.push_back(i); break; @@ -132,11 +130,12 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message if (pointList[i].mConnectionNum == 0) { std::ostringstream ss; - ss << " has an orphaned point (" << i - << ") x=" << pathgrid.mPoints[i].mX - << ", y=" << pathgrid.mPoints[i].mY - << ", z=" << pathgrid.mPoints[i].mZ; - messages.add (id, pathgrid.mId + ss.str(), "", CSMDoc::Message::Severity_Warning); + ss << "Point " << i << " (" + << pathgrid.mPoints[i].mX << ", " + << pathgrid.mPoints[i].mY << ", " + << pathgrid.mPoints[i].mZ << ") " + << "is disconnected from other points"; + messages.add (id, ss.str(), "", CSMDoc::Message::Severity_Warning); } } diff --git a/apps/opencs/model/tools/regioncheck.cpp b/apps/opencs/model/tools/regioncheck.cpp index f21253090..8375e3f0a 100644 --- a/apps/opencs/model/tools/regioncheck.cpp +++ b/apps/opencs/model/tools/regioncheck.cpp @@ -36,7 +36,7 @@ void CSMTools::RegionCheckStage::perform (int stage, CSMDoc::Messages& messages) // test for empty name if (region.mName.empty()) - messages.add(id, region.mId + " has an empty name", "", CSMDoc::Message::Severity_Error); + messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); /// \todo test that the ID in mSleeplist exists From a6d3cd919016c060bc1d2735e85f5653d0db53d1 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 24 Aug 2018 23:12:11 +0300 Subject: [PATCH 09/35] Update topic info verifier messages --- apps/opencs/model/tools/magiceffectcheck.cpp | 4 +- apps/opencs/model/tools/topicinfocheck.cpp | 109 ++++++++----------- apps/opencs/model/tools/topicinfocheck.hpp | 11 -- 3 files changed, 48 insertions(+), 76 deletions(-) diff --git a/apps/opencs/model/tools/magiceffectcheck.cpp b/apps/opencs/model/tools/magiceffectcheck.cpp index 448e4d28c..7e7a09aa5 100644 --- a/apps/opencs/model/tools/magiceffectcheck.cpp +++ b/apps/opencs/model/tools/magiceffectcheck.cpp @@ -20,7 +20,7 @@ namespace std::string CSMTools::MagicEffectCheckStage::checkTexture(const std::string &texture, bool isIcon) const { - if (texture.empty()) return (isIcon ? "Icon is not specified" : std::string()); + if (texture.empty()) return (isIcon ? "Icon is missing" : std::string()); const CSMWorld::Resources &textures = isIcon ? mIcons : mTextures; if (textures.searchId(texture) != -1) return std::string(); @@ -97,7 +97,7 @@ void CSMTools::MagicEffectCheckStage::perform(int stage, CSMDoc::Messages &messa { addMessage(messages, id, "Description is missing"); } - + if (effect.mData.mBaseCost < 0.0f) { addMessage(messages, id, "Base cost is negative"); diff --git a/apps/opencs/model/tools/topicinfocheck.cpp b/apps/opencs/model/tools/topicinfocheck.cpp index ac1f596ae..9a31db72b 100644 --- a/apps/opencs/model/tools/topicinfocheck.cpp +++ b/apps/opencs/model/tools/topicinfocheck.cpp @@ -134,7 +134,7 @@ void CSMTools::TopicInfoCheckStage::perform(int stage, CSMDoc::Messages& message if (topicInfo.mData.mGender < -1 || topicInfo.mData.mGender > 1) { std::ostringstream stream; - messages.add(id, "Gender: Value is invalid", "", CSMDoc::Message::Severity_Error); + messages.add(id, "Gender is invalid", "", CSMDoc::Message::Severity_Error); } if (!topicInfo.mRace.empty()) @@ -166,23 +166,28 @@ void CSMTools::TopicInfoCheckStage::perform(int stage, CSMDoc::Messages& message bool CSMTools::TopicInfoCheckStage::verifyActor(const std::string& actor, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages) { - const std::string specifier = "Actor"; - CSMWorld::RefIdData::LocalIndex index = mReferencables.searchId(actor); if (index.first == -1) { - writeMissingIdError(specifier, actor, id, messages); + std::ostringstream stream; + stream << "Actor '" << actor << "' does not exist"; + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); return false; } else if (mReferencables.getRecord(index).isDeleted()) { - writeDeletedRecordError(specifier, actor, id, messages); + std::ostringstream stream; + stream << "Deleted actor '" << actor << "' is being referenced"; + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); return false; } else if (index.second != CSMWorld::UniversalId::Type_Npc && index.second != CSMWorld::UniversalId::Type_Creature) { - writeInvalidTypeError(specifier, actor, index.second, "NPC or Creature", id, messages); + CSMWorld::UniversalId tempId(index.second, actor); + std::ostringstream stream; + stream << "Object '" << actor << "' has invalid type " << tempId.getTypeName() << " (an actor must be an NPC or a creature)"; + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); return false; } @@ -192,11 +197,11 @@ bool CSMTools::TopicInfoCheckStage::verifyActor(const std::string& actor, const bool CSMTools::TopicInfoCheckStage::verifyCell(const std::string& cell, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages) { - const std::string specifier = "Cell"; - if (mCellNames.find(cell) == mCellNames.end()) { - writeMissingIdError(specifier, cell, id, messages); + std::ostringstream stream; + stream << "Cell '" << cell << "' does not exist"; + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); return false; } @@ -209,9 +214,8 @@ bool CSMTools::TopicInfoCheckStage::verifyFactionRank(const std::string& faction if (rank < -1) { std::ostringstream stream; - stream << "Rank or PC Rank is set to " << rank << ", but should be set to -1 if no rank is required"; - - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); + stream << "Faction rank is set to " << rank << ", but it should be set to -1 if there are no rank requirements"; + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Warning); return false; } @@ -229,10 +233,10 @@ bool CSMTools::TopicInfoCheckStage::verifyFactionRank(const std::string& faction if (rank >= limit) { std::ostringstream stream; - stream << "Rank or PC Rank is set to " << rank << " which is more than the maximum of " << limit - 1 - << " for the " << factionName << " faction"; + stream << "Faction rank is set to " << rank << " which is more than the maximum of " << limit - 1 + << " for the '" << factionName << "' faction"; - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Warning); return false; } @@ -242,18 +246,20 @@ bool CSMTools::TopicInfoCheckStage::verifyFactionRank(const std::string& faction bool CSMTools::TopicInfoCheckStage::verifyItem(const std::string& item, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages) { - const std::string specifier = "Item"; - CSMWorld::RefIdData::LocalIndex index = mReferencables.searchId(item); if (index.first == -1) { - writeMissingIdError(specifier, item, id, messages); + std::ostringstream stream; + stream << "Item '" << item << "' does not exist"; + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); return false; } else if (mReferencables.getRecord(index).isDeleted()) { - writeDeletedRecordError(specifier, item, id, messages); + std::ostringstream stream; + stream << "Deleted item '" << item << "' is being referenced"; + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); return false; } else @@ -276,8 +282,13 @@ bool CSMTools::TopicInfoCheckStage::verifyItem(const std::string& item, const CS break; default: - writeInvalidTypeError(specifier, item, index.second, "Potion, Armor, Book, etc.", id, messages); + { + CSMWorld::UniversalId tempId(index.second, item); + std::ostringstream stream; + stream << "Object '" << item << "' has invalid type " << tempId.getTypeName() << " (an item can be a potion, an armor piece, a book and so on)"; + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); return false; + } } } @@ -291,13 +302,13 @@ bool CSMTools::TopicInfoCheckStage::verifySelectStruct(const ESM::DialInfo::Sele if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_None) { - messages.add(id, "Invalid Info Condition: " + infoCondition.toString(), "", CSMDoc::Message::Severity_Error); + messages.add(id, "Invalid condition '" + infoCondition.toString() + "'", "", CSMDoc::Message::Severity_Error); return false; } else if (!infoCondition.variantTypeIsValid()) { std::ostringstream stream; - stream << "Info Condition: Value for \"" << infoCondition.toString() << "\" has a type of "; + stream << "Value of condition '" << infoCondition.toString() << "' has invalid "; switch (select.mValue.getType()) { @@ -307,8 +318,9 @@ bool CSMTools::TopicInfoCheckStage::verifySelectStruct(const ESM::DialInfo::Sele case ESM::VT_Long: stream << "Long"; break; case ESM::VT_Float: stream << "Float"; break; case ESM::VT_String: stream << "String"; break; - default: stream << "Unknown"; break; + default: stream << "unknown"; break; } + stream << " type"; messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); return false; @@ -316,7 +328,7 @@ bool CSMTools::TopicInfoCheckStage::verifySelectStruct(const ESM::DialInfo::Sele else if (infoCondition.conditionIsAlwaysTrue()) { std::ostringstream stream; - stream << "Info Condition: " << infoCondition.toString() << " is always true"; + stream << "Condition '" << infoCondition.toString() << "' is always true"; messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Warning); return false; @@ -324,7 +336,7 @@ bool CSMTools::TopicInfoCheckStage::verifySelectStruct(const ESM::DialInfo::Sele else if (infoCondition.conditionIsNeverTrue()) { std::ostringstream stream; - stream << "Info Condition: " << infoCondition.toString() << " is never true"; + stream << "Condition '" << infoCondition.toString() << "' is never true"; messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Warning); return false; @@ -383,11 +395,11 @@ bool CSMTools::TopicInfoCheckStage::verifySelectStruct(const ESM::DialInfo::Sele bool CSMTools::TopicInfoCheckStage::verifySound(const std::string& sound, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages) { - const std::string specifier = "Sound File"; - if (mSoundFiles.searchId(sound) == -1) { - writeMissingIdError(specifier, sound, id, messages); + std::ostringstream stream; + stream << "Sound file '" << sound << "' does not exist"; + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); return false; } @@ -402,47 +414,18 @@ bool CSMTools::TopicInfoCheckStage::verifyId(const std::string& name, const CSMW if (index == -1) { - writeMissingIdError(T::getRecordType(), name, id, messages); + std::ostringstream stream; + stream << T::getRecordType() + " '" << name << "' does not exist"; + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); return false; } else if (collection.getRecord(index).isDeleted()) { - writeDeletedRecordError(T::getRecordType(), name, id, messages); + std::ostringstream stream; + stream << "Deleted " << T::getRecordType() << " record '" << name << "' is being referenced"; + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); return false; } return true; } - -// Error functions - -void CSMTools::TopicInfoCheckStage::writeMissingIdError(const std::string& specifier, const std::string& missingId, - const CSMWorld::UniversalId& id, CSMDoc::Messages& messages) -{ - std::ostringstream stream; - stream << specifier << ": ID or name \"" << missingId << "\" could not be found"; - - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); -} - -void CSMTools::TopicInfoCheckStage::writeDeletedRecordError(const std::string& specifier, const std::string& recordId, - const CSMWorld::UniversalId& id, CSMDoc::Messages& messages) -{ - std::ostringstream stream; - stream << specifier << ": Deleted record with ID \"" << recordId << "\" is being referenced"; - - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); -} - -void CSMTools::TopicInfoCheckStage::writeInvalidTypeError(const std::string& specifier, const std::string& invalidId, - CSMWorld::UniversalId::Type invalidType, const std::string& expectedType, const CSMWorld::UniversalId& id, - CSMDoc::Messages& messages) -{ - CSMWorld::UniversalId tempId(invalidType, invalidId); - - std::ostringstream stream; - stream << specifier << ": invalid type of " << tempId.getTypeName() << " was found for referencable \"" - << invalidId << "\" (can be of type " << expectedType << ")"; - - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); -} diff --git a/apps/opencs/model/tools/topicinfocheck.hpp b/apps/opencs/model/tools/topicinfocheck.hpp index dbd5fe1c5..9575181b0 100644 --- a/apps/opencs/model/tools/topicinfocheck.hpp +++ b/apps/opencs/model/tools/topicinfocheck.hpp @@ -80,17 +80,6 @@ namespace CSMTools template bool verifyId(const std::string& name, const CSMWorld::IdCollection& collection, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages); - - // Common error messages - void writeMissingIdError(const std::string& specifier, const std::string& missingId, - const CSMWorld::UniversalId& id, CSMDoc::Messages& messages); - - void writeDeletedRecordError(const std::string& specifier, const std::string& recordId, - const CSMWorld::UniversalId& id, CSMDoc::Messages& messages); - - void writeInvalidTypeError(const std::string& specifier, const std::string& invalidId, - CSMWorld::UniversalId::Type invalidType, const std::string& expectedType, - const CSMWorld::UniversalId& id, CSMDoc::Messages& messages); }; } From 1f717def35c32dfa78c356239dd0a32b83554e19 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 25 Aug 2018 00:27:42 +0300 Subject: [PATCH 10/35] Update journal, start script and spell verifiers messages --- apps/opencs/model/tools/journalcheck.cpp | 18 +++++------------- apps/opencs/model/tools/spellcheck.cpp | 4 ++-- apps/opencs/model/tools/startscriptcheck.cpp | 3 +-- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/apps/opencs/model/tools/journalcheck.cpp b/apps/opencs/model/tools/journalcheck.cpp index 4a7ab7d66..bd77e95b6 100644 --- a/apps/opencs/model/tools/journalcheck.cpp +++ b/apps/opencs/model/tools/journalcheck.cpp @@ -33,6 +33,7 @@ void CSMTools::JournalCheckStage::perform(int stage, CSMDoc::Messages& messages) std::set questIndices; CSMWorld::InfoCollection::Range range = mJournalInfos.getTopicRange(journal.mId); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Journal, journal.mId); for (CSMWorld::InfoCollection::RecordConstIterator it = range.first; it != range.second; ++it) { @@ -56,9 +57,7 @@ void CSMTools::JournalCheckStage::perform(int stage, CSMDoc::Messages& messages) if (journalInfo.mResponse.empty()) { - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_JournalInfo, journalInfo.mId); - - messages.add(id, "Journal Info: missing description", "", CSMDoc::Message::Severity_Warning); + messages.add(id, "Missing journal entry text", "", CSMDoc::Message::Severity_Warning); } std::pair::iterator, bool> result = questIndices.insert(journalInfo.mData.mJournalIndex); @@ -66,25 +65,18 @@ void CSMTools::JournalCheckStage::perform(int stage, CSMDoc::Messages& messages) // 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; - + stream << "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); + messages.add(id, "No related journal entry", "", 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); + messages.add(id, "Multiple entries with quest status 'Named'", "", CSMDoc::Message::Severity_Error); } } diff --git a/apps/opencs/model/tools/spellcheck.cpp b/apps/opencs/model/tools/spellcheck.cpp index 3e59f0d9a..6c08aca37 100644 --- a/apps/opencs/model/tools/spellcheck.cpp +++ b/apps/opencs/model/tools/spellcheck.cpp @@ -36,11 +36,11 @@ void CSMTools::SpellCheckStage::perform (int stage, CSMDoc::Messages& messages) // test for empty name and description if (spell.mName.empty()) - messages.push_back (std::make_pair (id, spell.mId + " has an empty name")); + messages.push_back (std::make_pair (id, "Name is missing")); // test for invalid cost values if (spell.mData.mCost<0) - messages.push_back (std::make_pair (id, spell.mId + " has a negative spell costs")); + messages.push_back (std::make_pair (id, "Spell cost is negative")); /// \todo check data members that can't be edited in the table view } diff --git a/apps/opencs/model/tools/startscriptcheck.cpp b/apps/opencs/model/tools/startscriptcheck.cpp index b1d92380b..5a9f63dc4 100644 --- a/apps/opencs/model/tools/startscriptcheck.cpp +++ b/apps/opencs/model/tools/startscriptcheck.cpp @@ -25,8 +25,7 @@ void CSMTools::StartScriptCheckStage::perform(int stage, CSMDoc::Messages& messa CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_StartScript, scriptId); if (mScripts.searchId (Misc::StringUtils::lowerCase (scriptId))==-1) - messages.push_back ( - std::make_pair (id, "Start script " + scriptId + " does not exist")); + messages.push_back (std::make_pair (id, "Start script " + scriptId + " does not exist")); } int CSMTools::StartScriptCheckStage::setup() From 38ea7928f54876755d30a732fd36ed2db547d039 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 25 Aug 2018 00:47:38 +0300 Subject: [PATCH 11/35] Add sound file checks to sound record verifier --- apps/opencs/model/tools/soundcheck.cpp | 17 ++++++++++++++--- apps/opencs/model/tools/soundcheck.hpp | 9 ++++++++- apps/opencs/model/tools/tools.cpp | 2 +- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/tools/soundcheck.cpp b/apps/opencs/model/tools/soundcheck.cpp index 3fdbcc3bc..5708a59d3 100644 --- a/apps/opencs/model/tools/soundcheck.cpp +++ b/apps/opencs/model/tools/soundcheck.cpp @@ -6,10 +6,14 @@ #include "../prefs/state.hpp" +#include "../world/data.hpp" +#include "../world/resources.hpp" #include "../world/universalid.hpp" -CSMTools::SoundCheckStage::SoundCheckStage (const CSMWorld::IdCollection& sounds) -: mSounds (sounds) +CSMTools::SoundCheckStage::SoundCheckStage (const CSMWorld::IdCollection &sounds, + const CSMWorld::Resources &soundfiles) + : mSounds (sounds), + mSoundFiles (soundfiles) { mIgnoreBaseRecords = false; } @@ -36,5 +40,12 @@ void CSMTools::SoundCheckStage::perform (int stage, CSMDoc::Messages& messages) if (sound.mData.mMinRange>sound.mData.mMaxRange) messages.push_back (std::make_pair (id, "Minimum range larger than maximum range")); - /// \todo check, if the sound file exists ADD CHECK HERE + if (sound.mSound.empty()) + { + messages.push_back(std::make_pair(id, "Sound file is missing")); + } + else if (mSoundFiles.searchId(sound.mSound) == -1) + { + messages.push_back(std::make_pair(id, "Sound file '" + sound.mSound + "' does not exist")); + } } diff --git a/apps/opencs/model/tools/soundcheck.hpp b/apps/opencs/model/tools/soundcheck.hpp index d6fff5263..47c3249ce 100644 --- a/apps/opencs/model/tools/soundcheck.hpp +++ b/apps/opencs/model/tools/soundcheck.hpp @@ -7,17 +7,24 @@ #include "../doc/stage.hpp" +namespace CSMWorld +{ + class Resources; +} + namespace CSMTools { /// \brief VerifyStage: make sure that sound records are internally consistent class SoundCheckStage : public CSMDoc::Stage { const CSMWorld::IdCollection& mSounds; + const CSMWorld::Resources &mSoundFiles; bool mIgnoreBaseRecords; public: - SoundCheckStage (const CSMWorld::IdCollection& sounds); + SoundCheckStage (const CSMWorld::IdCollection& sounds, + const CSMWorld::Resources &soundfiles); virtual int setup(); ///< \return number of steps diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index 0946225cf..dfa2ae202 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -74,7 +74,7 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier() mVerifierOperation->appendStage (new RaceCheckStage (mData.getRaces())); - mVerifierOperation->appendStage (new SoundCheckStage (mData.getSounds())); + mVerifierOperation->appendStage (new SoundCheckStage (mData.getSounds(), mData.getResources (CSMWorld::UniversalId::Type_SoundsRes))); mVerifierOperation->appendStage (new RegionCheckStage (mData.getRegions())); From d90940011f7c1bd5f25dedc9cae476b61b1f7b15 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 25 Aug 2018 01:22:41 +0300 Subject: [PATCH 12/35] Add model checks to object record verifier --- .../opencs/model/tools/referenceablecheck.cpp | 123 ++++++++++-------- .../opencs/model/tools/referenceablecheck.hpp | 7 +- apps/opencs/model/tools/tools.cpp | 3 +- 3 files changed, 75 insertions(+), 58 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 6d06cce12..8a1103c3d 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -11,13 +11,14 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& classes, const CSMWorld::IdCollection& faction, - const CSMWorld::IdCollection& scripts) - : - mReferencables(referenceable), + const CSMWorld::IdCollection& scripts, + const CSMWorld::Resources& models) + :mObjects(referenceable), mRaces(races), mClasses(classes), mFactions(faction), mScripts(scripts), + mModels(models), mPlayerPresent(false) { mIgnoreBaseRecords = false; @@ -26,201 +27,201 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( void CSMTools::ReferenceableCheckStage::perform (int stage, CSMDoc::Messages& messages) { //Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage. - const int bookSize(mReferencables.getBooks().getSize()); + const int bookSize(mObjects.getBooks().getSize()); if (stage < bookSize) { - bookCheck(stage, mReferencables.getBooks(), messages); + bookCheck(stage, mObjects.getBooks(), messages); return; } stage -= bookSize; - const int activatorSize(mReferencables.getActivators().getSize()); + const int activatorSize(mObjects.getActivators().getSize()); if (stage < activatorSize) { - activatorCheck(stage, mReferencables.getActivators(), messages); + activatorCheck(stage, mObjects.getActivators(), messages); return; } stage -= activatorSize; - const int potionSize(mReferencables.getPotions().getSize()); + const int potionSize(mObjects.getPotions().getSize()); if (stage < potionSize) { - potionCheck(stage, mReferencables.getPotions(), messages); + potionCheck(stage, mObjects.getPotions(), messages); return; } stage -= potionSize; - const int apparatusSize(mReferencables.getApparati().getSize()); + const int apparatusSize(mObjects.getApparati().getSize()); if (stage < apparatusSize) { - apparatusCheck(stage, mReferencables.getApparati(), messages); + apparatusCheck(stage, mObjects.getApparati(), messages); return; } stage -= apparatusSize; - const int armorSize(mReferencables.getArmors().getSize()); + const int armorSize(mObjects.getArmors().getSize()); if (stage < armorSize) { - armorCheck(stage, mReferencables.getArmors(), messages); + armorCheck(stage, mObjects.getArmors(), messages); return; } stage -= armorSize; - const int clothingSize(mReferencables.getClothing().getSize()); + const int clothingSize(mObjects.getClothing().getSize()); if (stage < clothingSize) { - clothingCheck(stage, mReferencables.getClothing(), messages); + clothingCheck(stage, mObjects.getClothing(), messages); return; } stage -= clothingSize; - const int containerSize(mReferencables.getContainers().getSize()); + const int containerSize(mObjects.getContainers().getSize()); if (stage < containerSize) { - containerCheck(stage, mReferencables.getContainers(), messages); + containerCheck(stage, mObjects.getContainers(), messages); return; } stage -= containerSize; - const int doorSize(mReferencables.getDoors().getSize()); + const int doorSize(mObjects.getDoors().getSize()); if (stage < doorSize) { - doorCheck(stage, mReferencables.getDoors(), messages); + doorCheck(stage, mObjects.getDoors(), messages); return; } stage -= doorSize; - const int ingredientSize(mReferencables.getIngredients().getSize()); + const int ingredientSize(mObjects.getIngredients().getSize()); if (stage < ingredientSize) { - ingredientCheck(stage, mReferencables.getIngredients(), messages); + ingredientCheck(stage, mObjects.getIngredients(), messages); return; } stage -= ingredientSize; - const int creatureLevListSize(mReferencables.getCreatureLevelledLists().getSize()); + const int creatureLevListSize(mObjects.getCreatureLevelledLists().getSize()); if (stage < creatureLevListSize) { - creaturesLevListCheck(stage, mReferencables.getCreatureLevelledLists(), messages); + creaturesLevListCheck(stage, mObjects.getCreatureLevelledLists(), messages); return; } stage -= creatureLevListSize; - const int itemLevelledListSize(mReferencables.getItemLevelledList().getSize()); + const int itemLevelledListSize(mObjects.getItemLevelledList().getSize()); if (stage < itemLevelledListSize) { - itemLevelledListCheck(stage, mReferencables.getItemLevelledList(), messages); + itemLevelledListCheck(stage, mObjects.getItemLevelledList(), messages); return; } stage -= itemLevelledListSize; - const int lightSize(mReferencables.getLights().getSize()); + const int lightSize(mObjects.getLights().getSize()); if (stage < lightSize) { - lightCheck(stage, mReferencables.getLights(), messages); + lightCheck(stage, mObjects.getLights(), messages); return; } stage -= lightSize; - const int lockpickSize(mReferencables.getLocpicks().getSize()); + const int lockpickSize(mObjects.getLocpicks().getSize()); if (stage < lockpickSize) { - lockpickCheck(stage, mReferencables.getLocpicks(), messages); + lockpickCheck(stage, mObjects.getLocpicks(), messages); return; } stage -= lockpickSize; - const int miscSize(mReferencables.getMiscellaneous().getSize()); + const int miscSize(mObjects.getMiscellaneous().getSize()); if (stage < miscSize) { - miscCheck(stage, mReferencables.getMiscellaneous(), messages); + miscCheck(stage, mObjects.getMiscellaneous(), messages); return; } stage -= miscSize; - const int npcSize(mReferencables.getNPCs().getSize()); + const int npcSize(mObjects.getNPCs().getSize()); if (stage < npcSize) { - npcCheck(stage, mReferencables.getNPCs(), messages); + npcCheck(stage, mObjects.getNPCs(), messages); return; } stage -= npcSize; - const int weaponSize(mReferencables.getWeapons().getSize()); + const int weaponSize(mObjects.getWeapons().getSize()); if (stage < weaponSize) { - weaponCheck(stage, mReferencables.getWeapons(), messages); + weaponCheck(stage, mObjects.getWeapons(), messages); return; } stage -= weaponSize; - const int probeSize(mReferencables.getProbes().getSize()); + const int probeSize(mObjects.getProbes().getSize()); if (stage < probeSize) { - probeCheck(stage, mReferencables.getProbes(), messages); + probeCheck(stage, mObjects.getProbes(), messages); return; } stage -= probeSize; - const int repairSize(mReferencables.getRepairs().getSize()); + const int repairSize(mObjects.getRepairs().getSize()); if (stage < repairSize) { - repairCheck(stage, mReferencables.getRepairs(), messages); + repairCheck(stage, mObjects.getRepairs(), messages); return; } stage -= repairSize; - const int staticSize(mReferencables.getStatics().getSize()); + const int staticSize(mObjects.getStatics().getSize()); if (stage < staticSize) { - staticCheck(stage, mReferencables.getStatics(), messages); + staticCheck(stage, mObjects.getStatics(), messages); return; } stage -= staticSize; - const int creatureSize(mReferencables.getCreatures().getSize()); + const int creatureSize(mObjects.getCreatures().getSize()); if (stage < creatureSize) { - creatureCheck(stage, mReferencables.getCreatures(), messages); + creatureCheck(stage, mObjects.getCreatures(), messages); return; } // if we come that far, we are about to perform our last, final check. @@ -233,7 +234,7 @@ int CSMTools::ReferenceableCheckStage::setup() mPlayerPresent = false; mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue(); - return mReferencables.getSize() + 1; + return mObjects.getSize() + 1; } void CSMTools::ReferenceableCheckStage::bookCheck( @@ -272,7 +273,9 @@ void CSMTools::ReferenceableCheckStage::activatorCheck( //Checking for model, IIRC all activators should have a model if (activator.mModel.empty()) - messages.push_back (std::make_pair (id, "Model is missing")); // ADD CHECK HERE + messages.push_back (std::make_pair (id, "Model is missing")); + else if (mModels.searchId(activator.mModel) == -1) + messages.push_back (std::make_pair (id, "Model '" + activator.mModel + "' does not exist")); // Check that mentioned scripts exist scriptCheck(activator, messages, id.toString()); @@ -383,9 +386,11 @@ void CSMTools::ReferenceableCheckStage::containerCheck( const ESM::Container& container = (dynamic_cast& >(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Container, container.mId); - //Checking for model, IIRC all containers should have a model + //Checking for model if (container.mModel.empty()) - messages.push_back (std::make_pair (id, "Model is missing")); // ADD CHECK HERE + messages.push_back (std::make_pair (id, "Model is missing")); + else if (mModels.searchId(container.mModel) == -1) + messages.push_back (std::make_pair (id, "Model '" + container.mModel + "' does not exist")); //Checking for capacity (weight) if (container.mWeight < 0) //0 is allowed @@ -416,7 +421,9 @@ void CSMTools::ReferenceableCheckStage::creatureCheck ( CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Creature, creature.mId); if (creature.mModel.empty()) - messages.push_back (std::make_pair (id, "Model is missing")); // ADD CHECK HERE + messages.push_back (std::make_pair (id, "Model is missing")); + else if (mModels.searchId(creature.mModel) == -1) + messages.push_back (std::make_pair (id, "Model '" + creature.mModel + "' does not exist")); if (creature.mName.empty()) messages.push_back (std::make_pair (id, "Name is missing")); @@ -496,7 +503,9 @@ void CSMTools::ReferenceableCheckStage::doorCheck( messages.push_back (std::make_pair (id, "Name is missing")); if (door.mModel.empty()) - messages.push_back (std::make_pair (id, "Model is missing")); // ADD CHECK HERE + messages.push_back (std::make_pair (id, "Model is missing")); + else if (mModels.searchId(door.mModel) == -1) + messages.push_back (std::make_pair (id, "Model '" + door.mModel + "' does not exist")); // Check that mentioned scripts exist scriptCheck(door, messages, id.toString()); @@ -729,8 +738,6 @@ void CSMTools::ReferenceableCheckStage::npcCheck ( if (npc.mHair.empty()) messages.push_back (std::make_pair (id, "Hair is missing")); // ADD CHECK HERE - //TODO: reputation, Disposition, rank, everything else - // Check inventory inventoryListCheck(npc.mInventory.mList, messages, id.toString()); @@ -871,6 +878,8 @@ void CSMTools::ReferenceableCheckStage::staticCheck ( if (staticElement.mModel.empty()) messages.push_back (std::make_pair (id, "Model is missing")); + else if (mModels.searchId(staticElement.mModel) == -1) + messages.push_back (std::make_pair (id, "Model '" + staticElement.mModel + "' does not exist")); } //final check @@ -890,7 +899,7 @@ void CSMTools::ReferenceableCheckStage::inventoryListCheck( for (size_t i = 0; i < itemList.size(); ++i) { std::string itemName = itemList[i].mItem.toString(); - CSMWorld::RefIdData::LocalIndex localIndex = mReferencables.searchId(itemName); + CSMWorld::RefIdData::LocalIndex localIndex = mObjects.searchId(itemName); if (localIndex.first == -1) messages.push_back (std::make_pair (id, "Item '" + itemName + "' does not exist")); @@ -938,7 +947,9 @@ template void CSMTools::ReferenceableCheckStage::inventoryItemChe //checking for model if (someItem.mModel.empty()) - messages.push_back (std::make_pair (someID, "Model is missing")); // ADD CHECK HERE + messages.push_back (std::make_pair (someID, "Model is missing")); + else if (mModels.searchId(someItem.mModel) == -1) + messages.push_back(std::make_pair(someID, "Model '" + someItem.mModel + "' does not exist")); //checking for icon if (someItem.mIcon.empty()) @@ -964,7 +975,9 @@ template void CSMTools::ReferenceableCheckStage::inventoryItemChe //checking for model if (someItem.mModel.empty()) - messages.push_back (std::make_pair (someID, "Model is missing")); // ADD CHECK HERE + messages.push_back (std::make_pair (someID, "Model is missing")); + else if (mModels.searchId(someItem.mModel) == -1) + messages.push_back (std::make_pair (someID, "Model '" + someItem.mModel + "' does not exist")); //checking for icon if (someItem.mIcon.empty()) @@ -993,7 +1006,7 @@ template void CSMTools::ReferenceableCheckStage::listCheck ( { for (unsigned i = 0; i < someList.mList.size(); ++i) { - if (mReferencables.searchId(someList.mList[i].mId).first == -1) + if (mObjects.searchId(someList.mList[i].mId).first == -1) messages.push_back (std::make_pair (someID, "Object '" + someList.mList[i].mId + "' does not exist")); if (someList.mList[i].mLevel < 1) diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index f9341bd9c..24f73176c 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -5,6 +5,7 @@ #include "../doc/stage.hpp" #include "../world/data.hpp" #include "../world/refiddata.hpp" +#include "../world/resources.hpp" namespace CSMTools { @@ -16,7 +17,8 @@ namespace CSMTools const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& classes, const CSMWorld::IdCollection& factions, - const CSMWorld::IdCollection& scripts); + const CSMWorld::IdCollection& scripts, + const CSMWorld::Resources& models); virtual void perform(int stage, CSMDoc::Messages& messages); virtual int setup(); @@ -76,11 +78,12 @@ namespace CSMTools CSMDoc::Messages& messages, const std::string& someID); - const CSMWorld::RefIdData& mReferencables; + const CSMWorld::RefIdData& mObjects; const CSMWorld::IdCollection& mRaces; const CSMWorld::IdCollection& mClasses; const CSMWorld::IdCollection& mFactions; const CSMWorld::IdCollection& mScripts; + const CSMWorld::Resources& mModels; bool mPlayerPresent; bool mIgnoreBaseRecords; }; diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index dfa2ae202..2e471d66f 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -82,7 +82,8 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier() mVerifierOperation->appendStage (new SpellCheckStage (mData.getSpells())); - mVerifierOperation->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions(), mData.getScripts())); + mVerifierOperation->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions(), mData.getScripts(), + mData.getResources (CSMWorld::UniversalId::Type_Meshes))); mVerifierOperation->appendStage (new ReferenceCheckStage(mData.getReferences(), mData.getReferenceables(), mData.getCells(), mData.getFactions())); From 34077a6987939791ffd5f62552eaf6b28194f781 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 25 Aug 2018 01:27:10 +0300 Subject: [PATCH 13/35] Purge unnecessary namespaces --- apps/opencs/model/tools/birthsigncheck.cpp | 1 - apps/opencs/model/tools/birthsigncheck.hpp | 6 +----- apps/opencs/model/tools/magiceffectcheck.cpp | 1 - apps/opencs/model/tools/magiceffectcheck.hpp | 6 +----- 4 files changed, 2 insertions(+), 12 deletions(-) diff --git a/apps/opencs/model/tools/birthsigncheck.cpp b/apps/opencs/model/tools/birthsigncheck.cpp index 4ef264f65..b61bf7421 100644 --- a/apps/opencs/model/tools/birthsigncheck.cpp +++ b/apps/opencs/model/tools/birthsigncheck.cpp @@ -9,7 +9,6 @@ #include "../prefs/state.hpp" #include "../world/data.hpp" -#include "../world/resources.hpp" #include "../world/universalid.hpp" namespace diff --git a/apps/opencs/model/tools/birthsigncheck.hpp b/apps/opencs/model/tools/birthsigncheck.hpp index cd22fb6d0..d032d3cef 100644 --- a/apps/opencs/model/tools/birthsigncheck.hpp +++ b/apps/opencs/model/tools/birthsigncheck.hpp @@ -4,14 +4,10 @@ #include #include "../world/idcollection.hpp" +#include "../world/resources.hpp" #include "../doc/stage.hpp" -namespace CSMWorld -{ - class Resources; -} - namespace CSMTools { /// \brief VerifyStage: make sure that birthsign records are internally consistent diff --git a/apps/opencs/model/tools/magiceffectcheck.cpp b/apps/opencs/model/tools/magiceffectcheck.cpp index 7e7a09aa5..77a26c596 100644 --- a/apps/opencs/model/tools/magiceffectcheck.cpp +++ b/apps/opencs/model/tools/magiceffectcheck.cpp @@ -4,7 +4,6 @@ #include "../prefs/state.hpp" -#include "../world/resources.hpp" #include "../world/data.hpp" namespace diff --git a/apps/opencs/model/tools/magiceffectcheck.hpp b/apps/opencs/model/tools/magiceffectcheck.hpp index 3e45495c1..22dad3db9 100644 --- a/apps/opencs/model/tools/magiceffectcheck.hpp +++ b/apps/opencs/model/tools/magiceffectcheck.hpp @@ -6,14 +6,10 @@ #include "../world/idcollection.hpp" #include "../world/refidcollection.hpp" +#include "../world/resources.hpp" #include "../doc/stage.hpp" -namespace CSMWorld -{ - class Resources; -} - namespace CSMTools { /// \brief VerifyStage: make sure that magic effect records are internally consistent From dc847dce09aeddbe7df925d305dc96969220538d Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 25 Aug 2018 01:44:46 +0300 Subject: [PATCH 14/35] Add item icon checks to object record verifier --- .../opencs/model/tools/referenceablecheck.cpp | 21 ++++++++++++++++--- .../opencs/model/tools/referenceablecheck.hpp | 4 +++- apps/opencs/model/tools/tools.cpp | 2 +- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 8a1103c3d..d3901ac88 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -1,6 +1,7 @@ #include "referenceablecheck.hpp" #include +#include #include "../prefs/state.hpp" @@ -12,13 +13,15 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( const CSMWorld::IdCollection& classes, const CSMWorld::IdCollection& faction, const CSMWorld::IdCollection& scripts, - const CSMWorld::Resources& models) + const CSMWorld::Resources& models, + const CSMWorld::Resources& icons) :mObjects(referenceable), mRaces(races), mClasses(classes), mFactions(faction), mScripts(scripts), mModels(models), + mIcons(icons), mPlayerPresent(false) { mIgnoreBaseRecords = false; @@ -953,7 +956,13 @@ template void CSMTools::ReferenceableCheckStage::inventoryItemChe //checking for icon if (someItem.mIcon.empty()) - messages.push_back (std::make_pair (someID, "Icon is missing")); // ADD CHECK HERE + messages.push_back (std::make_pair (someID, "Icon is missing")); + else if (mIcons.searchId(someItem.mIcon) == -1) + { + std::string ddsIcon = someItem.mIcon; + if (!(Misc::ResourceHelpers::changeExtensionToDds(ddsIcon) && mIcons.searchId(ddsIcon) != -1)) + messages.push_back(std::make_pair(someID, "Icon '" + someItem.mIcon + "' does not exist")); + } if (enchantable && someItem.mData.mEnchant < 0) messages.push_back (std::make_pair (someID, "Enchantment points number is negative")); @@ -981,7 +990,13 @@ template void CSMTools::ReferenceableCheckStage::inventoryItemChe //checking for icon if (someItem.mIcon.empty()) - messages.push_back (std::make_pair (someID, "Icon is missing")); // ADD CHECK HERE + messages.push_back (std::make_pair (someID, "Icon is missing")); + else if (mIcons.searchId(someItem.mIcon) == -1) + { + std::string ddsIcon = someItem.mIcon; + if (!(Misc::ResourceHelpers::changeExtensionToDds(ddsIcon) && mIcons.searchId(ddsIcon) != -1)) + messages.push_back(std::make_pair(someID, "Icon '" + someItem.mIcon + "' does not exist")); + } } template void CSMTools::ReferenceableCheckStage::toolCheck ( diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 24f73176c..5da737875 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -18,7 +18,8 @@ namespace CSMTools const CSMWorld::IdCollection& classes, const CSMWorld::IdCollection& factions, const CSMWorld::IdCollection& scripts, - const CSMWorld::Resources& models); + const CSMWorld::Resources& models, + const CSMWorld::Resources& icons); virtual void perform(int stage, CSMDoc::Messages& messages); virtual int setup(); @@ -84,6 +85,7 @@ namespace CSMTools const CSMWorld::IdCollection& mFactions; const CSMWorld::IdCollection& mScripts; const CSMWorld::Resources& mModels; + const CSMWorld::Resources& mIcons; bool mPlayerPresent; bool mIgnoreBaseRecords; }; diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index 2e471d66f..87b5041e0 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -83,7 +83,7 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier() mVerifierOperation->appendStage (new SpellCheckStage (mData.getSpells())); mVerifierOperation->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions(), mData.getScripts(), - mData.getResources (CSMWorld::UniversalId::Type_Meshes))); + mData.getResources (CSMWorld::UniversalId::Type_Meshes), mData.getResources (CSMWorld::UniversalId::Type_Icons))); mVerifierOperation->appendStage (new ReferenceCheckStage(mData.getReferences(), mData.getReferenceables(), mData.getCells(), mData.getFactions())); From 5b8880c6fa24b65f6899a9141a0f64fd991368e9 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 25 Aug 2018 02:03:55 +0300 Subject: [PATCH 15/35] Update cell reference record verifier messages --- apps/opencs/model/tools/referencecheck.cpp | 42 +++++++++++----------- apps/opencs/model/tools/referencecheck.hpp | 2 +- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/apps/opencs/model/tools/referencecheck.cpp b/apps/opencs/model/tools/referencecheck.cpp index 447238be4..dd93b4e9c 100644 --- a/apps/opencs/model/tools/referencecheck.cpp +++ b/apps/opencs/model/tools/referencecheck.cpp @@ -9,7 +9,7 @@ CSMTools::ReferenceCheckStage::ReferenceCheckStage( const CSMWorld::IdCollection& factions) : mReferences(references), - mReferencables(referencables), + mObjects(referencables), mDataSet(referencables.getDataSet()), mCells(cells), mFactions(factions) @@ -30,75 +30,73 @@ void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages &message // Check for empty reference id if (cellRef.mRefID.empty()) { - messages.push_back(std::make_pair(id, " is an empty instance (not based on an object)")); + messages.push_back(std::make_pair(id, "Instance is not based on an object")); } else { // Check for non existing referenced object - if (mReferencables.searchId(cellRef.mRefID) == -1) { - messages.push_back(std::make_pair(id, " is referencing non existing object " + cellRef.mRefID)); + if (mObjects.searchId(cellRef.mRefID) == -1) { + messages.push_back(std::make_pair(id, "Instance of a non-existent object '" + cellRef.mRefID + "'")); } else { // Check if reference charge is valid for it's proper referenced type CSMWorld::RefIdData::LocalIndex localIndex = mDataSet.searchId(cellRef.mRefID); bool isLight = localIndex.second == CSMWorld::UniversalId::Type_Light; if ((isLight && cellRef.mChargeFloat < -1) || (!isLight && cellRef.mChargeInt < -1)) { - std::string str = " has invalid charge "; + std::string str = "Invalid charge: "; if (localIndex.second == CSMWorld::UniversalId::Type_Light) str += std::to_string(cellRef.mChargeFloat); else str += std::to_string(cellRef.mChargeInt); - messages.push_back(std::make_pair(id, id.getId() + str)); + messages.push_back(std::make_pair(id, str)); } } } // If object have owner, check if that owner reference is valid - if (!cellRef.mOwner.empty() && mReferencables.searchId(cellRef.mOwner) == -1) - messages.push_back(std::make_pair(id, " has non existing owner " + cellRef.mOwner)); + if (!cellRef.mOwner.empty() && mObjects.searchId(cellRef.mOwner) == -1) + messages.push_back(std::make_pair(id, "Owner object '" + cellRef.mOwner + "' does not exist")); // If object have creature soul trapped, check if that creature reference is valid if (!cellRef.mSoul.empty()) - if (mReferencables.searchId(cellRef.mSoul) == -1) - messages.push_back(std::make_pair(id, " has non existing trapped soul " + cellRef.mSoul)); + if (mObjects.searchId(cellRef.mSoul) == -1) + messages.push_back(std::make_pair(id, "Trapped soul object '" + cellRef.mSoul + "' does not exist")); bool hasFaction = !cellRef.mFaction.empty(); // If object have faction, check if that faction reference is valid if (hasFaction) if (mFactions.searchId(cellRef.mFaction) == -1) - messages.push_back(std::make_pair(id, " has non existing faction " + cellRef.mFaction)); + messages.push_back(std::make_pair(id, "Faction '" + cellRef.mFaction + "' does not exist")); // Check item's faction rank - if (hasFaction && cellRef.mFactionRank < -1) - messages.push_back(std::make_pair(id, " has faction set but has invalid faction rank " + std::to_string(cellRef.mFactionRank))); - else if (!hasFaction && cellRef.mFactionRank != -2) - messages.push_back(std::make_pair(id, " has invalid faction rank " + std::to_string(cellRef.mFactionRank))); + if ((hasFaction && cellRef.mFactionRank < -1) || (!hasFaction && cellRef.mFactionRank != -2)) + messages.push_back(std::make_pair(id, "Invalid faction rank " + std::to_string(cellRef.mFactionRank))); // If door have destination cell, check if that reference is valid if (!cellRef.mDestCell.empty()) if (mCells.searchId(cellRef.mDestCell) == -1) - messages.push_back(std::make_pair(id, " has non existing destination cell " + cellRef.mDestCell)); + messages.push_back(std::make_pair(id, "Destination cell '" + cellRef.mDestCell + "' does not exist")); // Check if scale isn't negative if (cellRef.mScale < 0) { - std::string str = " has negative scale "; + std::string str = "Negative scale: "; str += std::to_string(cellRef.mScale); - messages.push_back(std::make_pair(id, id.getId() + str)); + messages.push_back(std::make_pair(id, str)); } // Check if enchantement points aren't negative or are at full (-1) if (cellRef.mEnchantmentCharge < 0 && cellRef.mEnchantmentCharge != -1) { - std::string str = " has negative enchantment points "; + std::string str = "Negative enchantment points: "; str += std::to_string(cellRef.mEnchantmentCharge); - messages.push_back(std::make_pair(id, id.getId() + str)); + messages.push_back(std::make_pair(id, str)); } // Check if gold value isn't negative if (cellRef.mGoldValue < 0) { - std::string str = " has negative gold value "; + std::string str = "Negative gold value: "; str += cellRef.mGoldValue; - messages.push_back(std::make_pair(id, id.getId() + str)); + messages.push_back(std::make_pair(id, str)); } } diff --git a/apps/opencs/model/tools/referencecheck.hpp b/apps/opencs/model/tools/referencecheck.hpp index 5e25924f3..7373903e6 100644 --- a/apps/opencs/model/tools/referencecheck.hpp +++ b/apps/opencs/model/tools/referencecheck.hpp @@ -19,7 +19,7 @@ namespace CSMTools private: const CSMWorld::RefCollection& mReferences; - const CSMWorld::RefIdCollection& mReferencables; + const CSMWorld::RefIdCollection& mObjects; const CSMWorld::RefIdData& mDataSet; const CSMWorld::IdCollection& mCells; const CSMWorld::IdCollection& mFactions; From 6b226eef8f53d06dfdb9bb0817614ee4db35077b Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 25 Aug 2018 02:38:02 +0300 Subject: [PATCH 16/35] Use Messages::add in magic effect record verifier --- apps/opencs/model/tools/magiceffectcheck.cpp | 128 ++++++++++++------- 1 file changed, 81 insertions(+), 47 deletions(-) diff --git a/apps/opencs/model/tools/magiceffectcheck.cpp b/apps/opencs/model/tools/magiceffectcheck.cpp index 77a26c596..917e358c3 100644 --- a/apps/opencs/model/tools/magiceffectcheck.cpp +++ b/apps/opencs/model/tools/magiceffectcheck.cpp @@ -4,23 +4,8 @@ #include "../prefs/state.hpp" -#include "../world/data.hpp" - -namespace -{ - void addMessage(CSMDoc::Messages &messages, const CSMWorld::UniversalId &id, const std::string& text) - { - if (!text.empty()) - { - messages.push_back(std::make_pair(id, text)); - } - } -} - std::string CSMTools::MagicEffectCheckStage::checkTexture(const std::string &texture, bool isIcon) const { - if (texture.empty()) return (isIcon ? "Icon is missing" : std::string()); - const CSMWorld::Resources &textures = isIcon ? mIcons : mTextures; if (textures.searchId(texture) != -1) return std::string(); @@ -34,30 +19,16 @@ std::string CSMTools::MagicEffectCheckStage::checkObject(const std::string &id, const CSMWorld::UniversalId &type, const std::string &column) const { - std::string error; - if (!id.empty()) - { - CSMWorld::RefIdData::LocalIndex index = mObjects.getDataSet().searchId(id); - if (index.first == -1) - { - error = column + " '" + id + "' " + "does not exist"; - } - else if (index.second != type.getType()) - { - error = column + " '" + id + "' " + "does not have " + type.getTypeName() + " type"; - } - } - return error; + CSMWorld::RefIdData::LocalIndex index = mObjects.getDataSet().searchId(id); + if (index.first == -1) return (column + " '" + id + "' " + "does not exist"); + else if (index.second != type.getType()) return (column + " '" + id + "' " + "does not have " + type.getTypeName() + " type"); + return std::string(); } std::string CSMTools::MagicEffectCheckStage::checkSound(const std::string &id, const std::string &column) const { - std::string error; - if (!id.empty() && mSounds.searchId(id) == -1) - { - error = column + " '" + id + "' " + "does not exist"; - } - return error; + if (!id.empty() && mSounds.searchId(id) == -1) return (column + " '" + id + "' " + "does not exist"); + return std::string(); } CSMTools::MagicEffectCheckStage::MagicEffectCheckStage(const CSMWorld::IdCollection &effects, @@ -94,22 +65,85 @@ void CSMTools::MagicEffectCheckStage::perform(int stage, CSMDoc::Messages &messa if (effect.mDescription.empty()) { - addMessage(messages, id, "Description is missing"); + messages.add(id, "Description is missing", "", CSMDoc::Message::Severity_Warning); } if (effect.mData.mBaseCost < 0.0f) { - addMessage(messages, id, "Base cost is negative"); + messages.add(id, "Base cost is negative", "", CSMDoc::Message::Severity_Error); + } + + if (effect.mIcon.empty()) + { + messages.add(id, "Icon is missing", "", CSMDoc::Message::Severity_Error); + } + else + { + const std::string error = checkTexture(effect.mIcon, true); + if (!error.empty()) + messages.add(id, error, "", CSMDoc::Message::Severity_Error); + } + + if (!effect.mParticle.empty()) + { + const std::string error = checkTexture(effect.mParticle, false); + if (!error.empty()) + messages.add(id, error, "", CSMDoc::Message::Severity_Error); + } + + if (!effect.mCasting.empty()) + { + const std::string error = checkObject(effect.mCasting, CSMWorld::UniversalId::Type_Static, "Casting object"); + if (!error.empty()) + messages.add(id, error, "", CSMDoc::Message::Severity_Error); + } + + if (!effect.mHit.empty()) + { + const std::string error = checkObject(effect.mHit, CSMWorld::UniversalId::Type_Static, "Hit object"); + if (!error.empty()) + messages.add(id, error, "", CSMDoc::Message::Severity_Error); } - addMessage(messages, id, checkTexture(effect.mIcon, true)); - addMessage(messages, id, checkTexture(effect.mParticle, false)); - addMessage(messages, id, checkObject(effect.mCasting, CSMWorld::UniversalId::Type_Static, "Casting object")); - addMessage(messages, id, checkObject(effect.mHit, CSMWorld::UniversalId::Type_Static, "Hit object")); - addMessage(messages, id, checkObject(effect.mArea, CSMWorld::UniversalId::Type_Static, "Area object")); - addMessage(messages, id, checkObject(effect.mBolt, CSMWorld::UniversalId::Type_Weapon, "Bolt object")); - addMessage(messages, id, checkSound(effect.mCastSound, "Casting sound")); - addMessage(messages, id, checkSound(effect.mHitSound, "Hit sound")); - addMessage(messages, id, checkSound(effect.mAreaSound, "Area sound")); - addMessage(messages, id, checkSound(effect.mBoltSound, "Bolt sound")); + if (!effect.mArea.empty()) + { + const std::string error = checkObject(effect.mArea, CSMWorld::UniversalId::Type_Static, "Area object"); + if (!error.empty()) + messages.add(id, error, "", CSMDoc::Message::Severity_Error); + } + + if (!effect.mBolt.empty()) + { + const std::string error = checkObject(effect.mBolt, CSMWorld::UniversalId::Type_Static, "Bolt object"); + if (!error.empty()) + messages.add(id, error, "", CSMDoc::Message::Severity_Error); + } + + if (!effect.mCastSound.empty()) + { + const std::string error = checkSound(effect.mCastSound, "Casting sound"); + if (!error.empty()) + messages.add(id, error, "", CSMDoc::Message::Severity_Error); + } + + if (!effect.mHitSound.empty()) + { + const std::string error = checkSound(effect.mHitSound, "Hit sound"); + if (!error.empty()) + messages.add(id, error, "", CSMDoc::Message::Severity_Error); + } + + if (!effect.mAreaSound.empty()) + { + const std::string error = checkSound(effect.mAreaSound, "Area sound"); + if (!error.empty()) + messages.add(id, error, "", CSMDoc::Message::Severity_Error); + } + + if (!effect.mBoltSound.empty()) + { + const std::string error = checkSound(effect.mBoltSound, "Bolt sound"); + if (!error.empty()) + messages.add(id, error, "", CSMDoc::Message::Severity_Error); + } } From d433929194578c477343df7a09183b5ed83dde20 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 25 Aug 2018 02:48:58 +0300 Subject: [PATCH 17/35] Use Messages::add in birthsign record verifier --- apps/opencs/model/tools/birthsigncheck.cpp | 37 ++++++++++------------ 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/apps/opencs/model/tools/birthsigncheck.cpp b/apps/opencs/model/tools/birthsigncheck.cpp index b61bf7421..c582da8e4 100644 --- a/apps/opencs/model/tools/birthsigncheck.cpp +++ b/apps/opencs/model/tools/birthsigncheck.cpp @@ -1,37 +1,21 @@ #include "birthsigncheck.hpp" -#include -#include - #include #include #include "../prefs/state.hpp" -#include "../world/data.hpp" #include "../world/universalid.hpp" -namespace -{ - void addMessage(CSMDoc::Messages &messages, const CSMWorld::UniversalId &id, const std::string& text) - { - if (!text.empty()) - { - messages.push_back(std::make_pair(id, text)); - } - } -} - std::string CSMTools::BirthsignCheckStage::checkTexture(const std::string &texture) const { - if (texture.empty()) return "Texture is missing"; if (mTextures.searchId(texture) != -1) return std::string(); std::string ddsTexture = texture; if (Misc::ResourceHelpers::changeExtensionToDds(ddsTexture) && mTextures.searchId(ddsTexture) != -1) return std::string(); - return "Texture '" + texture + "' does not exist"; + return "Image '" + texture + "' does not exist"; } CSMTools::BirthsignCheckStage::BirthsignCheckStage (const CSMWorld::IdCollection& birthsigns, @@ -62,12 +46,25 @@ void CSMTools::BirthsignCheckStage::perform (int stage, CSMDoc::Messages& messag CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Birthsign, birthsign.mId); if (birthsign.mName.empty()) - addMessage(messages, id, "Name is missing"); + { + messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); + } if (birthsign.mDescription.empty()) - addMessage(messages, id, "Description is missing"); + { + messages.add(id, "Description is missing", "", CSMDoc::Message::Severity_Warning); + } - addMessage(messages, id, checkTexture(birthsign.mTexture)); + if (birthsign.mTexture.empty()) + { + messages.add(id, "Image is missing", "", CSMDoc::Message::Severity_Error); + } + else + { + const std::string error = checkTexture(birthsign.mTexture); + if (!error.empty()) + messages.add(id, error, "", CSMDoc::Message::Severity_Error); + } /// \todo check data members that can't be edited in the table view } From 8dcb58d745839d87272446cb318565cc08756484 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 25 Aug 2018 03:49:10 +0300 Subject: [PATCH 18/35] Use Messages::add in Faction, Sound, Bodypart and Class record verifiers --- apps/opencs/model/tools/bodypartcheck.cpp | 15 +++++++-------- apps/opencs/model/tools/classcheck.cpp | 19 +++++++++---------- apps/opencs/model/tools/factioncheck.cpp | 6 +++--- apps/opencs/model/tools/soundcheck.cpp | 11 +++++------ 4 files changed, 24 insertions(+), 27 deletions(-) diff --git a/apps/opencs/model/tools/bodypartcheck.cpp b/apps/opencs/model/tools/bodypartcheck.cpp index d33705cf6..16dd9891e 100644 --- a/apps/opencs/model/tools/bodypartcheck.cpp +++ b/apps/opencs/model/tools/bodypartcheck.cpp @@ -34,24 +34,23 @@ void CSMTools::BodyPartCheckStage::perform (int stage, CSMDoc::Messages &message // Check BYDT if (bodyPart.mData.mPart > 14 ) - messages.push_back(std::make_pair(id, "Invalid mesh part")); + messages.add(id, "Invalid part", "", CSMDoc::Message::Severity_Error); if (bodyPart.mData.mFlags > 3 ) - messages.push_back(std::make_pair(id, "Invalid flags")); + messages.add(id, "Invalid flags", "", CSMDoc::Message::Severity_Error); if (bodyPart.mData.mType > 2 ) - messages.push_back(std::make_pair(id, "Invalid type")); + messages.add(id, "Invalid type", "", CSMDoc::Message::Severity_Error); // Check MODL - if ( bodyPart.mModel.empty() ) - messages.push_back(std::make_pair(id, "Model is missing" )); + messages.add(id, "Model is missing", "", CSMDoc::Message::Severity_Error); else if ( mMeshes.searchId( bodyPart.mModel ) == -1 ) - messages.push_back(std::make_pair(id, "Model '" + bodyPart.mModel + "' does not exist")); + messages.add(id, "Model '" + bodyPart.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error); // Check FNAM if ( bodyPart.mRace.empty() ) - messages.push_back(std::make_pair(id, "Race is missing" )); + messages.add(id, "Race is missing", "", CSMDoc::Message::Severity_Error); else if ( mRaces.searchId( bodyPart.mRace ) == -1 ) - messages.push_back(std::make_pair(id, "Race '" + bodyPart.mRace + " does not exist")); + messages.add(id, "Race '" + bodyPart.mRace + " does not exist", "", CSMDoc::Message::Severity_Error); } diff --git a/apps/opencs/model/tools/classcheck.cpp b/apps/opencs/model/tools/classcheck.cpp index 157dfab7f..b409c4e06 100644 --- a/apps/opencs/model/tools/classcheck.cpp +++ b/apps/opencs/model/tools/classcheck.cpp @@ -1,6 +1,5 @@ #include "classcheck.hpp" -#include #include #include @@ -37,26 +36,24 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages) // A class should have a name if (class_.mName.empty()) - messages.push_back (std::make_pair (id, "Name is missing")); + messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Warning); // A playable class should have a description if (class_.mData.mIsPlayable != 0 && class_.mDescription.empty()) - messages.push_back (std::make_pair (id, "Description of a playable class is missing")); + messages.add(id, "Description of a playable class is missing", "", CSMDoc::Message::Severity_Warning); // test for invalid attributes for (int i=0; i<2; ++i) + { if (class_.mData.mAttribute[i]==-1) { - std::ostringstream stream; - - stream << "Attribute #" << i << " is not set"; - - messages.push_back (std::make_pair (id, stream.str())); + messages.add(id, "Attribute #" + std::to_string(i) + " is not set", "", CSMDoc::Message::Severity_Error); } + } if (class_.mData.mAttribute[0]==class_.mData.mAttribute[1] && class_.mData.mAttribute[0]!=-1) { - messages.push_back (std::make_pair (id, "Same attribute is listed twice")); + messages.add(id, "Same attribute is listed twice", "", CSMDoc::Message::Severity_Warning); } // test for non-unique skill @@ -67,8 +64,10 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages) ++skills[class_.mData.mSkills[i][i2]]; for (auto &skill : skills) + { if (skill.second>1) { - messages.push_back (std::make_pair (id, "Skill " + ESM::Skill::indexToId (skill.first) + " is listed more than once")); + messages.add(id, "Skill " + ESM::Skill::indexToId (skill.first) + " is listed more than once", "", CSMDoc::Message::Severity_Warning); } + } } diff --git a/apps/opencs/model/tools/factioncheck.cpp b/apps/opencs/model/tools/factioncheck.cpp index d19c0ae52..5bd613851 100644 --- a/apps/opencs/model/tools/factioncheck.cpp +++ b/apps/opencs/model/tools/factioncheck.cpp @@ -37,12 +37,12 @@ void CSMTools::FactionCheckStage::perform (int stage, CSMDoc::Messages& messages // test for empty name if (faction.mName.empty()) - messages.push_back (std::make_pair (id, "Name is missing")); + messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Warning); // test for invalid attributes if (faction.mData.mAttribute[0]==faction.mData.mAttribute[1] && faction.mData.mAttribute[0]!=-1) { - messages.push_back (std::make_pair (id, "Same attribute is listed twice")); + messages.add(id, "Same attribute is listed twice", "", CSMDoc::Message::Severity_Warning); } // test for non-unique skill @@ -55,7 +55,7 @@ void CSMTools::FactionCheckStage::perform (int stage, CSMDoc::Messages& messages for (auto &skill : skills) if (skill.second>1) { - messages.push_back (std::make_pair (id, "Skill " + ESM::Skill::indexToId (skill.first) + " is listed more than once")); + messages.add(id, "Skill " + ESM::Skill::indexToId (skill.first) + " is listed more than once", "", CSMDoc::Message::Severity_Warning); } /// \todo check data members that can't be edited in the table view diff --git a/apps/opencs/model/tools/soundcheck.cpp b/apps/opencs/model/tools/soundcheck.cpp index 5708a59d3..7bb27e984 100644 --- a/apps/opencs/model/tools/soundcheck.cpp +++ b/apps/opencs/model/tools/soundcheck.cpp @@ -1,12 +1,9 @@ #include "soundcheck.hpp" -#include - #include #include "../prefs/state.hpp" -#include "../world/data.hpp" #include "../world/resources.hpp" #include "../world/universalid.hpp" @@ -38,14 +35,16 @@ void CSMTools::SoundCheckStage::perform (int stage, CSMDoc::Messages& messages) CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Sound, sound.mId); if (sound.mData.mMinRange>sound.mData.mMaxRange) - messages.push_back (std::make_pair (id, "Minimum range larger than maximum range")); + { + messages.add(id, "Minimum range larger than maximum range", "", CSMDoc::Message::Severity_Warning); + } if (sound.mSound.empty()) { - messages.push_back(std::make_pair(id, "Sound file is missing")); + messages.add(id, "Sound file is missing", "", CSMDoc::Message::Severity_Error); } else if (mSoundFiles.searchId(sound.mSound) == -1) { - messages.push_back(std::make_pair(id, "Sound file '" + sound.mSound + "' does not exist")); + messages.add(id, "Sound file '" + sound.mSound + "' does not exist", "", CSMDoc::Message::Severity_Error); } } From b2b9bd94f09b817a20ac9cae3b54e7f174bd4f6d Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 25 Aug 2018 04:05:48 +0300 Subject: [PATCH 19/35] Fix bolt object type --- apps/opencs/model/tools/magiceffectcheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/magiceffectcheck.cpp b/apps/opencs/model/tools/magiceffectcheck.cpp index 917e358c3..943d89cdc 100644 --- a/apps/opencs/model/tools/magiceffectcheck.cpp +++ b/apps/opencs/model/tools/magiceffectcheck.cpp @@ -114,7 +114,7 @@ void CSMTools::MagicEffectCheckStage::perform(int stage, CSMDoc::Messages &messa if (!effect.mBolt.empty()) { - const std::string error = checkObject(effect.mBolt, CSMWorld::UniversalId::Type_Static, "Bolt object"); + const std::string error = checkObject(effect.mBolt, CSMWorld::UniversalId::Type_Weapon, "Bolt object"); if (!error.empty()) messages.add(id, error, "", CSMDoc::Message::Severity_Error); } From 35281d7c3844b9c3b1af100fd7317d8ca9eebc78 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 25 Aug 2018 05:04:49 +0300 Subject: [PATCH 20/35] Use Messages::add in race, soundgen, spell and start script record verifiers --- apps/opencs/model/tools/racecheck.cpp | 18 ++++++++++-------- apps/opencs/model/tools/soundgencheck.cpp | 8 ++++---- apps/opencs/model/tools/spellcheck.cpp | 6 +++--- apps/opencs/model/tools/startscriptcheck.cpp | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/apps/opencs/model/tools/racecheck.cpp b/apps/opencs/model/tools/racecheck.cpp index 7ce9a8869..3b487b925 100644 --- a/apps/opencs/model/tools/racecheck.cpp +++ b/apps/opencs/model/tools/racecheck.cpp @@ -28,25 +28,27 @@ void CSMTools::RaceCheckStage::performPerRecord (int stage, CSMDoc::Messages& me CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Race, race.mId); // test for empty name and description - if (race.mName.empty()) - messages.push_back (std::make_pair (id, "Name is missing")); + if (race.mName.empty() && race.mData.mFlags & 0x1) + messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); + else if (race.mName.empty()) + messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Warning); if (race.mDescription.empty()) - messages.push_back (std::make_pair (id, "Description is missing")); + messages.add(id, "Description is missing", "", CSMDoc::Message::Severity_Warning); // test for positive height if (race.mData.mHeight.mMale<=0) - messages.push_back (std::make_pair (id, "Male height is non-positive")); + messages.add(id, "Male height is non-positive", "", CSMDoc::Message::Severity_Error); if (race.mData.mHeight.mFemale<=0) - messages.push_back (std::make_pair (id, "Female height is non-positive")); + messages.add(id, "Female height is non-positive", "", CSMDoc::Message::Severity_Error); // test for non-negative weight if (race.mData.mWeight.mMale<0) - messages.push_back (std::make_pair (id, "Male weight is negative")); + messages.add(id, "Male weight is negative", "", CSMDoc::Message::Severity_Error); if (race.mData.mWeight.mFemale<0) - messages.push_back (std::make_pair (id, "Female weight is negative")); + messages.add(id, "Female weight is negative", "", CSMDoc::Message::Severity_Error); /// \todo check data members that can't be edited in the table view } @@ -56,7 +58,7 @@ void CSMTools::RaceCheckStage::performFinal (CSMDoc::Messages& messages) CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Races); if (!mPlayable) - messages.push_back (std::make_pair (id, "No playable race")); + messages.add(id, "No playable race", "", CSMDoc::Message::Severity_SeriousError); } CSMTools::RaceCheckStage::RaceCheckStage (const CSMWorld::IdCollection& races) diff --git a/apps/opencs/model/tools/soundgencheck.cpp b/apps/opencs/model/tools/soundgencheck.cpp index 99a8c184c..7b6cf7a4b 100644 --- a/apps/opencs/model/tools/soundgencheck.cpp +++ b/apps/opencs/model/tools/soundgencheck.cpp @@ -40,20 +40,20 @@ void CSMTools::SoundGenCheckStage::perform(int stage, CSMDoc::Messages &messages CSMWorld::RefIdData::LocalIndex creatureIndex = mObjects.getDataSet().searchId(soundGen.mCreature); if (creatureIndex.first == -1) { - messages.push_back(std::make_pair(id, "Creature '" + soundGen.mCreature + "' doesn't exist")); + messages.add(id, "Creature '" + soundGen.mCreature + "' doesn't exist", "", CSMDoc::Message::Severity_Error); } else if (creatureIndex.second != CSMWorld::UniversalId::Type_Creature) { - messages.push_back(std::make_pair(id, "'" + soundGen.mCreature + "' is not a creature")); + messages.add(id, "'" + soundGen.mCreature + "' is not a creature", "", CSMDoc::Message::Severity_Error); } } if (soundGen.mSound.empty()) { - messages.push_back(std::make_pair(id, "Sound is missing")); + messages.add(id, "Sound is missing", "", CSMDoc::Message::Severity_Error); } else if (mSounds.searchId(soundGen.mSound) == -1) { - messages.push_back(std::make_pair(id, "Sound '" + soundGen.mSound + "' doesn't exist")); + messages.add(id, "Sound '" + soundGen.mSound + "' doesn't exist", "", CSMDoc::Message::Severity_Error); } } diff --git a/apps/opencs/model/tools/spellcheck.cpp b/apps/opencs/model/tools/spellcheck.cpp index 6c08aca37..dc9ce65c0 100644 --- a/apps/opencs/model/tools/spellcheck.cpp +++ b/apps/opencs/model/tools/spellcheck.cpp @@ -34,13 +34,13 @@ void CSMTools::SpellCheckStage::perform (int stage, CSMDoc::Messages& messages) CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Spell, spell.mId); - // test for empty name and description + // test for empty name if (spell.mName.empty()) - messages.push_back (std::make_pair (id, "Name is missing")); + messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); // test for invalid cost values if (spell.mData.mCost<0) - messages.push_back (std::make_pair (id, "Spell cost is negative")); + messages.add(id, "Spell cost is negative", "", CSMDoc::Message::Severity_Error); /// \todo check data members that can't be edited in the table view } diff --git a/apps/opencs/model/tools/startscriptcheck.cpp b/apps/opencs/model/tools/startscriptcheck.cpp index 5a9f63dc4..deb7d384f 100644 --- a/apps/opencs/model/tools/startscriptcheck.cpp +++ b/apps/opencs/model/tools/startscriptcheck.cpp @@ -25,7 +25,7 @@ void CSMTools::StartScriptCheckStage::perform(int stage, CSMDoc::Messages& messa CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_StartScript, scriptId); if (mScripts.searchId (Misc::StringUtils::lowerCase (scriptId))==-1) - messages.push_back (std::make_pair (id, "Start script " + scriptId + " does not exist")); + messages.add(id, "Start script " + scriptId + " does not exist", "", CSMDoc::Message::Severity_Error); } int CSMTools::StartScriptCheckStage::setup() From 1e5330d9da8577df523f7c51c9dda94bc036d27f Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 25 Aug 2018 05:16:49 +0300 Subject: [PATCH 21/35] Use Messages::add in skill record verifier --- apps/opencs/model/tools/skillcheck.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/apps/opencs/model/tools/skillcheck.cpp b/apps/opencs/model/tools/skillcheck.cpp index a2bf3ff03..ab7df51cb 100644 --- a/apps/opencs/model/tools/skillcheck.cpp +++ b/apps/opencs/model/tools/skillcheck.cpp @@ -1,7 +1,5 @@ #include "skillcheck.hpp" -#include - #include #include "../prefs/state.hpp" @@ -33,16 +31,14 @@ void CSMTools::SkillCheckStage::perform (int stage, CSMDoc::Messages& messages) CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Skill, skill.mId); + if (skill.mDescription.empty()) + messages.add(id, "Description is missing", "", CSMDoc::Message::Severity_Warning); + for (int i=0; i<4; ++i) + { if (skill.mData.mUseValue[i]<0) { - std::ostringstream stream; - - stream << "Usage experience value #" << i << " is negative"; - - messages.push_back (std::make_pair (id, stream.str())); + messages.add(id, "Usage experience value #" + std::to_string(i) + " is negative", "", CSMDoc::Message::Severity_Error); } - - if (skill.mDescription.empty()) - messages.push_back (std::make_pair (id, "Description is missing")); + } } From e1ae7a9b0e964154cc0a205ad1bc14364d0f7a27 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 25 Aug 2018 06:40:14 +0300 Subject: [PATCH 22/35] Avoid duplicate duplicate pathgrid point warnings --- apps/opencs/model/tools/pathgridcheck.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/opencs/model/tools/pathgridcheck.cpp b/apps/opencs/model/tools/pathgridcheck.cpp index e63e9122f..88750ad7f 100644 --- a/apps/opencs/model/tools/pathgridcheck.cpp +++ b/apps/opencs/model/tools/pathgridcheck.cpp @@ -100,11 +100,8 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message // check duplicate points // FIXME: how to do this efficiently? - for (unsigned int j = 0; j < pathgrid.mPoints.size(); ++j) + for (unsigned int j = 0; j != i; ++j) { - if (j == i) - continue; - if (pathgrid.mPoints[i].mX == pathgrid.mPoints[j].mX && pathgrid.mPoints[i].mY == pathgrid.mPoints[j].mY && pathgrid.mPoints[i].mZ == pathgrid.mPoints[j].mZ) From 85dc1e4ef2b43953fbade3294acb5a77a6242c28 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 26 Aug 2018 10:45:02 +0300 Subject: [PATCH 23/35] Revert unnecessary universalid changes in Journal record verifier --- apps/opencs/model/tools/journalcheck.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/journalcheck.cpp b/apps/opencs/model/tools/journalcheck.cpp index bd77e95b6..dc15b26ee 100644 --- a/apps/opencs/model/tools/journalcheck.cpp +++ b/apps/opencs/model/tools/journalcheck.cpp @@ -33,7 +33,6 @@ void CSMTools::JournalCheckStage::perform(int stage, CSMDoc::Messages& messages) std::set questIndices; CSMWorld::InfoCollection::Range range = mJournalInfos.getTopicRange(journal.mId); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Journal, journal.mId); for (CSMWorld::InfoCollection::RecordConstIterator it = range.first; it != range.second; ++it) { @@ -57,6 +56,7 @@ void CSMTools::JournalCheckStage::perform(int stage, CSMDoc::Messages& messages) if (journalInfo.mResponse.empty()) { + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_JournalInfo, journalInfo.mId); messages.add(id, "Missing journal entry text", "", CSMDoc::Message::Severity_Warning); } @@ -65,6 +65,7 @@ void CSMTools::JournalCheckStage::perform(int stage, CSMDoc::Messages& messages) // Duplicate index if (result.second == false) { + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_JournalInfo, journalInfo.mId); std::ostringstream stream; stream << "Duplicated quest index " << journalInfo.mData.mJournalIndex; messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); @@ -73,10 +74,12 @@ void CSMTools::JournalCheckStage::perform(int stage, CSMDoc::Messages& messages) if (totalInfoCount == 0) { + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Journal, journal.mId); messages.add(id, "No related journal entry", "", CSMDoc::Message::Severity_Warning); } else if (statusNamedCount > 1) { + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Journal, journal.mId); messages.add(id, "Multiple entries with quest status 'Named'", "", CSMDoc::Message::Severity_Error); } } From d1b2fc11ef58594bacafe48b3191e9bf150f8983 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 26 Aug 2018 13:00:39 +0300 Subject: [PATCH 24/35] Use messages::add in object record verifiers Add NPC head and hair body part existence checks and expand creature record verifier, update playable class checks in class record verifier --- apps/opencs/model/tools/classcheck.cpp | 7 +- .../opencs/model/tools/referenceablecheck.cpp | 259 +++++++++--------- .../opencs/model/tools/referenceablecheck.hpp | 4 +- apps/opencs/model/tools/tools.cpp | 3 +- 4 files changed, 145 insertions(+), 128 deletions(-) diff --git a/apps/opencs/model/tools/classcheck.cpp b/apps/opencs/model/tools/classcheck.cpp index b409c4e06..9984c3287 100644 --- a/apps/opencs/model/tools/classcheck.cpp +++ b/apps/opencs/model/tools/classcheck.cpp @@ -36,7 +36,12 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages) // A class should have a name if (class_.mName.empty()) - messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Warning); + { + if (class_.mData.mIsPlayable != 0) + messages.add(id, "Name of a playable class is missing", "", CSMDoc::Message::Severity_Error); + else + messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Warning); + } // A playable class should have a description if (class_.mData.mIsPlayable != 0 && class_.mDescription.empty()) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index d3901ac88..c61d84d51 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -14,7 +14,8 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( const CSMWorld::IdCollection& faction, const CSMWorld::IdCollection& scripts, const CSMWorld::Resources& models, - const CSMWorld::Resources& icons) + const CSMWorld::Resources& icons, + const CSMWorld::IdCollection& bodyparts) :mObjects(referenceable), mRaces(races), mClasses(classes), @@ -22,6 +23,7 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( mScripts(scripts), mModels(models), mIcons(icons), + mBodyParts(bodyparts), mPlayerPresent(false) { mIgnoreBaseRecords = false; @@ -274,11 +276,10 @@ void CSMTools::ReferenceableCheckStage::activatorCheck( const ESM::Activator& activator = (dynamic_cast& >(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Activator, activator.mId); - //Checking for model, IIRC all activators should have a model if (activator.mModel.empty()) - messages.push_back (std::make_pair (id, "Model is missing")); + messages.add(id, "Model is missing", "", CSMDoc::Message::Severity_Error); else if (mModels.searchId(activator.mModel) == -1) - messages.push_back (std::make_pair (id, "Model '" + activator.mModel + "' does not exist")); + messages.add(id, "Model '" + activator.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error); // Check that mentioned scripts exist scriptCheck(activator, messages, id.toString()); @@ -299,7 +300,6 @@ void CSMTools::ReferenceableCheckStage::potionCheck( CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Potion, potion.mId); inventoryItemCheck(potion, messages, id.toString()); - //IIRC potion can have empty effects list just fine. // Check that mentioned scripts exist scriptCheck(potion, messages, id.toString()); @@ -344,13 +344,13 @@ void CSMTools::ReferenceableCheckStage::armorCheck( inventoryItemCheck(armor, messages, id.toString(), true); - //checking for armor class, armor should have poistive armor class, but 0 is considered legal + // Armor should have positive armor class, but 0 class is not an error if (armor.mData.mArmor < 0) - messages.push_back (std::make_pair (id, "Armor class is negative")); + messages.add(id, "Armor class is negative", "", CSMDoc::Message::Severity_Error); - //checking for health. Only positive numbers are allowed, or 0 is illegal + // Armor durability must be a positive number if (armor.mData.mHealth <= 0) - messages.push_back (std::make_pair (id, "Durability is non-positive")); + messages.add(id, "Durability is non-positive", "", CSMDoc::Message::Severity_Error); // Check that mentioned scripts exist scriptCheck(armor, messages, id.toString()); @@ -389,19 +389,19 @@ void CSMTools::ReferenceableCheckStage::containerCheck( const ESM::Container& container = (dynamic_cast& >(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Container, container.mId); + //checking for name + if (container.mName.empty()) + messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); + //Checking for model if (container.mModel.empty()) - messages.push_back (std::make_pair (id, "Model is missing")); + messages.add(id, "Model is missing", "", CSMDoc::Message::Severity_Error); else if (mModels.searchId(container.mModel) == -1) - messages.push_back (std::make_pair (id, "Model '" + container.mModel + "' does not exist")); + messages.add(id, "Model '" + container.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error); //Checking for capacity (weight) if (container.mWeight < 0) //0 is allowed - messages.push_back (std::make_pair (id, "Capacity is negative")); - - //checking for name - if (container.mName.empty()) - messages.push_back (std::make_pair (id, "Name is missing")); + messages.add(id, "Capacity is negative", "", CSMDoc::Message::Severity_Error); //checking contained items inventoryListCheck(container.mInventory.mList, messages, id.toString()); @@ -423,69 +423,81 @@ void CSMTools::ReferenceableCheckStage::creatureCheck ( const ESM::Creature& creature = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Creature, creature.mId); + if (creature.mName.empty()) + messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); + if (creature.mModel.empty()) - messages.push_back (std::make_pair (id, "Model is missing")); + messages.add(id, "Model is missing", "", CSMDoc::Message::Severity_Error); else if (mModels.searchId(creature.mModel) == -1) - messages.push_back (std::make_pair (id, "Model '" + creature.mModel + "' does not exist")); - - if (creature.mName.empty()) - messages.push_back (std::make_pair (id, "Name is missing")); + messages.add(id, "Model '" + creature.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error); //stats checks - if (creature.mData.mLevel < 1) - messages.push_back (std::make_pair (id, "Level is non-positive")); + if (creature.mData.mLevel <= 0) + messages.add(id, "Level is non-positive", "", CSMDoc::Message::Severity_Warning); if (creature.mData.mStrength < 0) - messages.push_back (std::make_pair (id, "Strength is negative")); - + messages.add(id, "Strength is negative", "", CSMDoc::Message::Severity_Warning); if (creature.mData.mIntelligence < 0) - messages.push_back (std::make_pair (id, "Intelligence is negative")); - + messages.add(id, "Intelligence is negative", "", CSMDoc::Message::Severity_Warning); if (creature.mData.mWillpower < 0) - messages.push_back (std::make_pair (id, "Willpower is negative")); - + messages.add(id, "Willpower is negative", "", CSMDoc::Message::Severity_Warning); if (creature.mData.mAgility < 0) - messages.push_back (std::make_pair (id, "Agility is negative")); - + messages.add(id, "Agility is negative", "", CSMDoc::Message::Severity_Warning); if (creature.mData.mSpeed < 0) - messages.push_back (std::make_pair (id, "Speed is negative")); - + messages.add(id, "Speed is negative", "", CSMDoc::Message::Severity_Warning); if (creature.mData.mEndurance < 0) - messages.push_back (std::make_pair (id, "Endurance is negative")); - + messages.add(id, "Endurance is negative", "", CSMDoc::Message::Severity_Warning); if (creature.mData.mPersonality < 0) - messages.push_back (std::make_pair (id, "Personality is negative")); - + messages.add(id, "Personality is negative", "", CSMDoc::Message::Severity_Warning); if (creature.mData.mLuck < 0) - messages.push_back (std::make_pair (id, "Luck is negative")); + messages.add(id, "Luck is negative", "", CSMDoc::Message::Severity_Warning); + + if (creature.mData.mCombat < 0) + messages.add(id, "Combat is negative", "", CSMDoc::Message::Severity_Warning); + if (creature.mData.mMagic < 0) + messages.add(id, "Magic is negative", "", CSMDoc::Message::Severity_Warning); + if (creature.mData.mStealth < 0) + messages.add(id, "Stealth is negative", "", CSMDoc::Message::Severity_Warning); if (creature.mData.mHealth < 0) - messages.push_back (std::make_pair (id, "Health is negative")); + messages.add(id, "Health is negative", "", CSMDoc::Message::Severity_Error); + if (creature.mData.mMana < 0) + messages.add(id, "Magicka is negative", "", CSMDoc::Message::Severity_Error); + if (creature.mData.mFatigue < 0) + messages.add(id, "Fatigue is negative", "", CSMDoc::Message::Severity_Error); if (creature.mData.mSoul < 0) - messages.push_back (std::make_pair (id, "Soul value is negative")); + messages.add(id, "Soul value is negative", "", CSMDoc::Message::Severity_Error); for (int i = 0; i < 6; ++i) { if (creature.mData.mAttack[i] < 0) - { - messages.push_back (std::make_pair (id, "One of attacks has negative damage")); - break; - } + messages.add(id, "Attack " + std::to_string(i/2 + 1) + " has negative" + (i % 2 == 0 ? " minimum " : " maximum ") + "damage", "", CSMDoc::Message::Severity_Error); + if (i % 2 == 0 && creature.mData.mAttack[i] > creature.mData.mAttack[i+1]) + messages.add(id, "Attack " + std::to_string(i/2 + 1) + " has minimum damage higher than maximum damage", "", CSMDoc::Message::Severity_Warning); } - //TODO, find meaning of other values if (creature.mData.mGold < 0) - messages.push_back (std::make_pair (id, "Gold count is negative")); + messages.add(id, "Gold count is negative", "", CSMDoc::Message::Severity_Error); if (creature.mScale == 0) - messages.push_back (std::make_pair (id, "Scale is equal to zero")); + messages.add(id, "Scale is equal to zero", "", CSMDoc::Message::Severity_Error); + + if (!creature.mOriginal.empty()) + { + CSMWorld::RefIdData::LocalIndex index = mObjects.searchId(creature.mOriginal); + if (index.first == -1) + messages.add(id, "Parent creature '" + creature.mOriginal + "' does not exist", "", CSMDoc::Message::Severity_Error); + else if (index.second != CSMWorld::UniversalId::Type_Creature) + messages.add(id, "'" + creature.mOriginal + "' is not a creature", "", CSMDoc::Message::Severity_Error); + } // Check inventory inventoryListCheck(creature.mInventory.mList, messages, id.toString()); // Check that mentioned scripts exist scriptCheck(creature, messages, id.toString()); + /// \todo Check spells, teleport table, AI data and AI packages for validity } void CSMTools::ReferenceableCheckStage::doorCheck( @@ -503,12 +515,12 @@ void CSMTools::ReferenceableCheckStage::doorCheck( //usual, name or model if (door.mName.empty()) - messages.push_back (std::make_pair (id, "Name is missing")); + messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); if (door.mModel.empty()) - messages.push_back (std::make_pair (id, "Model is missing")); + messages.add(id, "Model is missing", "", CSMDoc::Message::Severity_Error); else if (mModels.searchId(door.mModel) == -1) - messages.push_back (std::make_pair (id, "Model '" + door.mModel + "' does not exist")); + messages.add(id, "Model '" + door.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error); // Check that mentioned scripts exist scriptCheck(door, messages, id.toString()); @@ -582,7 +594,7 @@ void CSMTools::ReferenceableCheckStage::lightCheck( CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Light, light.mId); if (light.mData.mRadius < 0) - messages.push_back (std::make_pair (id, "Light radius is negative")); + messages.add(id, "Light radius is negative", "", CSMDoc::Message::Severity_Error); if (light.mData.mFlags & ESM::Light::Carry) inventoryItemCheck(light, messages, id.toString()); @@ -657,89 +669,87 @@ void CSMTools::ReferenceableCheckStage::npcCheck ( char disposition(npc.mNpdt.mDisposition); char reputation(npc.mNpdt.mReputation); char rank(npc.mNpdt.mRank); - //Don't know what unknown is for int gold(npc.mNpdt.mGold); if (npc.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) //12 = autocalculated { if ((npc.mFlags & ESM::NPC::Autocalc) == 0) //0x0010 = autocalculated flag { - messages.push_back (std::make_pair (id, npc.mId + " mNpdtType or flags mismatch!")); //should not happen? + messages.add(id, "NPC with autocalculated stats doesn't have autocalc flag turned on", "", CSMDoc::Message::Severity_Error); //should not happen? return; } - - level = npc.mNpdt.mLevel; - disposition = npc.mNpdt.mDisposition; - reputation = npc.mNpdt.mReputation; - rank = npc.mNpdt.mRank; - gold = npc.mNpdt.mGold; } else { + if (npc.mNpdt.mStrength == 0) + messages.add(id, "Strength is equal to zero", "", CSMDoc::Message::Severity_Warning); + if (npc.mNpdt.mIntelligence == 0) + messages.add(id, "Intelligence is equal to zero", "", CSMDoc::Message::Severity_Warning); + if (npc.mNpdt.mWillpower == 0) + messages.add(id, "Willpower is equal to zero", "", CSMDoc::Message::Severity_Warning); if (npc.mNpdt.mAgility == 0) - messages.push_back (std::make_pair (id, "Agility is equal to zero")); - + messages.add(id, "Agility is equal to zero", "", CSMDoc::Message::Severity_Warning); + if (npc.mNpdt.mSpeed == 0) + messages.add(id, "Speed is equal to zero", "", CSMDoc::Message::Severity_Warning); if (npc.mNpdt.mEndurance == 0) - messages.push_back (std::make_pair (id, "Endurance is equal to zero")); - - if (npc.mNpdt.mIntelligence == 0) - messages.push_back (std::make_pair (id, "Intelligence is equal to zero")); - - if (npc.mNpdt.mLuck == 0) - messages.push_back (std::make_pair (id, "Luck is equal to zero")); - + messages.add(id, "Endurance is equal to zero", "", CSMDoc::Message::Severity_Warning); if (npc.mNpdt.mPersonality == 0) - messages.push_back (std::make_pair (id, "Personality is equal to zero")); - - if (npc.mNpdt.mStrength == 0) - messages.push_back (std::make_pair (id, "Strength is equal to zero")); - - if (npc.mNpdt.mSpeed == 0) - messages.push_back (std::make_pair (id, "Speed is equal to zero")); - - if (npc.mNpdt.mWillpower == 0) - messages.push_back (std::make_pair (id, "Willpower is equal to zero")); + messages.add(id, "Personality is equal to zero", "", CSMDoc::Message::Severity_Warning); + if (npc.mNpdt.mLuck == 0) + messages.add(id, "Luck is equal to zero", "", CSMDoc::Message::Severity_Warning); } if (level <= 0) - messages.push_back (std::make_pair (id, "Level is non-positive")); + messages.add(id, "Level is non-positive", "", CSMDoc::Message::Severity_Warning); if (gold < 0) - messages.push_back (std::make_pair (id, "Gold count is negative")); + messages.add(id, "Gold count is negative", "", CSMDoc::Message::Severity_Error); if (npc.mName.empty()) - messages.push_back (std::make_pair (id, "Name is missing")); + messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); if (npc.mClass.empty()) - messages.push_back (std::make_pair (id, "Class is missing")); + messages.add(id, "Class is missing", "", CSMDoc::Message::Severity_Error); else if (mClasses.searchId (npc.mClass) == -1) - messages.push_back (std::make_pair (id, "Class '" + npc.mClass + "' does not exist")); + messages.add(id, "Class '" + npc.mClass + "' does not exist", "", CSMDoc::Message::Severity_Error); if (npc.mRace.empty()) - messages.push_back (std::make_pair (id, "Race is missing")); + messages.add(id, "Race is missing", "", CSMDoc::Message::Severity_Error); else if (mRaces.searchId (npc.mRace) == -1) - messages.push_back (std::make_pair (id, "Race '" + npc.mRace + "' does not exist")); + messages.add(id, "Race '" + npc.mRace + "' does not exist", "", CSMDoc::Message::Severity_Error); if (disposition < 0) - messages.push_back (std::make_pair (id, "Disposition is negative")); + messages.add(id, "Disposition is negative", "", CSMDoc::Message::Severity_Warning); if (reputation < 0) - messages.push_back (std::make_pair (id, "Reputation is negative")); + messages.add(id, "Reputation is negative", "", CSMDoc::Message::Severity_Warning); if (!npc.mFaction.empty()) { if (rank < 0) - messages.push_back (std::make_pair (id, "Faction rank is negative")); + messages.add(id, "Faction rank is negative", "", CSMDoc::Message::Severity_Warning); if (mFactions.searchId(npc.mFaction) == -1) - messages.push_back (std::make_pair (id, "Faction '" + npc.mFaction + "' does not exist")); + messages.add(id, "Faction '" + npc.mFaction + "' does not exist", "", CSMDoc::Message::Severity_Error); } if (npc.mHead.empty()) - messages.push_back (std::make_pair (id, "Head is missing")); // ADD CHECK HERE + messages.push_back (std::make_pair (id, "Head is missing")); + else + { + if (mBodyParts.searchId(npc.mHead) == -1) + messages.add(id, "Head body part '" + npc.mHead + "' does not exist", "", CSMDoc::Message::Severity_Error); + /// \todo Check gender, race and other body parts stuff validity for the specific NPC + } if (npc.mHair.empty()) - messages.push_back (std::make_pair (id, "Hair is missing")); // ADD CHECK HERE + messages.push_back (std::make_pair (id, "Hair is missing")); + else + { + if (mBodyParts.searchId(npc.mHair) == -1) + messages.add(id, "Hair body part '" + npc.mHair + "' does not exist", "", CSMDoc::Message::Severity_Error); + /// \todo Check gender, race and other body part stuff validity for the specific NPC + } // Check inventory inventoryListCheck(npc.mInventory.mList, messages, id.toString()); @@ -799,14 +809,14 @@ void CSMTools::ReferenceableCheckStage::weaponCheck( weapon.mData.mType == ESM::Weapon::Bolt)) { if (weapon.mData.mSlash[0] > weapon.mData.mSlash[1]) - messages.push_back (std::make_pair (id, "Minimum slash damage higher than maximum")); + messages.add(id, "Minimum slash damage higher than maximum", "", CSMDoc::Message::Severity_Warning); if (weapon.mData.mThrust[0] > weapon.mData.mThrust[1]) - messages.push_back (std::make_pair (id, "Minimum thrust damage is higher than maximum")); + messages.add(id, "Minimum thrust damage higher than maximum", "", CSMDoc::Message::Severity_Warning); } if (weapon.mData.mChop[0] > weapon.mData.mChop[1]) - messages.push_back (std::make_pair (id, "Minimum chop damage is higher than maximum")); + messages.add(id, "Minimum chop damage higher than maximum", "", CSMDoc::Message::Severity_Warning); if (!(weapon.mData.mType == ESM::Weapon::Arrow || weapon.mData.mType == ESM::Weapon::Bolt || @@ -814,10 +824,10 @@ void CSMTools::ReferenceableCheckStage::weaponCheck( { //checking of health if (weapon.mData.mHealth == 0) - messages.push_back (std::make_pair (id, "Durability is equal to zero")); + messages.add(id, "Durability is equal to zero", "", CSMDoc::Message::Severity_Warning); if (weapon.mData.mReach < 0) - messages.push_back (std::make_pair (id, "Reach is negative")); + messages.add(id, "Reach is negative", "", CSMDoc::Message::Severity_Error); } } @@ -880,9 +890,9 @@ void CSMTools::ReferenceableCheckStage::staticCheck ( CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Static, staticElement.mId); if (staticElement.mModel.empty()) - messages.push_back (std::make_pair (id, "Model is missing")); + messages.add(id, "Model is missing", "", CSMDoc::Message::Severity_Error); else if (mModels.searchId(staticElement.mModel) == -1) - messages.push_back (std::make_pair (id, "Model '" + staticElement.mModel + "' does not exist")); + messages.add(id, "Model '" + staticElement.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error); } //final check @@ -890,8 +900,7 @@ void CSMTools::ReferenceableCheckStage::staticCheck ( void CSMTools::ReferenceableCheckStage::finalCheck (CSMDoc::Messages& messages) { if (!mPlayerPresent) - messages.push_back (std::make_pair (CSMWorld::UniversalId::Type_Referenceables, - "Player record is missing")); + messages.add(CSMWorld::UniversalId::Type_Referenceables, "Player record is missing", "", CSMDoc::Message::Severity_SeriousError); } void CSMTools::ReferenceableCheckStage::inventoryListCheck( @@ -905,7 +914,7 @@ void CSMTools::ReferenceableCheckStage::inventoryListCheck( CSMWorld::RefIdData::LocalIndex localIndex = mObjects.searchId(itemName); if (localIndex.first == -1) - messages.push_back (std::make_pair (id, "Item '" + itemName + "' does not exist")); + messages.add(id, "Item '" + itemName + "' does not exist", "", CSMDoc::Message::Severity_Error); else { // Needs to accommodate containers, creatures, and NPCs @@ -926,7 +935,7 @@ void CSMTools::ReferenceableCheckStage::inventoryListCheck( case CSMWorld::UniversalId::Type_ItemLevelledList: break; default: - messages.push_back (std::make_pair(id, "'" + itemName + "' is not an item")); + messages.add(id, "'" + itemName + "' is not an item", "", CSMDoc::Message::Severity_Error); } } } @@ -938,64 +947,64 @@ template void CSMTools::ReferenceableCheckStage::inventoryItemChe const Item& someItem, CSMDoc::Messages& messages, const std::string& someID, bool enchantable) { if (someItem.mName.empty()) - messages.push_back (std::make_pair (someID, "Name is missing")); + messages.add(someID, "Name is missing", "", CSMDoc::Message::Severity_Error); //Checking for weight if (someItem.mData.mWeight < 0) - messages.push_back (std::make_pair (someID, "Weight is negative")); + messages.add(someID, "Weight is negative", "", CSMDoc::Message::Severity_Error); //Checking for value if (someItem.mData.mValue < 0) - messages.push_back (std::make_pair (someID, "Value is negative")); + messages.add(someID, "Value is negative", "", CSMDoc::Message::Severity_Error); //checking for model if (someItem.mModel.empty()) - messages.push_back (std::make_pair (someID, "Model is missing")); + messages.add(someID, "Model is missing", "", CSMDoc::Message::Severity_Error); else if (mModels.searchId(someItem.mModel) == -1) - messages.push_back(std::make_pair(someID, "Model '" + someItem.mModel + "' does not exist")); + messages.add(someID, "Model '" + someItem.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error); //checking for icon if (someItem.mIcon.empty()) - messages.push_back (std::make_pair (someID, "Icon is missing")); + messages.add(someID, "Icon is missing", "", CSMDoc::Message::Severity_Error); else if (mIcons.searchId(someItem.mIcon) == -1) { std::string ddsIcon = someItem.mIcon; if (!(Misc::ResourceHelpers::changeExtensionToDds(ddsIcon) && mIcons.searchId(ddsIcon) != -1)) - messages.push_back(std::make_pair(someID, "Icon '" + someItem.mIcon + "' does not exist")); + messages.add(someID, "Icon '" + someItem.mIcon + "' does not exist", "", CSMDoc::Message::Severity_Error); } if (enchantable && someItem.mData.mEnchant < 0) - messages.push_back (std::make_pair (someID, "Enchantment points number is negative")); + messages.add(someID, "Enchantment points number is negative", "", CSMDoc::Message::Severity_Error); } template void CSMTools::ReferenceableCheckStage::inventoryItemCheck ( const Item& someItem, CSMDoc::Messages& messages, const std::string& someID) { if (someItem.mName.empty()) - messages.push_back (std::make_pair (someID, "Name is missing")); + messages.add(someID, "Name is missing", "", CSMDoc::Message::Severity_Error); //Checking for weight if (someItem.mData.mWeight < 0) - messages.push_back (std::make_pair (someID, "Weight is negative")); + messages.add(someID, "Weight is negative", "", CSMDoc::Message::Severity_Error); //Checking for value if (someItem.mData.mValue < 0) - messages.push_back (std::make_pair (someID, "Value is negative")); + messages.add(someID, "Value is negative", "", CSMDoc::Message::Severity_Error); //checking for model if (someItem.mModel.empty()) - messages.push_back (std::make_pair (someID, "Model is missing")); + messages.add(someID, "Model is missing", "", CSMDoc::Message::Severity_Error); else if (mModels.searchId(someItem.mModel) == -1) - messages.push_back (std::make_pair (someID, "Model '" + someItem.mModel + "' does not exist")); + messages.add(someID, "Model '" + someItem.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error); //checking for icon if (someItem.mIcon.empty()) - messages.push_back (std::make_pair (someID, "Icon is missing")); + messages.add(someID, "Icon is missing", "", CSMDoc::Message::Severity_Error); else if (mIcons.searchId(someItem.mIcon) == -1) { std::string ddsIcon = someItem.mIcon; if (!(Misc::ResourceHelpers::changeExtensionToDds(ddsIcon) && mIcons.searchId(ddsIcon) != -1)) - messages.push_back(std::make_pair(someID, "Icon '" + someItem.mIcon + "' does not exist")); + messages.add(someID, "Icon '" + someItem.mIcon + "' does not exist", "", CSMDoc::Message::Severity_Error); } } @@ -1003,17 +1012,17 @@ template void CSMTools::ReferenceableCheckStage::toolCheck ( const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID, bool canBeBroken) { if (someTool.mData.mQuality <= 0) - messages.push_back (std::make_pair (someID, "Quality is non-positive")); + messages.add(someID, "Quality is non-positive", "", CSMDoc::Message::Severity_Error); if (canBeBroken && someTool.mData.mUses<=0) - messages.push_back (std::make_pair (someID, "Number of uses is non-positive")); + messages.add(someID, "Number of uses is non-positive", "", CSMDoc::Message::Severity_Error); } template void CSMTools::ReferenceableCheckStage::toolCheck ( const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID) -{ +{ if (someTool.mData.mQuality <= 0) - messages.push_back (std::make_pair (someID, "Quality is non-positive")); + messages.add(someID, "Quality is non-positive", "", CSMDoc::Message::Severity_Error); } template void CSMTools::ReferenceableCheckStage::listCheck ( @@ -1022,10 +1031,10 @@ template void CSMTools::ReferenceableCheckStage::listCheck ( for (unsigned i = 0; i < someList.mList.size(); ++i) { if (mObjects.searchId(someList.mList[i].mId).first == -1) - messages.push_back (std::make_pair (someID, "Object '" + someList.mList[i].mId + "' does not exist")); + messages.add(someID, "Object '" + someList.mList[i].mId + "' does not exist", "", CSMDoc::Message::Severity_Error); if (someList.mList[i].mLevel < 1) - messages.push_back (std::make_pair (someID, "Level of item '" + someList.mList[i].mId + "' is non-positive")); + messages.add(someID, "Level of item '" + someList.mList[i].mId + "' is non-positive", "", CSMDoc::Message::Severity_Error); } } @@ -1035,6 +1044,6 @@ template void CSMTools::ReferenceableCheckStage::scriptCheck ( if (!someTool.mScript.empty()) { if (mScripts.searchId(someTool.mScript) == -1) - messages.push_back (std::make_pair (someID, "Script '"+someTool.mScript+"' does not exist")); + messages.add(someID, "Script '" + someTool.mScript + "' does not exist", "", CSMDoc::Message::Severity_Error); } } diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index 5da737875..d8682c907 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -19,7 +19,8 @@ namespace CSMTools const CSMWorld::IdCollection& factions, const CSMWorld::IdCollection& scripts, const CSMWorld::Resources& models, - const CSMWorld::Resources& icons); + const CSMWorld::Resources& icons, + const CSMWorld::IdCollection& bodyparts); virtual void perform(int stage, CSMDoc::Messages& messages); virtual int setup(); @@ -86,6 +87,7 @@ namespace CSMTools const CSMWorld::IdCollection& mScripts; const CSMWorld::Resources& mModels; const CSMWorld::Resources& mIcons; + const CSMWorld::IdCollection& mBodyParts; bool mPlayerPresent; bool mIgnoreBaseRecords; }; diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index 87b5041e0..b9a0abb75 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -83,7 +83,8 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier() mVerifierOperation->appendStage (new SpellCheckStage (mData.getSpells())); mVerifierOperation->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions(), mData.getScripts(), - mData.getResources (CSMWorld::UniversalId::Type_Meshes), mData.getResources (CSMWorld::UniversalId::Type_Icons))); + mData.getResources (CSMWorld::UniversalId::Type_Meshes), mData.getResources (CSMWorld::UniversalId::Type_Icons), + mData.getBodyParts())); mVerifierOperation->appendStage (new ReferenceCheckStage(mData.getReferences(), mData.getReferenceables(), mData.getCells(), mData.getFactions())); From 34ffaa2fe2cf6f85094289769cc788f55a9c4c03 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 26 Aug 2018 21:18:17 +0300 Subject: [PATCH 25/35] Make finishing touches to object record verifiers --- .../opencs/model/tools/referenceablecheck.cpp | 95 ++++++++++--------- .../opencs/model/tools/referenceablecheck.hpp | 2 +- 2 files changed, 49 insertions(+), 48 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index c61d84d51..60d4a6b58 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -16,7 +16,7 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( const CSMWorld::Resources& models, const CSMWorld::Resources& icons, const CSMWorld::IdCollection& bodyparts) - :mObjects(referenceable), + :mReferencables(referenceable), mRaces(races), mClasses(classes), mFactions(faction), @@ -32,201 +32,201 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( void CSMTools::ReferenceableCheckStage::perform (int stage, CSMDoc::Messages& messages) { //Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage. - const int bookSize(mObjects.getBooks().getSize()); + const int bookSize(mReferencables.getBooks().getSize()); if (stage < bookSize) { - bookCheck(stage, mObjects.getBooks(), messages); + bookCheck(stage, mReferencables.getBooks(), messages); return; } stage -= bookSize; - const int activatorSize(mObjects.getActivators().getSize()); + const int activatorSize(mReferencables.getActivators().getSize()); if (stage < activatorSize) { - activatorCheck(stage, mObjects.getActivators(), messages); + activatorCheck(stage, mReferencables.getActivators(), messages); return; } stage -= activatorSize; - const int potionSize(mObjects.getPotions().getSize()); + const int potionSize(mReferencables.getPotions().getSize()); if (stage < potionSize) { - potionCheck(stage, mObjects.getPotions(), messages); + potionCheck(stage, mReferencables.getPotions(), messages); return; } stage -= potionSize; - const int apparatusSize(mObjects.getApparati().getSize()); + const int apparatusSize(mReferencables.getApparati().getSize()); if (stage < apparatusSize) { - apparatusCheck(stage, mObjects.getApparati(), messages); + apparatusCheck(stage, mReferencables.getApparati(), messages); return; } stage -= apparatusSize; - const int armorSize(mObjects.getArmors().getSize()); + const int armorSize(mReferencables.getArmors().getSize()); if (stage < armorSize) { - armorCheck(stage, mObjects.getArmors(), messages); + armorCheck(stage, mReferencables.getArmors(), messages); return; } stage -= armorSize; - const int clothingSize(mObjects.getClothing().getSize()); + const int clothingSize(mReferencables.getClothing().getSize()); if (stage < clothingSize) { - clothingCheck(stage, mObjects.getClothing(), messages); + clothingCheck(stage, mReferencables.getClothing(), messages); return; } stage -= clothingSize; - const int containerSize(mObjects.getContainers().getSize()); + const int containerSize(mReferencables.getContainers().getSize()); if (stage < containerSize) { - containerCheck(stage, mObjects.getContainers(), messages); + containerCheck(stage, mReferencables.getContainers(), messages); return; } stage -= containerSize; - const int doorSize(mObjects.getDoors().getSize()); + const int doorSize(mReferencables.getDoors().getSize()); if (stage < doorSize) { - doorCheck(stage, mObjects.getDoors(), messages); + doorCheck(stage, mReferencables.getDoors(), messages); return; } stage -= doorSize; - const int ingredientSize(mObjects.getIngredients().getSize()); + const int ingredientSize(mReferencables.getIngredients().getSize()); if (stage < ingredientSize) { - ingredientCheck(stage, mObjects.getIngredients(), messages); + ingredientCheck(stage, mReferencables.getIngredients(), messages); return; } stage -= ingredientSize; - const int creatureLevListSize(mObjects.getCreatureLevelledLists().getSize()); + const int creatureLevListSize(mReferencables.getCreatureLevelledLists().getSize()); if (stage < creatureLevListSize) { - creaturesLevListCheck(stage, mObjects.getCreatureLevelledLists(), messages); + creaturesLevListCheck(stage, mReferencables.getCreatureLevelledLists(), messages); return; } stage -= creatureLevListSize; - const int itemLevelledListSize(mObjects.getItemLevelledList().getSize()); + const int itemLevelledListSize(mReferencables.getItemLevelledList().getSize()); if (stage < itemLevelledListSize) { - itemLevelledListCheck(stage, mObjects.getItemLevelledList(), messages); + itemLevelledListCheck(stage, mReferencables.getItemLevelledList(), messages); return; } stage -= itemLevelledListSize; - const int lightSize(mObjects.getLights().getSize()); + const int lightSize(mReferencables.getLights().getSize()); if (stage < lightSize) { - lightCheck(stage, mObjects.getLights(), messages); + lightCheck(stage, mReferencables.getLights(), messages); return; } stage -= lightSize; - const int lockpickSize(mObjects.getLocpicks().getSize()); + const int lockpickSize(mReferencables.getLocpicks().getSize()); if (stage < lockpickSize) { - lockpickCheck(stage, mObjects.getLocpicks(), messages); + lockpickCheck(stage, mReferencables.getLocpicks(), messages); return; } stage -= lockpickSize; - const int miscSize(mObjects.getMiscellaneous().getSize()); + const int miscSize(mReferencables.getMiscellaneous().getSize()); if (stage < miscSize) { - miscCheck(stage, mObjects.getMiscellaneous(), messages); + miscCheck(stage, mReferencables.getMiscellaneous(), messages); return; } stage -= miscSize; - const int npcSize(mObjects.getNPCs().getSize()); + const int npcSize(mReferencables.getNPCs().getSize()); if (stage < npcSize) { - npcCheck(stage, mObjects.getNPCs(), messages); + npcCheck(stage, mReferencables.getNPCs(), messages); return; } stage -= npcSize; - const int weaponSize(mObjects.getWeapons().getSize()); + const int weaponSize(mReferencables.getWeapons().getSize()); if (stage < weaponSize) { - weaponCheck(stage, mObjects.getWeapons(), messages); + weaponCheck(stage, mReferencables.getWeapons(), messages); return; } stage -= weaponSize; - const int probeSize(mObjects.getProbes().getSize()); + const int probeSize(mReferencables.getProbes().getSize()); if (stage < probeSize) { - probeCheck(stage, mObjects.getProbes(), messages); + probeCheck(stage, mReferencables.getProbes(), messages); return; } stage -= probeSize; - const int repairSize(mObjects.getRepairs().getSize()); + const int repairSize(mReferencables.getRepairs().getSize()); if (stage < repairSize) { - repairCheck(stage, mObjects.getRepairs(), messages); + repairCheck(stage, mReferencables.getRepairs(), messages); return; } stage -= repairSize; - const int staticSize(mObjects.getStatics().getSize()); + const int staticSize(mReferencables.getStatics().getSize()); if (stage < staticSize) { - staticCheck(stage, mObjects.getStatics(), messages); + staticCheck(stage, mReferencables.getStatics(), messages); return; } stage -= staticSize; - const int creatureSize(mObjects.getCreatures().getSize()); + const int creatureSize(mReferencables.getCreatures().getSize()); if (stage < creatureSize) { - creatureCheck(stage, mObjects.getCreatures(), messages); + creatureCheck(stage, mReferencables.getCreatures(), messages); return; } // if we come that far, we are about to perform our last, final check. @@ -239,7 +239,7 @@ int CSMTools::ReferenceableCheckStage::setup() mPlayerPresent = false; mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue(); - return mObjects.getSize() + 1; + return mReferencables.getSize() + 1; } void CSMTools::ReferenceableCheckStage::bookCheck( @@ -300,6 +300,7 @@ void CSMTools::ReferenceableCheckStage::potionCheck( CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Potion, potion.mId); inventoryItemCheck(potion, messages, id.toString()); + /// \todo Check magic effects for validity // Check that mentioned scripts exist scriptCheck(potion, messages, id.toString()); @@ -485,7 +486,7 @@ void CSMTools::ReferenceableCheckStage::creatureCheck ( if (!creature.mOriginal.empty()) { - CSMWorld::RefIdData::LocalIndex index = mObjects.searchId(creature.mOriginal); + CSMWorld::RefIdData::LocalIndex index = mReferencables.searchId(creature.mOriginal); if (index.first == -1) messages.add(id, "Parent creature '" + creature.mOriginal + "' does not exist", "", CSMDoc::Message::Severity_Error); else if (index.second != CSMWorld::UniversalId::Type_Creature) @@ -892,7 +893,7 @@ void CSMTools::ReferenceableCheckStage::staticCheck ( if (staticElement.mModel.empty()) messages.add(id, "Model is missing", "", CSMDoc::Message::Severity_Error); else if (mModels.searchId(staticElement.mModel) == -1) - messages.add(id, "Model '" + staticElement.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error); + messages.add(id, "Model '" + staticElement.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error); } //final check @@ -911,7 +912,7 @@ void CSMTools::ReferenceableCheckStage::inventoryListCheck( for (size_t i = 0; i < itemList.size(); ++i) { std::string itemName = itemList[i].mItem.toString(); - CSMWorld::RefIdData::LocalIndex localIndex = mObjects.searchId(itemName); + CSMWorld::RefIdData::LocalIndex localIndex = mReferencables.searchId(itemName); if (localIndex.first == -1) messages.add(id, "Item '" + itemName + "' does not exist", "", CSMDoc::Message::Severity_Error); @@ -1020,7 +1021,7 @@ template void CSMTools::ReferenceableCheckStage::toolCheck ( template void CSMTools::ReferenceableCheckStage::toolCheck ( const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID) -{ +{ if (someTool.mData.mQuality <= 0) messages.add(someID, "Quality is non-positive", "", CSMDoc::Message::Severity_Error); } @@ -1030,7 +1031,7 @@ template void CSMTools::ReferenceableCheckStage::listCheck ( { for (unsigned i = 0; i < someList.mList.size(); ++i) { - if (mObjects.searchId(someList.mList[i].mId).first == -1) + if (mReferencables.searchId(someList.mList[i].mId).first == -1) messages.add(someID, "Object '" + someList.mList[i].mId + "' does not exist", "", CSMDoc::Message::Severity_Error); if (someList.mList[i].mLevel < 1) diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index d8682c907..e55e5fad9 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -80,7 +80,7 @@ namespace CSMTools CSMDoc::Messages& messages, const std::string& someID); - const CSMWorld::RefIdData& mObjects; + const CSMWorld::RefIdData& mReferencables; const CSMWorld::IdCollection& mRaces; const CSMWorld::IdCollection& mClasses; const CSMWorld::IdCollection& mFactions; From 0bdb7ea92f77c695f90e10b0eda0d581561515cb Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 26 Aug 2018 21:40:07 +0300 Subject: [PATCH 26/35] Cleanup --- apps/opencs/model/tools/birthsigncheck.cpp | 26 ++----- apps/opencs/model/tools/birthsigncheck.hpp | 3 - apps/opencs/model/tools/classcheck.cpp | 4 -- apps/opencs/model/tools/magiceffectcheck.cpp | 70 ++++++------------- .../opencs/model/tools/referenceablecheck.cpp | 2 + 5 files changed, 28 insertions(+), 77 deletions(-) diff --git a/apps/opencs/model/tools/birthsigncheck.cpp b/apps/opencs/model/tools/birthsigncheck.cpp index c582da8e4..a0ae4b11f 100644 --- a/apps/opencs/model/tools/birthsigncheck.cpp +++ b/apps/opencs/model/tools/birthsigncheck.cpp @@ -7,17 +7,6 @@ #include "../world/universalid.hpp" - -std::string CSMTools::BirthsignCheckStage::checkTexture(const std::string &texture) const -{ - if (mTextures.searchId(texture) != -1) return std::string(); - - std::string ddsTexture = texture; - if (Misc::ResourceHelpers::changeExtensionToDds(ddsTexture) && mTextures.searchId(ddsTexture) != -1) return std::string(); - - return "Image '" + texture + "' does not exist"; -} - CSMTools::BirthsignCheckStage::BirthsignCheckStage (const CSMWorld::IdCollection& birthsigns, const CSMWorld::Resources &textures) : mBirthsigns(birthsigns), @@ -46,24 +35,21 @@ void CSMTools::BirthsignCheckStage::perform (int stage, CSMDoc::Messages& messag CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Birthsign, birthsign.mId); if (birthsign.mName.empty()) - { messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); - } if (birthsign.mDescription.empty()) - { messages.add(id, "Description is missing", "", CSMDoc::Message::Severity_Warning); - } if (birthsign.mTexture.empty()) - { messages.add(id, "Image is missing", "", CSMDoc::Message::Severity_Error); - } else { - const std::string error = checkTexture(birthsign.mTexture); - if (!error.empty()) - messages.add(id, error, "", CSMDoc::Message::Severity_Error); + if (mTextures.searchId(birthsign.mTexture) != -1) + return; + + std::string ddsTexture = birthsign.mTexture; + if (!(Misc::ResourceHelpers::changeExtensionToDds(ddsTexture) && mTextures.searchId(ddsTexture) != -1)) + messages.add(id, "Image '" + birthsign.mTexture + "' does not exist", "", CSMDoc::Message::Severity_Error); } /// \todo check data members that can't be edited in the table view diff --git a/apps/opencs/model/tools/birthsigncheck.hpp b/apps/opencs/model/tools/birthsigncheck.hpp index d032d3cef..9001c524c 100644 --- a/apps/opencs/model/tools/birthsigncheck.hpp +++ b/apps/opencs/model/tools/birthsigncheck.hpp @@ -17,9 +17,6 @@ namespace CSMTools const CSMWorld::Resources &mTextures; bool mIgnoreBaseRecords; - private: - std::string checkTexture(const std::string &texture) const; - public: BirthsignCheckStage (const CSMWorld::IdCollection &birthsigns, diff --git a/apps/opencs/model/tools/classcheck.cpp b/apps/opencs/model/tools/classcheck.cpp index 9984c3287..25cca8fcd 100644 --- a/apps/opencs/model/tools/classcheck.cpp +++ b/apps/opencs/model/tools/classcheck.cpp @@ -49,12 +49,10 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages) // test for invalid attributes for (int i=0; i<2; ++i) - { if (class_.mData.mAttribute[i]==-1) { messages.add(id, "Attribute #" + std::to_string(i) + " is not set", "", CSMDoc::Message::Severity_Error); } - } if (class_.mData.mAttribute[0]==class_.mData.mAttribute[1] && class_.mData.mAttribute[0]!=-1) { @@ -69,10 +67,8 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages) ++skills[class_.mData.mSkills[i][i2]]; for (auto &skill : skills) - { if (skill.second>1) { messages.add(id, "Skill " + ESM::Skill::indexToId (skill.first) + " is listed more than once", "", CSMDoc::Message::Severity_Warning); } - } } diff --git a/apps/opencs/model/tools/magiceffectcheck.cpp b/apps/opencs/model/tools/magiceffectcheck.cpp index 943d89cdc..b62e791a4 100644 --- a/apps/opencs/model/tools/magiceffectcheck.cpp +++ b/apps/opencs/model/tools/magiceffectcheck.cpp @@ -4,17 +4,6 @@ #include "../prefs/state.hpp" -std::string CSMTools::MagicEffectCheckStage::checkTexture(const std::string &texture, bool isIcon) const -{ - const CSMWorld::Resources &textures = isIcon ? mIcons : mTextures; - if (textures.searchId(texture) != -1) return std::string(); - - std::string ddsTexture = texture; - if (Misc::ResourceHelpers::changeExtensionToDds(ddsTexture) && textures.searchId(ddsTexture) != -1) return std::string(); - - return (isIcon ? "Icon '" : "Particle '") + texture + "' does not exist"; -} - std::string CSMTools::MagicEffectCheckStage::checkObject(const std::string &id, const CSMWorld::UniversalId &type, const std::string &column) const @@ -25,12 +14,6 @@ std::string CSMTools::MagicEffectCheckStage::checkObject(const std::string &id, return std::string(); } -std::string CSMTools::MagicEffectCheckStage::checkSound(const std::string &id, const std::string &column) const -{ - if (!id.empty() && mSounds.searchId(id) == -1) return (column + " '" + id + "' " + "does not exist"); - return std::string(); -} - CSMTools::MagicEffectCheckStage::MagicEffectCheckStage(const CSMWorld::IdCollection &effects, const CSMWorld::IdCollection &sounds, const CSMWorld::RefIdCollection &objects, @@ -79,16 +62,22 @@ void CSMTools::MagicEffectCheckStage::perform(int stage, CSMDoc::Messages &messa } else { - const std::string error = checkTexture(effect.mIcon, true); - if (!error.empty()) - messages.add(id, error, "", CSMDoc::Message::Severity_Error); + if (mIcons.searchId(effect.mIcon) == -1) + { + std::string ddsIcon = effect.mIcon; + if (!(Misc::ResourceHelpers::changeExtensionToDds(ddsIcon) && mIcons.searchId(ddsIcon) != -1)) + messages.add(id, "Icon '" + effect.mIcon + "' does not exist", "", CSMDoc::Message::Severity_Error); + } } if (!effect.mParticle.empty()) { - const std::string error = checkTexture(effect.mParticle, false); - if (!error.empty()) - messages.add(id, error, "", CSMDoc::Message::Severity_Error); + if (mTextures.searchId(effect.mParticle) == -1) + { + std::string ddsParticle = effect.mParticle; + if (!(Misc::ResourceHelpers::changeExtensionToDds(ddsParticle) && mTextures.searchId(ddsParticle) != -1)) + messages.add(id, "Particle texture '" + effect.mParticle + "' does not exist", "", CSMDoc::Message::Severity_Error); + } } if (!effect.mCasting.empty()) @@ -119,31 +108,12 @@ void CSMTools::MagicEffectCheckStage::perform(int stage, CSMDoc::Messages &messa messages.add(id, error, "", CSMDoc::Message::Severity_Error); } - if (!effect.mCastSound.empty()) - { - const std::string error = checkSound(effect.mCastSound, "Casting sound"); - if (!error.empty()) - messages.add(id, error, "", CSMDoc::Message::Severity_Error); - } - - if (!effect.mHitSound.empty()) - { - const std::string error = checkSound(effect.mHitSound, "Hit sound"); - if (!error.empty()) - messages.add(id, error, "", CSMDoc::Message::Severity_Error); - } - - if (!effect.mAreaSound.empty()) - { - const std::string error = checkSound(effect.mAreaSound, "Area sound"); - if (!error.empty()) - messages.add(id, error, "", CSMDoc::Message::Severity_Error); - } - - if (!effect.mBoltSound.empty()) - { - const std::string error = checkSound(effect.mBoltSound, "Bolt sound"); - if (!error.empty()) - messages.add(id, error, "", CSMDoc::Message::Severity_Error); - } + if (!effect.mCastSound.empty() && mSounds.searchId(effect.mCastSound) == -1) + messages.add(id, "Casting sound '" + effect.mCastSound + "' does not exist", "", CSMDoc::Message::Severity_Error); + if (!effect.mHitSound.empty() && mSounds.searchId(effect.mHitSound) == -1) + messages.add(id, "Hit sound '" + effect.mHitSound + "' does not exist", "", CSMDoc::Message::Severity_Error); + if (!effect.mAreaSound.empty() && mSounds.searchId(effect.mAreaSound) == -1) + messages.add(id, "Area sound '" + effect.mAreaSound + "' does not exist", "", CSMDoc::Message::Severity_Error); + if (!effect.mBoltSound.empty() && mSounds.searchId(effect.mBoltSound) == -1) + messages.add(id, "Bolt sound '" + effect.mBoltSound + "' does not exist", "", CSMDoc::Message::Severity_Error); } diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 60d4a6b58..4d68c93cd 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -723,7 +723,9 @@ void CSMTools::ReferenceableCheckStage::npcCheck ( messages.add(id, "Disposition is negative", "", CSMDoc::Message::Severity_Warning); if (reputation < 0) + { messages.add(id, "Reputation is negative", "", CSMDoc::Message::Severity_Warning); + } if (!npc.mFaction.empty()) { From 47b9008743b9a2a4d824f0768035f2932f672dd7 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 26 Aug 2018 22:16:50 +0300 Subject: [PATCH 27/35] Renovate reference record verifier --- apps/opencs/model/tools/referencecheck.cpp | 77 +++++++++------------- apps/opencs/model/tools/skillcheck.cpp | 2 - apps/opencs/model/tools/soundcheck.cpp | 1 - apps/opencs/model/tools/soundcheck.hpp | 6 +- 4 files changed, 31 insertions(+), 55 deletions(-) diff --git a/apps/opencs/model/tools/referencecheck.cpp b/apps/opencs/model/tools/referencecheck.cpp index dd93b4e9c..76bfeb3ba 100644 --- a/apps/opencs/model/tools/referencecheck.cpp +++ b/apps/opencs/model/tools/referencecheck.cpp @@ -28,76 +28,59 @@ void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages &message const CSMWorld::CellRef& cellRef = record.get(); const CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Reference, cellRef.mId); - // Check for empty reference id - if (cellRef.mRefID.empty()) { - messages.push_back(std::make_pair(id, "Instance is not based on an object")); - } else { + // Check reference id + if (cellRef.mRefID.empty()) + messages.add(id, "Instance is not based on an object", "", CSMDoc::Message::Severity_Error); + else + { // Check for non existing referenced object - if (mObjects.searchId(cellRef.mRefID) == -1) { - messages.push_back(std::make_pair(id, "Instance of a non-existent object '" + cellRef.mRefID + "'")); - } else { + if (mObjects.searchId(cellRef.mRefID) == -1) + messages.add(id, "Instance of a non-existent object '" + cellRef.mRefID + "'", "", CSMDoc::Message::Severity_Error); + else + { // Check if reference charge is valid for it's proper referenced type CSMWorld::RefIdData::LocalIndex localIndex = mDataSet.searchId(cellRef.mRefID); bool isLight = localIndex.second == CSMWorld::UniversalId::Type_Light; - if ((isLight && cellRef.mChargeFloat < -1) || (!isLight && cellRef.mChargeInt < -1)) { - std::string str = "Invalid charge: "; - if (localIndex.second == CSMWorld::UniversalId::Type_Light) - str += std::to_string(cellRef.mChargeFloat); - else - str += std::to_string(cellRef.mChargeInt); - messages.push_back(std::make_pair(id, str)); - } + if ((isLight && cellRef.mChargeFloat < -1) || (!isLight && cellRef.mChargeInt < -1)) + messages.add(id, "Invalid charge", "", CSMDoc::Message::Severity_Error); } } // If object have owner, check if that owner reference is valid if (!cellRef.mOwner.empty() && mObjects.searchId(cellRef.mOwner) == -1) - messages.push_back(std::make_pair(id, "Owner object '" + cellRef.mOwner + "' does not exist")); + messages.add(id, "Owner object '" + cellRef.mOwner + "' does not exist", "", CSMDoc::Message::Severity_Error); // If object have creature soul trapped, check if that creature reference is valid if (!cellRef.mSoul.empty()) if (mObjects.searchId(cellRef.mSoul) == -1) - messages.push_back(std::make_pair(id, "Trapped soul object '" + cellRef.mSoul + "' does not exist")); - - bool hasFaction = !cellRef.mFaction.empty(); + messages.add(id, "Trapped soul object '" + cellRef.mOwner + "' does not exist", "", CSMDoc::Message::Severity_Error); - // If object have faction, check if that faction reference is valid - if (hasFaction) + if (cellRef.mFaction.empty()) + { + if (cellRef.mFactionRank != -2) + messages.add(id, "Reference without a faction has a faction rank", "", CSMDoc::Message::Severity_Error); + } + else + { if (mFactions.searchId(cellRef.mFaction) == -1) - messages.push_back(std::make_pair(id, "Faction '" + cellRef.mFaction + "' does not exist")); - - // Check item's faction rank - if ((hasFaction && cellRef.mFactionRank < -1) || (!hasFaction && cellRef.mFactionRank != -2)) - messages.push_back(std::make_pair(id, "Invalid faction rank " + std::to_string(cellRef.mFactionRank))); + messages.add(id, "Faction '" + cellRef.mFaction + "' does not exist", "", CSMDoc::Message::Severity_Error); + else if (cellRef.mFactionRank < -1) + messages.add(id, "Invalid faction rank", "", CSMDoc::Message::Severity_Error); + } - // If door have destination cell, check if that reference is valid - if (!cellRef.mDestCell.empty()) - if (mCells.searchId(cellRef.mDestCell) == -1) - messages.push_back(std::make_pair(id, "Destination cell '" + cellRef.mDestCell + "' does not exist")); + if (!cellRef.mDestCell.empty() && mCells.searchId(cellRef.mDestCell) == -1) + messages.add(id, "Destination cell '" + cellRef.mDestCell + "' does not exist", "", CSMDoc::Message::Severity_Error); - // Check if scale isn't negative if (cellRef.mScale < 0) - { - std::string str = "Negative scale: "; - str += std::to_string(cellRef.mScale); - messages.push_back(std::make_pair(id, str)); - } + messages.add(id, "Negative scale", "", CSMDoc::Message::Severity_Error); // Check if enchantement points aren't negative or are at full (-1) - if (cellRef.mEnchantmentCharge < 0 && cellRef.mEnchantmentCharge != -1) - { - std::string str = "Negative enchantment points: "; - str += std::to_string(cellRef.mEnchantmentCharge); - messages.push_back(std::make_pair(id, str)); - } + if (cellRef.mEnchantmentCharge < -1) + messages.add(id, "Negative number of enchantment points", "", CSMDoc::Message::Severity_Error); // Check if gold value isn't negative if (cellRef.mGoldValue < 0) - { - std::string str = "Negative gold value: "; - str += cellRef.mGoldValue; - messages.push_back(std::make_pair(id, str)); - } + messages.add(id, "Negative gold value", "", CSMDoc::Message::Severity_Error); } int CSMTools::ReferenceCheckStage::setup() diff --git a/apps/opencs/model/tools/skillcheck.cpp b/apps/opencs/model/tools/skillcheck.cpp index ab7df51cb..89eba011a 100644 --- a/apps/opencs/model/tools/skillcheck.cpp +++ b/apps/opencs/model/tools/skillcheck.cpp @@ -35,10 +35,8 @@ void CSMTools::SkillCheckStage::perform (int stage, CSMDoc::Messages& messages) messages.add(id, "Description is missing", "", CSMDoc::Message::Severity_Warning); for (int i=0; i<4; ++i) - { if (skill.mData.mUseValue[i]<0) { messages.add(id, "Usage experience value #" + std::to_string(i) + " is negative", "", CSMDoc::Message::Severity_Error); } - } } diff --git a/apps/opencs/model/tools/soundcheck.cpp b/apps/opencs/model/tools/soundcheck.cpp index 7bb27e984..09e5ecdbf 100644 --- a/apps/opencs/model/tools/soundcheck.cpp +++ b/apps/opencs/model/tools/soundcheck.cpp @@ -4,7 +4,6 @@ #include "../prefs/state.hpp" -#include "../world/resources.hpp" #include "../world/universalid.hpp" CSMTools::SoundCheckStage::SoundCheckStage (const CSMWorld::IdCollection &sounds, diff --git a/apps/opencs/model/tools/soundcheck.hpp b/apps/opencs/model/tools/soundcheck.hpp index 47c3249ce..fc5925717 100644 --- a/apps/opencs/model/tools/soundcheck.hpp +++ b/apps/opencs/model/tools/soundcheck.hpp @@ -3,15 +3,11 @@ #include +#include "../world/resources.hpp" #include "../world/idcollection.hpp" #include "../doc/stage.hpp" -namespace CSMWorld -{ - class Resources; -} - namespace CSMTools { /// \brief VerifyStage: make sure that sound records are internally consistent From dabdb0bfaf63d55ec72c678332e5153c19cdcc4b Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Wed, 29 Aug 2018 18:53:02 +0300 Subject: [PATCH 28/35] Get rid of deprecated Messages::push_back() --- apps/opencs/model/doc/messages.cpp | 5 ----- apps/opencs/model/doc/messages.hpp | 3 --- apps/opencs/model/tools/referenceablecheck.cpp | 4 ++-- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/opencs/model/doc/messages.cpp b/apps/opencs/model/doc/messages.cpp index 76bbb6f22..b70d44eda 100644 --- a/apps/opencs/model/doc/messages.cpp +++ b/apps/opencs/model/doc/messages.cpp @@ -35,11 +35,6 @@ void CSMDoc::Messages::add (const CSMWorld::UniversalId& id, const std::string& mMessages.push_back (Message (id, message, hint, severity)); } -void CSMDoc::Messages::push_back (const std::pair& data) -{ - add (data.first, data.second); -} - CSMDoc::Messages::Iterator CSMDoc::Messages::begin() const { return mMessages.begin(); diff --git a/apps/opencs/model/doc/messages.hpp b/apps/opencs/model/doc/messages.hpp index 4041e1a67..671ded82a 100644 --- a/apps/opencs/model/doc/messages.hpp +++ b/apps/opencs/model/doc/messages.hpp @@ -56,9 +56,6 @@ namespace CSMDoc const std::string& hint = "", Message::Severity severity = Message::Severity_Default); - /// \deprecated Use add instead. - void push_back (const std::pair& data); - Iterator begin() const; Iterator end() const; diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 4d68c93cd..def6dece3 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -737,7 +737,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck ( } if (npc.mHead.empty()) - messages.push_back (std::make_pair (id, "Head is missing")); + messages.add(id, "Head is missing", "", CSMDoc::Message::Severity_Error); else { if (mBodyParts.searchId(npc.mHead) == -1) @@ -746,7 +746,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck ( } if (npc.mHair.empty()) - messages.push_back (std::make_pair (id, "Hair is missing")); + messages.add(id, "Hair is missing", "", CSMDoc::Message::Severity_Error); else { if (mBodyParts.searchId(npc.mHair) == -1) From 015cd6064faa44fd4969de80722b2f9ebaa79dbc Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Thu, 30 Aug 2018 01:21:27 +0300 Subject: [PATCH 29/35] Implement basic enchantment record verifier (feature #1617) --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/tools/enchantmentcheck.cpp | 42 ++++++++++++++++++++ apps/opencs/model/tools/enchantmentcheck.hpp | 30 ++++++++++++++ apps/opencs/model/tools/magiceffectcheck.cpp | 6 ++- apps/opencs/model/tools/tools.cpp | 3 ++ 5 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 apps/opencs/model/tools/enchantmentcheck.cpp create mode 100644 apps/opencs/model/tools/enchantmentcheck.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index d1ebcde42..f2821f184 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 journalcheck + mergestages gmstcheck topicinfocheck journalcheck enchantmentcheck ) opencs_hdrs_noqt (model/tools diff --git a/apps/opencs/model/tools/enchantmentcheck.cpp b/apps/opencs/model/tools/enchantmentcheck.cpp new file mode 100644 index 000000000..e1dca9331 --- /dev/null +++ b/apps/opencs/model/tools/enchantmentcheck.cpp @@ -0,0 +1,42 @@ +#include "enchantmentcheck.hpp" + +#include "../prefs/state.hpp" + +#include "../world/universalid.hpp" + +CSMTools::EnchantmentCheckStage::EnchantmentCheckStage (const CSMWorld::IdCollection& enchantments) + : mEnchantments (enchantments) +{ + mIgnoreBaseRecords = false; +} + +int CSMTools::EnchantmentCheckStage::setup() +{ + mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue(); + + return mEnchantments.getSize(); +} + +void CSMTools::EnchantmentCheckStage::perform (int stage, CSMDoc::Messages& messages) +{ + const CSMWorld::Record& record = mEnchantments.getRecord (stage); + + // Skip "Base" records (setting!) and "Deleted" records + if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted()) + return; + + const ESM::Enchantment& enchantment = record.get(); + + CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Enchantment, enchantment.mId); + + if (enchantment.mData.mType < 0 || enchantment.mData.mType > 3) + messages.add(id, "Invalid type", "", CSMDoc::Message::Severity_Error); + + if (enchantment.mData.mCost < 0) + messages.add(id, "Cost is negative", "", CSMDoc::Message::Severity_Error); + + if (enchantment.mData.mCharge < 0) + messages.add(id, "Charge is negative", "", CSMDoc::Message::Severity_Error); + + /// \todo Check effects list for validity +} diff --git a/apps/opencs/model/tools/enchantmentcheck.hpp b/apps/opencs/model/tools/enchantmentcheck.hpp new file mode 100644 index 000000000..ba8ae64aa --- /dev/null +++ b/apps/opencs/model/tools/enchantmentcheck.hpp @@ -0,0 +1,30 @@ +#ifndef CSM_TOOLS_ENCHANTMENTCHECK_H +#define CSM_TOOLS_ENCHANTMENTCHECK_H + +#include + +#include "../world/idcollection.hpp" + +#include "../doc/stage.hpp" + +namespace CSMTools +{ + /// \brief Make sure that enchantment records are correct + class EnchantmentCheckStage : public CSMDoc::Stage + { + const CSMWorld::IdCollection& mEnchantments; + bool mIgnoreBaseRecords; + + public: + + EnchantmentCheckStage (const CSMWorld::IdCollection& enchantments); + + virtual int setup(); + ///< \return number of steps + + virtual void perform (int stage, CSMDoc::Messages& messages); + ///< Messages resulting from this tage will be appended to \a messages. + }; +} + +#endif diff --git a/apps/opencs/model/tools/magiceffectcheck.cpp b/apps/opencs/model/tools/magiceffectcheck.cpp index b62e791a4..f55fb14ee 100644 --- a/apps/opencs/model/tools/magiceffectcheck.cpp +++ b/apps/opencs/model/tools/magiceffectcheck.cpp @@ -9,8 +9,10 @@ std::string CSMTools::MagicEffectCheckStage::checkObject(const std::string &id, const std::string &column) const { CSMWorld::RefIdData::LocalIndex index = mObjects.getDataSet().searchId(id); - if (index.first == -1) return (column + " '" + id + "' " + "does not exist"); - else if (index.second != type.getType()) return (column + " '" + id + "' " + "does not have " + type.getTypeName() + " type"); + if (index.first == -1) + return (column + " '" + id + "' does not exist"); + else if (index.second != type.getType()) + return (column + " '" + id + "' does not have " + type.getTypeName() + " type"); return std::string(); } diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index b9a0abb75..07a721e8e 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -32,6 +32,7 @@ #include "gmstcheck.hpp" #include "topicinfocheck.hpp" #include "journalcheck.hpp" +#include "enchantmentcheck.hpp" CSMDoc::OperationHolder *CSMTools::Tools::get (int type) { @@ -128,6 +129,8 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier() mVerifierOperation->appendStage (new JournalCheckStage(mData.getJournals(), mData.getJournalInfos())); + mVerifierOperation->appendStage (new EnchantmentCheckStage(mData.getEnchantments())); + mVerifier.setOperation (mVerifierOperation); } From 5d1c1f25f79ed21432503ebb3fdc6b4a935e3352 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Mon, 3 Sep 2018 16:57:01 +0300 Subject: [PATCH 30/35] Remove now redundant NPC fields checks --- .../opencs/model/tools/referenceablecheck.cpp | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index def6dece3..d31b8b7d0 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -667,9 +667,6 @@ void CSMTools::ReferenceableCheckStage::npcCheck ( return; short level(npc.mNpdt.mLevel); - char disposition(npc.mNpdt.mDisposition); - char reputation(npc.mNpdt.mReputation); - char rank(npc.mNpdt.mRank); int gold(npc.mNpdt.mGold); if (npc.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) //12 = autocalculated @@ -719,22 +716,8 @@ void CSMTools::ReferenceableCheckStage::npcCheck ( else if (mRaces.searchId (npc.mRace) == -1) messages.add(id, "Race '" + npc.mRace + "' does not exist", "", CSMDoc::Message::Severity_Error); - if (disposition < 0) - messages.add(id, "Disposition is negative", "", CSMDoc::Message::Severity_Warning); - - if (reputation < 0) - { - messages.add(id, "Reputation is negative", "", CSMDoc::Message::Severity_Warning); - } - - if (!npc.mFaction.empty()) - { - if (rank < 0) - messages.add(id, "Faction rank is negative", "", CSMDoc::Message::Severity_Warning); - - if (mFactions.searchId(npc.mFaction) == -1) - messages.add(id, "Faction '" + npc.mFaction + "' does not exist", "", CSMDoc::Message::Severity_Error); - } + if (!npc.mFaction.empty() && mFactions.searchId(npc.mFaction) == -1) + messages.add(id, "Faction '" + npc.mFaction + "' does not exist", "", CSMDoc::Message::Severity_Error); if (npc.mHead.empty()) messages.add(id, "Head is missing", "", CSMDoc::Message::Severity_Error); From d6560d3f20dc5dd889088bc796e5bf0032610508 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Tue, 4 Sep 2018 16:08:09 +0300 Subject: [PATCH 31/35] Make several messages more strict and clean up topic info verifier --- apps/opencs/model/tools/classcheck.cpp | 11 ++--- apps/opencs/model/tools/factioncheck.cpp | 6 +-- .../opencs/model/tools/referenceablecheck.cpp | 2 +- apps/opencs/model/tools/topicinfocheck.cpp | 45 +++++-------------- 4 files changed, 18 insertions(+), 46 deletions(-) diff --git a/apps/opencs/model/tools/classcheck.cpp b/apps/opencs/model/tools/classcheck.cpp index 25cca8fcd..a82121597 100644 --- a/apps/opencs/model/tools/classcheck.cpp +++ b/apps/opencs/model/tools/classcheck.cpp @@ -36,12 +36,7 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages) // A class should have a name if (class_.mName.empty()) - { - if (class_.mData.mIsPlayable != 0) - messages.add(id, "Name of a playable class is missing", "", CSMDoc::Message::Severity_Error); - else - messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Warning); - } + messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); // A playable class should have a description if (class_.mData.mIsPlayable != 0 && class_.mDescription.empty()) @@ -56,7 +51,7 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages) if (class_.mData.mAttribute[0]==class_.mData.mAttribute[1] && class_.mData.mAttribute[0]!=-1) { - messages.add(id, "Same attribute is listed twice", "", CSMDoc::Message::Severity_Warning); + messages.add(id, "Same attribute is listed twice", "", CSMDoc::Message::Severity_Error); } // test for non-unique skill @@ -69,6 +64,6 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages) for (auto &skill : skills) if (skill.second>1) { - messages.add(id, "Skill " + ESM::Skill::indexToId (skill.first) + " is listed more than once", "", CSMDoc::Message::Severity_Warning); + messages.add(id, "Skill " + ESM::Skill::indexToId (skill.first) + " is listed more than once", "", CSMDoc::Message::Severity_Error); } } diff --git a/apps/opencs/model/tools/factioncheck.cpp b/apps/opencs/model/tools/factioncheck.cpp index 5bd613851..0ee245ad4 100644 --- a/apps/opencs/model/tools/factioncheck.cpp +++ b/apps/opencs/model/tools/factioncheck.cpp @@ -37,12 +37,12 @@ void CSMTools::FactionCheckStage::perform (int stage, CSMDoc::Messages& messages // test for empty name if (faction.mName.empty()) - messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Warning); + messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); // test for invalid attributes if (faction.mData.mAttribute[0]==faction.mData.mAttribute[1] && faction.mData.mAttribute[0]!=-1) { - messages.add(id, "Same attribute is listed twice", "", CSMDoc::Message::Severity_Warning); + messages.add(id, "Same attribute is listed twice", "", CSMDoc::Message::Severity_Error); } // test for non-unique skill @@ -55,7 +55,7 @@ void CSMTools::FactionCheckStage::perform (int stage, CSMDoc::Messages& messages for (auto &skill : skills) if (skill.second>1) { - messages.add(id, "Skill " + ESM::Skill::indexToId (skill.first) + " is listed more than once", "", CSMDoc::Message::Severity_Warning); + messages.add(id, "Skill " + ESM::Skill::indexToId (skill.first) + " is listed more than once", "", CSMDoc::Message::Severity_Error); } /// \todo check data members that can't be edited in the table view diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index d31b8b7d0..fdbab7fd0 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -475,7 +475,7 @@ void CSMTools::ReferenceableCheckStage::creatureCheck ( if (creature.mData.mAttack[i] < 0) messages.add(id, "Attack " + std::to_string(i/2 + 1) + " has negative" + (i % 2 == 0 ? " minimum " : " maximum ") + "damage", "", CSMDoc::Message::Severity_Error); if (i % 2 == 0 && creature.mData.mAttack[i] > creature.mData.mAttack[i+1]) - messages.add(id, "Attack " + std::to_string(i/2 + 1) + " has minimum damage higher than maximum damage", "", CSMDoc::Message::Severity_Warning); + messages.add(id, "Attack " + std::to_string(i/2 + 1) + " has minimum damage higher than maximum damage", "", CSMDoc::Message::Severity_Error); } if (creature.mData.mGold < 0) diff --git a/apps/opencs/model/tools/topicinfocheck.cpp b/apps/opencs/model/tools/topicinfocheck.cpp index 9a31db72b..fe9bc991d 100644 --- a/apps/opencs/model/tools/topicinfocheck.cpp +++ b/apps/opencs/model/tools/topicinfocheck.cpp @@ -133,7 +133,6 @@ void CSMTools::TopicInfoCheckStage::perform(int stage, CSMDoc::Messages& message if (topicInfo.mData.mGender < -1 || topicInfo.mData.mGender > 1) { - std::ostringstream stream; messages.add(id, "Gender is invalid", "", CSMDoc::Message::Severity_Error); } @@ -170,16 +169,12 @@ bool CSMTools::TopicInfoCheckStage::verifyActor(const std::string& actor, const if (index.first == -1) { - std::ostringstream stream; - stream << "Actor '" << actor << "' does not exist"; - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); + messages.add(id, "Actor '" + actor + "' does not exist", "", CSMDoc::Message::Severity_Error); return false; } else if (mReferencables.getRecord(index).isDeleted()) { - std::ostringstream stream; - stream << "Deleted actor '" << actor << "' is being referenced"; - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); + messages.add(id, "Deleted actor '" + actor + "' is being referenced", "", CSMDoc::Message::Severity_Error); return false; } else if (index.second != CSMWorld::UniversalId::Type_Npc && index.second != CSMWorld::UniversalId::Type_Creature) @@ -199,9 +194,7 @@ bool CSMTools::TopicInfoCheckStage::verifyCell(const std::string& cell, const CS { if (mCellNames.find(cell) == mCellNames.end()) { - std::ostringstream stream; - stream << "Cell '" << cell << "' does not exist"; - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); + messages.add(id, "Cell '" + cell + "' does not exist", "", CSMDoc::Message::Severity_Error); return false; } @@ -236,7 +229,7 @@ bool CSMTools::TopicInfoCheckStage::verifyFactionRank(const std::string& faction stream << "Faction rank is set to " << rank << " which is more than the maximum of " << limit - 1 << " for the '" << factionName << "' faction"; - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Warning); + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); return false; } @@ -250,16 +243,12 @@ bool CSMTools::TopicInfoCheckStage::verifyItem(const std::string& item, const CS if (index.first == -1) { - std::ostringstream stream; - stream << "Item '" << item << "' does not exist"; - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); + messages.add(id, ("Item '" + item + "' does not exist"), "", CSMDoc::Message::Severity_Error); return false; } else if (mReferencables.getRecord(index).isDeleted()) { - std::ostringstream stream; - stream << "Deleted item '" << item << "' is being referenced"; - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); + messages.add(id, ("Deleted item '" + item + "' is being referenced"), "", CSMDoc::Message::Severity_Error); return false; } else @@ -327,18 +316,12 @@ bool CSMTools::TopicInfoCheckStage::verifySelectStruct(const ESM::DialInfo::Sele } else if (infoCondition.conditionIsAlwaysTrue()) { - std::ostringstream stream; - stream << "Condition '" << infoCondition.toString() << "' is always true"; - - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Warning); + messages.add(id, "Condition '" + infoCondition.toString() + "' is always true", "", CSMDoc::Message::Severity_Warning); return false; } else if (infoCondition.conditionIsNeverTrue()) { - std::ostringstream stream; - stream << "Condition '" << infoCondition.toString() << "' is never true"; - - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Warning); + messages.add(id, "Condition '" + infoCondition.toString() + "' is never true", "", CSMDoc::Message::Severity_Warning); return false; } @@ -397,9 +380,7 @@ bool CSMTools::TopicInfoCheckStage::verifySound(const std::string& sound, const { if (mSoundFiles.searchId(sound) == -1) { - std::ostringstream stream; - stream << "Sound file '" << sound << "' does not exist"; - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); + messages.add(id, "Sound file '" + sound + "' does not exist", "", CSMDoc::Message::Severity_Error); return false; } @@ -414,16 +395,12 @@ bool CSMTools::TopicInfoCheckStage::verifyId(const std::string& name, const CSMW if (index == -1) { - std::ostringstream stream; - stream << T::getRecordType() + " '" << name << "' does not exist"; - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); + messages.add(id, T::getRecordType() + " '" + name + "' does not exist", "", CSMDoc::Message::Severity_Error); return false; } else if (collection.getRecord(index).isDeleted()) { - std::ostringstream stream; - stream << "Deleted " << T::getRecordType() << " record '" << name << "' is being referenced"; - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); + messages.add(id, "Deleted " + T::getRecordType() + " record '" + name + "' is being referenced", "", CSMDoc::Message::Severity_Error); return false; } From c025427575e7279f2871a982f2a6213f3a4b9642 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Tue, 11 Sep 2018 21:40:41 +0300 Subject: [PATCH 32/35] Implement enchantment record effect list verification (feature #1617) --- apps/opencs/model/tools/enchantmentcheck.cpp | 42 +++++++++++++++++++- apps/opencs/model/tools/enchantmentcheck.hpp | 1 + 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/enchantmentcheck.cpp b/apps/opencs/model/tools/enchantmentcheck.cpp index e1dca9331..28f2b32cb 100644 --- a/apps/opencs/model/tools/enchantmentcheck.cpp +++ b/apps/opencs/model/tools/enchantmentcheck.cpp @@ -38,5 +38,45 @@ void CSMTools::EnchantmentCheckStage::perform (int stage, CSMDoc::Messages& mess if (enchantment.mData.mCharge < 0) messages.add(id, "Charge is negative", "", CSMDoc::Message::Severity_Error); - /// \todo Check effects list for validity + if (enchantment.mData.mCost > enchantment.mData.mCharge) + messages.add(id, "Cost is higher than charge", "", CSMDoc::Message::Severity_Error); + + if (enchantment.mEffects.mList.empty()) + { + messages.add(id, "Enchantment doesn't have any magic effects", "", CSMDoc::Message::Severity_Warning); + } + else + { + std::vector::const_iterator effect = enchantment.mEffects.mList.begin(); + + for (size_t i = 1; i <= enchantment.mEffects.mList.size(); i++) + { + const std::string number = std::to_string(i); + // At the time of writing this effects, attributes and skills are hardcoded + if (effect->mEffectID < 0 || effect->mEffectID > 142) + { + messages.add(id, "Effect #" + number + " is invalid", "", CSMDoc::Message::Severity_Error); + ++effect; + continue; + } + + if (effect->mSkill < -1 || effect->mSkill > 26) + messages.add(id, "Effect #" + number + " affected skill is invalid", "", CSMDoc::Message::Severity_Error); + if (effect->mAttribute < -1 || effect->mAttribute > 7) + messages.add(id, "Effect #" + number + " affected attribute is invalid", "", CSMDoc::Message::Severity_Error); + if (effect->mRange < 0 || effect->mRange > 2) + messages.add(id, "Effect #" + number + " range is invalid", "", CSMDoc::Message::Severity_Error); + if (effect->mArea < 0) + messages.add(id, "Effect #" + number + " area is negative", "", CSMDoc::Message::Severity_Error); + if (effect->mDuration < 0) + messages.add(id, "Effect #" + number + " duration is negative", "", CSMDoc::Message::Severity_Error); + if (effect->mMagnMin < 0) + messages.add(id, "Effect #" + number + " minimum magnitude is negative", "", CSMDoc::Message::Severity_Error); + if (effect->mMagnMax < 0) + messages.add(id, "Effect #" + number + " maximum magnitude is negative", "", CSMDoc::Message::Severity_Error); + if (effect->mMagnMin > effect->mMagnMax) + messages.add(id, "Effect #" + number + " minimum magnitude is higher than maximum magnitude", "", CSMDoc::Message::Severity_Error); + ++effect; + } + } } diff --git a/apps/opencs/model/tools/enchantmentcheck.hpp b/apps/opencs/model/tools/enchantmentcheck.hpp index ba8ae64aa..3bd85326f 100644 --- a/apps/opencs/model/tools/enchantmentcheck.hpp +++ b/apps/opencs/model/tools/enchantmentcheck.hpp @@ -24,6 +24,7 @@ namespace CSMTools virtual void perform (int stage, CSMDoc::Messages& messages); ///< Messages resulting from this tage will be appended to \a messages. + }; } From 5a86554f97f87c52add041865a4fdcd2a5dee6bd Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 14 Sep 2018 21:42:11 +0300 Subject: [PATCH 33/35] Cleanup --- apps/opencs/model/tools/birthsigncheck.cpp | 6 +----- apps/opencs/model/tools/factioncheck.cpp | 2 -- apps/opencs/model/tools/journalcheck.cpp | 7 ++----- apps/opencs/model/tools/magiceffectcheck.hpp | 2 -- apps/opencs/model/tools/racecheck.cpp | 10 ++-------- apps/opencs/model/tools/regioncheck.cpp | 5 ----- apps/opencs/model/tools/skillcheck.cpp | 4 +--- apps/opencs/model/tools/soundcheck.cpp | 4 +--- apps/opencs/model/tools/soundgencheck.cpp | 2 -- 9 files changed, 7 insertions(+), 35 deletions(-) diff --git a/apps/opencs/model/tools/birthsigncheck.cpp b/apps/opencs/model/tools/birthsigncheck.cpp index a0ae4b11f..f91fc22f6 100644 --- a/apps/opencs/model/tools/birthsigncheck.cpp +++ b/apps/opencs/model/tools/birthsigncheck.cpp @@ -1,6 +1,5 @@ #include "birthsigncheck.hpp" -#include #include #include "../prefs/state.hpp" @@ -42,11 +41,8 @@ void CSMTools::BirthsignCheckStage::perform (int stage, CSMDoc::Messages& messag if (birthsign.mTexture.empty()) messages.add(id, "Image is missing", "", CSMDoc::Message::Severity_Error); - else + else if (mTextures.searchId(birthsign.mTexture) == -1) { - if (mTextures.searchId(birthsign.mTexture) != -1) - return; - std::string ddsTexture = birthsign.mTexture; if (!(Misc::ResourceHelpers::changeExtensionToDds(ddsTexture) && mTextures.searchId(ddsTexture) != -1)) messages.add(id, "Image '" + birthsign.mTexture + "' does not exist", "", CSMDoc::Message::Severity_Error); diff --git a/apps/opencs/model/tools/factioncheck.cpp b/apps/opencs/model/tools/factioncheck.cpp index 0ee245ad4..8a198e953 100644 --- a/apps/opencs/model/tools/factioncheck.cpp +++ b/apps/opencs/model/tools/factioncheck.cpp @@ -1,9 +1,7 @@ #include "factioncheck.hpp" -#include #include -#include #include #include "../prefs/state.hpp" diff --git a/apps/opencs/model/tools/journalcheck.cpp b/apps/opencs/model/tools/journalcheck.cpp index dc15b26ee..ae83abfa0 100644 --- a/apps/opencs/model/tools/journalcheck.cpp +++ b/apps/opencs/model/tools/journalcheck.cpp @@ -1,7 +1,6 @@ #include "journalcheck.hpp" #include -#include #include "../prefs/state.hpp" @@ -63,12 +62,10 @@ void CSMTools::JournalCheckStage::perform(int stage, CSMDoc::Messages& messages) std::pair::iterator, bool> result = questIndices.insert(journalInfo.mData.mJournalIndex); // Duplicate index - if (result.second == false) + if (!result.second) { CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_JournalInfo, journalInfo.mId); - std::ostringstream stream; - stream << "Duplicated quest index " << journalInfo.mData.mJournalIndex; - messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); + messages.add(id, "Duplicated quest index " + std::to_string(journalInfo.mData.mJournalIndex), "", CSMDoc::Message::Severity_Error); } } diff --git a/apps/opencs/model/tools/magiceffectcheck.hpp b/apps/opencs/model/tools/magiceffectcheck.hpp index 22dad3db9..a52723b0f 100644 --- a/apps/opencs/model/tools/magiceffectcheck.hpp +++ b/apps/opencs/model/tools/magiceffectcheck.hpp @@ -23,9 +23,7 @@ namespace CSMTools bool mIgnoreBaseRecords; private: - std::string checkTexture(const std::string &texture, bool isIcon) const; std::string checkObject(const std::string &id, const CSMWorld::UniversalId &type, const std::string &column) const; - std::string checkSound(const std::string &id, const std::string &column) const; public: MagicEffectCheckStage(const CSMWorld::IdCollection &effects, diff --git a/apps/opencs/model/tools/racecheck.cpp b/apps/opencs/model/tools/racecheck.cpp index 3b487b925..6585a31cc 100644 --- a/apps/opencs/model/tools/racecheck.cpp +++ b/apps/opencs/model/tools/racecheck.cpp @@ -1,9 +1,5 @@ #include "racecheck.hpp" -#include - -#include - #include "../prefs/state.hpp" #include "../world/universalid.hpp" @@ -28,10 +24,8 @@ void CSMTools::RaceCheckStage::performPerRecord (int stage, CSMDoc::Messages& me CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Race, race.mId); // test for empty name and description - if (race.mName.empty() && race.mData.mFlags & 0x1) - messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); - else if (race.mName.empty()) - messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Warning); + if (race.mName.empty()) + messages.add(id, "Name is missing", "", (race.mData.mFlags & 0x1) ? CSMDoc::Message::Severity_Error : CSMDoc::Message::Severity_Warning); if (race.mDescription.empty()) messages.add(id, "Description is missing", "", CSMDoc::Message::Severity_Warning); diff --git a/apps/opencs/model/tools/regioncheck.cpp b/apps/opencs/model/tools/regioncheck.cpp index 8375e3f0a..0b6537d7f 100644 --- a/apps/opencs/model/tools/regioncheck.cpp +++ b/apps/opencs/model/tools/regioncheck.cpp @@ -1,10 +1,5 @@ #include "regioncheck.hpp" -#include -#include - -#include - #include "../prefs/state.hpp" #include "../world/universalid.hpp" diff --git a/apps/opencs/model/tools/skillcheck.cpp b/apps/opencs/model/tools/skillcheck.cpp index 89eba011a..c5b38dc1e 100644 --- a/apps/opencs/model/tools/skillcheck.cpp +++ b/apps/opencs/model/tools/skillcheck.cpp @@ -1,7 +1,5 @@ #include "skillcheck.hpp" -#include - #include "../prefs/state.hpp" #include "../world/universalid.hpp" @@ -37,6 +35,6 @@ void CSMTools::SkillCheckStage::perform (int stage, CSMDoc::Messages& messages) for (int i=0; i<4; ++i) if (skill.mData.mUseValue[i]<0) { - messages.add(id, "Usage experience value #" + std::to_string(i) + " is negative", "", CSMDoc::Message::Severity_Error); + messages.add(id, "Use value #" + std::to_string(i) + " is negative", "", CSMDoc::Message::Severity_Error); } } diff --git a/apps/opencs/model/tools/soundcheck.cpp b/apps/opencs/model/tools/soundcheck.cpp index 09e5ecdbf..c0d893f1a 100644 --- a/apps/opencs/model/tools/soundcheck.cpp +++ b/apps/opencs/model/tools/soundcheck.cpp @@ -1,7 +1,5 @@ #include "soundcheck.hpp" -#include - #include "../prefs/state.hpp" #include "../world/universalid.hpp" @@ -35,7 +33,7 @@ void CSMTools::SoundCheckStage::perform (int stage, CSMDoc::Messages& messages) if (sound.mData.mMinRange>sound.mData.mMaxRange) { - messages.add(id, "Minimum range larger than maximum range", "", CSMDoc::Message::Severity_Warning); + messages.add(id, "Minimum range is larger than maximum range", "", CSMDoc::Message::Severity_Warning); } if (sound.mSound.empty()) diff --git a/apps/opencs/model/tools/soundgencheck.cpp b/apps/opencs/model/tools/soundgencheck.cpp index 7b6cf7a4b..ec29e23fe 100644 --- a/apps/opencs/model/tools/soundgencheck.cpp +++ b/apps/opencs/model/tools/soundgencheck.cpp @@ -1,7 +1,5 @@ #include "soundgencheck.hpp" -#include - #include "../prefs/state.hpp" #include "../world/refiddata.hpp" From 95aa05e41be646c7ce556789f4c75619cfcfa6b6 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 16 Sep 2018 16:47:33 +0300 Subject: [PATCH 34/35] Tweaks to script parser messages and pathgrid warnings --- apps/opencs/model/tools/pathgridcheck.cpp | 18 ++++++++---------- apps/opencs/model/tools/scriptcheck.cpp | 2 +- components/compiler/declarationparser.cpp | 2 +- components/compiler/exprparser.cpp | 8 ++++---- components/compiler/junkparser.cpp | 4 ++-- components/compiler/lineparser.cpp | 18 +++++++++--------- 6 files changed, 25 insertions(+), 27 deletions(-) diff --git a/apps/opencs/model/tools/pathgridcheck.cpp b/apps/opencs/model/tools/pathgridcheck.cpp index 88750ad7f..febb79c64 100644 --- a/apps/opencs/model/tools/pathgridcheck.cpp +++ b/apps/opencs/model/tools/pathgridcheck.cpp @@ -56,8 +56,7 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message if (pointList[pathgrid.mEdges[i].mV0].mOtherIndex[j] == pathgrid.mEdges[i].mV1) { std::ostringstream ss; - ss << "Duplicate edge between points" - << pathgrid.mEdges[i].mV0 << " and " << pathgrid.mEdges[i].mV1; + ss << "Duplicate edge between points #" << pathgrid.mEdges[i].mV0 << " and #" << pathgrid.mEdges[i].mV1; messages.add (id, ss.str(), "", CSMDoc::Message::Severity_Error); break; } @@ -70,7 +69,7 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message else { std::ostringstream ss; - ss << "An edge is connected to a non-existent point " << pathgrid.mEdges[i].mV0; + ss << "An edge is connected to a non-existent point #" << pathgrid.mEdges[i].mV0; messages.add (id, ss.str(), "", CSMDoc::Message::Severity_Error); } } @@ -93,7 +92,7 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message if (!foundReverse) { std::ostringstream ss; - ss << "Missing edge between points " << i << " and " << pointList[i].mOtherIndex[j]; + ss << "Missing edge between points #" << i << " and #" << pointList[i].mOtherIndex[j]; messages.add (id, ss.str(), "", CSMDoc::Message::Severity_Error); } } @@ -110,7 +109,7 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message if (it == duplList.end()) { std::ostringstream ss; - ss << "Point " << i << " duplicates point " << j + ss << "Point #" << i << " duplicates point #" << j << " (" << pathgrid.mPoints[i].mX << ", " << pathgrid.mPoints[i].mY << ", " << pathgrid.mPoints[i].mZ << ")"; messages.add (id, ss.str(), "", CSMDoc::Message::Severity_Warning); @@ -127,11 +126,10 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message if (pointList[i].mConnectionNum == 0) { std::ostringstream ss; - ss << "Point " << i << " (" - << pathgrid.mPoints[i].mX << ", " - << pathgrid.mPoints[i].mY << ", " - << pathgrid.mPoints[i].mZ << ") " - << "is disconnected from other points"; + ss << "Point #" << i << " (" + << pathgrid.mPoints[i].mX << ", " + << pathgrid.mPoints[i].mY << ", " + << pathgrid.mPoints[i].mZ << ") is disconnected from other points"; messages.add (id, ss.str(), "", CSMDoc::Message::Severity_Warning); } } diff --git a/apps/opencs/model/tools/scriptcheck.cpp b/apps/opencs/model/tools/scriptcheck.cpp index e62f9eb88..d3d9d1503 100644 --- a/apps/opencs/model/tools/scriptcheck.cpp +++ b/apps/opencs/model/tools/scriptcheck.cpp @@ -30,7 +30,7 @@ void CSMTools::ScriptCheckStage::report (const std::string& message, const Compi CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId); - stream << "Line " << loc.mLine << ", column " << loc.mColumn << " (" << loc.mLiteral << "): " << message; + stream << "line " << loc.mLine << ", column " << loc.mColumn << ": " << message << " (" << loc.mLiteral << ")"; std::ostringstream hintStream; diff --git a/components/compiler/declarationparser.cpp b/components/compiler/declarationparser.cpp index ffac252d5..e85c8c3ec 100644 --- a/components/compiler/declarationparser.cpp +++ b/components/compiler/declarationparser.cpp @@ -24,7 +24,7 @@ bool Compiler::DeclarationParser::parseName (const std::string& name, const Toke if (type!=' ') { /// \todo add option to make re-declared local variables an error - getErrorHandler().warning ("can't re-declare local variable (ignoring declaration)", + getErrorHandler().warning ("ignoring local variable re-declaration", loc); mState = State_End; diff --git a/components/compiler/exprparser.cpp b/components/compiler/exprparser.cpp index 7cb0abfd1..6b849ec3a 100644 --- a/components/compiler/exprparser.cpp +++ b/components/compiler/exprparser.cpp @@ -422,7 +422,7 @@ namespace Compiler { if (!hasExplicit) { - getErrorHandler().warning ("stray explicit reference (ignoring it)", loc); + getErrorHandler().warning ("ignoring stray explicit reference", loc); mExplicit.clear(); } @@ -791,7 +791,7 @@ namespace Compiler ++optionalCount; } else - getErrorHandler().warning ("Ignoring extra argument", + getErrorHandler().warning ("ignoring extra argument", stringParser.getTokenLoc()); } else if (*iter=='X') @@ -805,7 +805,7 @@ namespace Compiler if (parser.isEmpty()) break; else - getErrorHandler().warning("Ignoring extra argument", parser.getTokenLoc()); + getErrorHandler().warning("ignoring extra argument", parser.getTokenLoc()); } else if (*iter=='z') { @@ -817,7 +817,7 @@ namespace Compiler if (discardParser.isEmpty()) break; else - getErrorHandler().warning("Ignoring extra argument", discardParser.getTokenLoc()); + getErrorHandler().warning("ignoring extra argument", discardParser.getTokenLoc()); } else if (*iter=='j') { diff --git a/components/compiler/junkparser.cpp b/components/compiler/junkparser.cpp index 7608e9bab..5910cca43 100644 --- a/components/compiler/junkparser.cpp +++ b/components/compiler/junkparser.cpp @@ -29,7 +29,7 @@ bool Compiler::JunkParser::parseName (const std::string& name, const TokenLoc& l bool Compiler::JunkParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) { if (keyword==mIgnoreKeyword) - reportWarning ("found junk (ignoring it)", loc); + reportWarning ("ignoring found junk", loc); else scanner.putbackKeyword (keyword, loc); @@ -39,7 +39,7 @@ bool Compiler::JunkParser::parseKeyword (int keyword, const TokenLoc& loc, Scann bool Compiler::JunkParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) { if (code==Scanner::S_member) - reportWarning ("found junk (ignoring it)", loc); + reportWarning ("ignoring found junk", loc); else scanner.putbackSpecial (code, loc); diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index c2c1dff9b..3f9d2e790 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -88,7 +88,7 @@ namespace Compiler { if (mState==PotentialEndState) { - getErrorHandler().warning ("stray string argument (ignoring it)", loc); + getErrorHandler().warning ("ignoring stray string argument", loc); mState = EndState; return true; } @@ -233,7 +233,7 @@ namespace Compiler if (mState==SetPotentialMemberVarState && keyword==Scanner::K_to) { - getErrorHandler().warning ("unknown variable (ignoring set instruction)", loc); + getErrorHandler().warning ("unknown variable, ignoring set instruction", loc); SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); return false; @@ -286,7 +286,7 @@ namespace Compiler { if (!hasExplicit && mState==ExplicitState) { - getErrorHandler().warning ("stray explicit reference (ignoring it)", loc); + getErrorHandler().warning ("ignoring stray explicit reference", loc); mExplicit.clear(); } @@ -344,7 +344,7 @@ namespace Compiler { if (!hasExplicit && !mExplicit.empty()) { - getErrorHandler().warning ("stray explicit reference (ignoring it)", loc); + getErrorHandler().warning ("ignoring stray explicit reference", loc); mExplicit.clear(); } @@ -360,7 +360,7 @@ namespace Compiler if (mState==ExplicitState) { // drop stray explicit reference - getErrorHandler().warning ("stray explicit reference (ignoring it)", loc); + getErrorHandler().warning ("ignoring stray explicit reference", loc); mState = BeginState; mExplicit.clear(); } @@ -412,19 +412,19 @@ namespace Compiler case Scanner::K_else: - getErrorHandler().warning ("stray else (ignoring it)", loc); + getErrorHandler().warning ("ignoring stray else", loc); mState = EndState; return true; case Scanner::K_endif: - getErrorHandler().warning ("stray endif (ignoring it)", loc); + getErrorHandler().warning ("ignoring stray endif", loc); mState = EndState; return true; case Scanner::K_begin: - getErrorHandler().warning ("stray begin (ignoring it)", loc); + getErrorHandler().warning ("ignoring stray begin", loc); mState = EndState; return true; } @@ -491,7 +491,7 @@ namespace Compiler { if (mState==EndState && code==Scanner::S_open) { - getErrorHandler().warning ("stray '[' or '(' at the end of the line (ignoring it)", + getErrorHandler().warning ("ignoring stray '[' or '(' at the end of the line", loc); return true; } From 2f054cc7a8f1f2c8196522419cb32a985f4ad653 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 16 Sep 2018 17:09:47 +0300 Subject: [PATCH 35/35] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bea04fcb..af29a67e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -121,6 +121,7 @@ Bug #4628: NPC record reputation, disposition and faction rank should have unsigned char type Bug #4633: Sneaking stance affects speed even if the actor is not able to crouch Feature #912: Editor: Add missing icons to UniversalId tables + Feature #1617: Editor: Enchantment effect record verifier Feature #1645: Casting effects from objects Feature #2606: Editor: Implemented (optional) case sensitive global search Feature #3083: Play animation when NPC is casting spell via script @@ -155,6 +156,7 @@ Task #4606: Support Rapture3D's OpenAL driver Task #4613: Incomplete type errors when compiling with g++ on OSX 10.9 Task #4621: Optimize combat AI + Task #4643: Revise editor record verifying functionality 0.44.0 ------