mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-27 12:35:46 +00:00
Editor: Verify magic effects for enchantments, ingredients and potions
Use constants for known magic effect/skill/attribute range
This commit is contained in:
parent
89eccffbf6
commit
2fdbd6287d
@ -10,6 +10,7 @@
|
|||||||
#include <apps/opencs/model/world/idcollection.hpp>
|
#include <apps/opencs/model/world/idcollection.hpp>
|
||||||
#include <apps/opencs/model/world/record.hpp>
|
#include <apps/opencs/model/world/record.hpp>
|
||||||
|
|
||||||
|
#include <components/esm/attr.hpp>
|
||||||
#include <components/esm3/effectlist.hpp>
|
#include <components/esm3/effectlist.hpp>
|
||||||
#include <components/esm3/loadench.hpp>
|
#include <components/esm3/loadench.hpp>
|
||||||
|
|
||||||
@ -65,18 +66,13 @@ void CSMTools::EnchantmentCheckStage::perform(int stage, CSMDoc::Messages& messa
|
|||||||
for (size_t i = 1; i <= enchantment.mEffects.mList.size(); i++)
|
for (size_t i = 1; i <= enchantment.mEffects.mList.size(); i++)
|
||||||
{
|
{
|
||||||
const std::string number = std::to_string(i);
|
const std::string number = std::to_string(i);
|
||||||
// At the time of writing this effects, attributes and skills are hardcoded
|
// At the time of writing this effects, attributes and skills are mostly hardcoded
|
||||||
if (effect->mData.mEffectID < 0 || effect->mData.mEffectID > 142)
|
if (effect->mData.mEffectID < 0 || effect->mData.mEffectID > ESM::MagicEffect::Length)
|
||||||
{
|
|
||||||
messages.add(id, "Effect #" + number + " is invalid", "", CSMDoc::Message::Severity_Error);
|
messages.add(id, "Effect #" + number + " is invalid", "", CSMDoc::Message::Severity_Error);
|
||||||
++effect;
|
if (effect->mData.mSkill < -1 || effect->mData.mSkill > ESM::Skill::Length)
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (effect->mData.mSkill < -1 || effect->mData.mSkill > 26)
|
|
||||||
messages.add(
|
messages.add(
|
||||||
id, "Effect #" + number + " affected skill is invalid", "", CSMDoc::Message::Severity_Error);
|
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(
|
messages.add(
|
||||||
id, "Effect #" + number + " affected attribute is invalid", "", CSMDoc::Message::Severity_Error);
|
id, "Effect #" + number + " affected attribute is invalid", "", CSMDoc::Message::Severity_Error);
|
||||||
if (effect->mData.mRange < 0 || effect->mData.mRange > 2)
|
if (effect->mData.mRange < 0 || effect->mData.mRange > 2)
|
||||||
|
@ -330,7 +330,45 @@ void CSMTools::ReferenceableCheckStage::potionCheck(
|
|||||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Potion, potion.mId);
|
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Potion, potion.mId);
|
||||||
|
|
||||||
inventoryItemCheck<ESM::Potion>(potion, messages, id.toString());
|
inventoryItemCheck<ESM::Potion>(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<ESM::IndexedENAMstruct>::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
|
// Check that mentioned scripts exist
|
||||||
scriptCheck<ESM::Potion>(potion, messages, id.toString());
|
scriptCheck<ESM::Potion>(potion, messages, id.toString());
|
||||||
@ -565,6 +603,28 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck(
|
|||||||
|
|
||||||
// Check that mentioned scripts exist
|
// Check that mentioned scripts exist
|
||||||
scriptCheck<ESM::Ingredient>(ingredient, messages, id.toString());
|
scriptCheck<ESM::Ingredient>(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(
|
void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <apps/opencs/model/world/record.hpp>
|
#include <apps/opencs/model/world/record.hpp>
|
||||||
#include <apps/opencs/model/world/universalid.hpp>
|
#include <apps/opencs/model/world/universalid.hpp>
|
||||||
|
|
||||||
|
#include <components/esm/attr.hpp>
|
||||||
#include <components/esm3/loadspel.hpp>
|
#include <components/esm3/loadspel.hpp>
|
||||||
|
|
||||||
#include "../prefs/state.hpp"
|
#include "../prefs/state.hpp"
|
||||||
@ -46,5 +47,42 @@ void CSMTools::SpellCheckStage::perform(int stage, CSMDoc::Messages& messages)
|
|||||||
if (spell.mData.mCost < 0)
|
if (spell.mData.mCost < 0)
|
||||||
messages.add(id, "Spell cost is negative", "", CSMDoc::Message::Severity_Error);
|
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<ESM::IndexedENAMstruct>::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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user