diff --git a/apps/opencs/model/tools/enchantmentcheck.cpp b/apps/opencs/model/tools/enchantmentcheck.cpp index 48cee579be..e12bfabca4 100644 --- a/apps/opencs/model/tools/enchantmentcheck.cpp +++ b/apps/opencs/model/tools/enchantmentcheck.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -65,18 +66,13 @@ void CSMTools::EnchantmentCheckStage::perform(int stage, CSMDoc::Messages& messa 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->mData.mEffectID < 0 || effect->mData.mEffectID > 142) - { + // At the time of writing this effects, attributes and skills are mostly hardcoded + if (effect->mData.mEffectID < 0 || effect->mData.mEffectID > ESM::MagicEffect::Length) messages.add(id, "Effect #" + number + " is invalid", "", CSMDoc::Message::Severity_Error); - ++effect; - continue; - } - - if (effect->mData.mSkill < -1 || effect->mData.mSkill > 26) + if (effect->mData.mSkill < -1 || effect->mData.mSkill > ESM::Skill::Length) messages.add( id, "Effect #" + number + " affected skill is invalid", "", CSMDoc::Message::Severity_Error); - if (effect->mData.mAttribute < -1 || effect->mData.mAttribute > 7) + if (effect->mData.mAttribute < -1 || effect->mData.mAttribute > ESM::Attribute::Length) messages.add( id, "Effect #" + number + " affected attribute is invalid", "", CSMDoc::Message::Severity_Error); if (effect->mData.mRange < 0 || effect->mData.mRange > 2) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index a692bc10d1..272521b420 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -330,7 +330,45 @@ void CSMTools::ReferenceableCheckStage::potionCheck( CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Potion, potion.mId); inventoryItemCheck(potion, messages, id.toString()); - /// \todo Check magic effects for validity + + if (potion.mEffects.mList.empty()) + { + messages.add(id, "Potion doesn't have any magic effects", "", CSMDoc::Message::Severity_Warning); + } + else + { + std::vector::const_iterator effect = potion.mEffects.mList.begin(); + + for (size_t i = 1; i <= potion.mEffects.mList.size(); i++) + { + const std::string number = std::to_string(i); + // At the time of writing this effects, attributes and skills are mostly hardcoded + if (effect->mData.mEffectID < 0 || effect->mData.mEffectID > ESM::MagicEffect::Length) + messages.add(id, "Effect #" + number + " is invalid", "", CSMDoc::Message::Severity_Error); + if (effect->mData.mSkill < -1 || effect->mData.mSkill > ESM::Skill::Length) + messages.add( + id, "Effect #" + number + " affected skill is invalid", "", CSMDoc::Message::Severity_Error); + if (effect->mData.mAttribute < -1 || effect->mData.mAttribute > ESM::Attribute::Length) + messages.add( + id, "Effect #" + number + " affected attribute is invalid", "", CSMDoc::Message::Severity_Error); + if (effect->mData.mRange != ESM::RT_Self) + messages.add(id, "Effect #" + number + " range is not Self", "", CSMDoc::Message::Severity_Error); + if (effect->mData.mArea < 0) + messages.add(id, "Effect #" + number + " area is negative", "", CSMDoc::Message::Severity_Error); + if (effect->mData.mDuration < 0) + messages.add(id, "Effect #" + number + " duration is negative", "", CSMDoc::Message::Severity_Error); + if (effect->mData.mMagnMin < 0) + messages.add( + id, "Effect #" + number + " minimum magnitude is negative", "", CSMDoc::Message::Severity_Error); + if (effect->mData.mMagnMax < 0) + messages.add( + id, "Effect #" + number + " maximum magnitude is negative", "", CSMDoc::Message::Severity_Error); + if (effect->mData.mMagnMin > effect->mData.mMagnMax) + messages.add(id, "Effect #" + number + " minimum magnitude is higher than maximum magnitude", "", + CSMDoc::Message::Severity_Error); + ++effect; + } + } // Check that mentioned scripts exist scriptCheck(potion, messages, id.toString()); @@ -565,6 +603,28 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck( // Check that mentioned scripts exist scriptCheck(ingredient, messages, id.toString()); + + bool hasEffects = false; + for (size_t i = 0; i < 4; i++) + { + if (ingredient.mData.mEffectID[i] == -1) + continue; + + hasEffects = true; + + const std::string number = std::to_string(i + 1); + // At the time of writing this effects, attributes and skills are mostly hardcoded + if (ingredient.mData.mEffectID[i] < -1 || ingredient.mData.mEffectID[i] > ESM::MagicEffect::Length) + messages.add(id, "Effect #" + number + " is invalid", "", CSMDoc::Message::Severity_Error); + if (ingredient.mData.mSkills[i] < -1 || ingredient.mData.mSkills[i] > ESM::Skill::Length) + messages.add(id, "Effect #" + number + " affected skill is invalid", "", CSMDoc::Message::Severity_Error); + if (ingredient.mData.mAttributes[i] < -1 || ingredient.mData.mAttributes[i] > ESM::Attribute::Length) + messages.add( + id, "Effect #" + number + " affected attribute is invalid", "", CSMDoc::Message::Severity_Error); + } + + if (!hasEffects) + messages.add(id, "Ingredient doesn't have any magic effects", "", CSMDoc::Message::Severity_Warning); } void CSMTools::ReferenceableCheckStage::creaturesLevListCheck( diff --git a/apps/opencs/model/tools/spellcheck.cpp b/apps/opencs/model/tools/spellcheck.cpp index f91438dc22..74ed87a5cc 100644 --- a/apps/opencs/model/tools/spellcheck.cpp +++ b/apps/opencs/model/tools/spellcheck.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include "../prefs/state.hpp" @@ -46,5 +47,42 @@ void CSMTools::SpellCheckStage::perform(int stage, CSMDoc::Messages& messages) if (spell.mData.mCost < 0) messages.add(id, "Spell cost is negative", "", CSMDoc::Message::Severity_Error); - /// \todo check data members that can't be edited in the table view + if (spell.mEffects.mList.empty()) + { + messages.add(id, "Spell doesn't have any magic effects", "", CSMDoc::Message::Severity_Warning); + } + else + { + std::vector::const_iterator effect = spell.mEffects.mList.begin(); + + for (size_t i = 1; i <= spell.mEffects.mList.size(); i++) + { + const std::string number = std::to_string(i); + // At the time of writing this effects, attributes and skills are mostly hardcoded + if (effect->mData.mEffectID < 0 || effect->mData.mEffectID > ESM::MagicEffect::Length) + messages.add(id, "Effect #" + number + " is invalid", "", CSMDoc::Message::Severity_Error); + if (effect->mData.mSkill < -1 || effect->mData.mSkill > ESM::Skill::Length) + messages.add( + id, "Effect #" + number + " affected skill is invalid", "", CSMDoc::Message::Severity_Error); + if (effect->mData.mAttribute < -1 || effect->mData.mAttribute > ESM::Attribute::Length) + messages.add( + id, "Effect #" + number + " affected attribute is invalid", "", CSMDoc::Message::Severity_Error); + if (effect->mData.mRange < 0 || effect->mData.mRange > 2) + messages.add(id, "Effect #" + number + " range is invalid", "", CSMDoc::Message::Severity_Error); + if (effect->mData.mArea < 0) + messages.add(id, "Effect #" + number + " area is negative", "", CSMDoc::Message::Severity_Error); + if (effect->mData.mDuration < 0) + messages.add(id, "Effect #" + number + " duration is negative", "", CSMDoc::Message::Severity_Error); + if (effect->mData.mMagnMin < 0) + messages.add( + id, "Effect #" + number + " minimum magnitude is negative", "", CSMDoc::Message::Severity_Error); + if (effect->mData.mMagnMax < 0) + messages.add( + id, "Effect #" + number + " maximum magnitude is negative", "", CSMDoc::Message::Severity_Error); + if (effect->mData.mMagnMin > effect->mData.mMagnMax) + messages.add(id, "Effect #" + number + " minimum magnitude is higher than maximum magnitude", "", + CSMDoc::Message::Severity_Error); + ++effect; + } + } }