1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2026-02-11 19:02:06 +00:00

Merge branch 'Transform-effect-associated-skills-and-attributes-in-ENAM-and-IRDT-to-RefIds' into 'master'

Transform magic effect-associated skills and attributes in ENAM and IRDT structs to RefIds

See merge request OpenMW/openmw!5143
This commit is contained in:
Alexei Kotov 2026-02-05 18:27:45 +03:00
commit a086ff3fb6
23 changed files with 100 additions and 108 deletions

View file

@ -576,8 +576,8 @@ namespace ESM
EffectList record;
record.mList.emplace_back(IndexedENAMstruct{ {
.mEffectID = ESM::MagicEffect::SwiftSwim,
.mSkill = 2,
.mAttribute = 3,
.mSkill = ESM::Skill::MediumArmor,
.mAttribute = ESM::Attribute::Agility,
.mRange = 4,
.mArea = 5,
.mDuration = 6,

View file

@ -154,15 +154,16 @@ namespace
for (const ESM::IndexedENAMstruct& effect : effects.mList)
{
int effectIdx = ESM::MagicEffect::refIdToIndex(effect.mData.mEffectID);
int skillIdx = ESM::Skill::refIdToIndex(effect.mData.mSkill);
int attributeIdx = ESM::Attribute::refIdToIndex(effect.mData.mAttribute);
if (effectIdx != -1)
std::cout << " Effect[" << i << "]: " << magicEffectLabel(effectIdx) << " (" << effectIdx << ")"
<< std::endl;
if (effect.mData.mSkill != -1)
std::cout << " Skill: " << skillLabel(effect.mData.mSkill) << " (" << (int)effect.mData.mSkill << ")"
if (skillIdx != -1)
std::cout << " Skill: " << skillLabel(skillIdx) << " (" << skillIdx << ")" << std::endl;
if (attributeIdx != -1)
std::cout << " Attribute: " << attributeLabel(attributeIdx) << " (" << attributeIdx << ")"
<< std::endl;
if (effect.mData.mAttribute != -1)
std::cout << " Attribute: " << attributeLabel(effect.mData.mAttribute) << " ("
<< (int)effect.mData.mAttribute << ")" << std::endl;
std::cout << " Range: " << rangeTypeLabel(effect.mData.mRange) << " (" << effect.mData.mRange << ")"
<< std::endl;
// Area is always zero if range type is "Self"
@ -850,11 +851,11 @@ namespace EsmTool
continue;
int effectIdx = ESM::MagicEffect::refIdToIndex(mData.mData.mEffectID[i]);
int skillIdx = ESM::Skill::refIdToIndex(mData.mData.mSkills[i]);
int attributeIdx = ESM::Attribute::refIdToIndex(mData.mData.mAttributes[i]);
std::cout << " Effect: " << magicEffectLabel(effectIdx) << " (" << effectIdx << ")" << std::endl;
std::cout << " Skill: " << skillLabel(mData.mData.mSkills[i]) << " (" << mData.mData.mSkills[i] << ")"
<< std::endl;
std::cout << " Attribute: " << attributeLabel(mData.mData.mAttributes[i]) << " ("
<< mData.mData.mAttributes[i] << ")" << std::endl;
std::cout << " Skill: " << skillLabel(skillIdx) << " (" << skillIdx << ")" << std::endl;
std::cout << " Attribute: " << attributeLabel(attributeIdx) << " (" << attributeIdx << ")" << std::endl;
}
std::cout << " Deleted: " << mIsDeleted << std::endl;
}

View file

@ -27,11 +27,13 @@ namespace CSMTools
// At the time of writing this effects, attributes and skills are mostly hardcoded
int effectIndex = ESM::MagicEffect::refIdToIndex(effect.mData.mEffectID);
int skillIndex = ESM::Skill::refIdToIndex(effect.mData.mSkill);
int attributeIndex = ESM::Attribute::refIdToIndex(effect.mData.mAttribute);
if (effectIndex < -1 || effectIndex >= ESM::MagicEffect::Length)
messages.add(id, "Effect #" + number + ": invalid effect ID", "", CSMDoc::Message::Severity_Error);
if (effect.mData.mSkill < -1 || effect.mData.mSkill >= ESM::Skill::Length)
if (skillIndex < -1 || skillIndex >= ESM::Skill::Length)
messages.add(id, "Effect #" + number + ": invalid skill", "", CSMDoc::Message::Severity_Error);
if (effect.mData.mAttribute < -1 || effect.mData.mAttribute >= ESM::Attribute::Length)
if (attributeIndex < -1 || attributeIndex >= ESM::Attribute::Length)
messages.add(id, "Effect #" + number + ": invalid attribute", "", CSMDoc::Message::Severity_Error);
if (effect.mData.mRange < ESM::RT_Self || effect.mData.mRange > ESM::RT_Target)
@ -74,13 +76,15 @@ namespace CSMTools
hasEffects = true;
int effectIndex = ESM::MagicEffect::refIdToIndex(ingredient.mData.mEffectID[i]);
int skillIndex = ESM::Skill::refIdToIndex(ingredient.mData.mSkills[i]);
int attributeIndex = ESM::Attribute::refIdToIndex(ingredient.mData.mAttributes[i]);
const std::string number = std::to_string(i + 1);
if (effectIndex < -1 || effectIndex >= ESM::MagicEffect::Length)
messages.add(id, "Effect #" + number + ": invalid effect ID", "", CSMDoc::Message::Severity_Error);
if (ingredient.mData.mSkills[i] < -1 || ingredient.mData.mSkills[i] >= ESM::Skill::Length)
if (skillIndex < -1 || skillIndex >= ESM::Skill::Length)
messages.add(id, "Effect #" + number + ": invalid skill", "", CSMDoc::Message::Severity_Error);
if (ingredient.mData.mAttributes[i] < -1 || ingredient.mData.mAttributes[i] >= ESM::Attribute::Length)
if (attributeIndex < -1 || attributeIndex >= ESM::Attribute::Length)
messages.add(id, "Effect #" + number + ": invalid attribute", "", CSMDoc::Message::Severity_Error);
}

View file

@ -9,8 +9,10 @@
#include <string>
#include <vector>
#include <components/esm/attr.hpp>
#include <components/esm3/effectlist.hpp>
#include <components/esm3/loadmgef.hpp> // for converting magic effect id to string & back
#include <components/esm3/loadskil.hpp>
#include "idcollection.hpp"
#include "nestedcolumnadapter.hpp"
@ -267,8 +269,6 @@ namespace CSMWorld
ESM::IndexedENAMstruct effect;
effect.mIndex = position;
effect.mData.mEffectID = ESM::MagicEffect::WaterBreathing;
effect.mData.mSkill = -1;
effect.mData.mAttribute = -1;
effect.mData.mRange = 0;
effect.mData.mArea = 0;
effect.mData.mDuration = 0;
@ -339,14 +339,14 @@ namespace CSMWorld
case 1:
{
if (targetSkill)
return effect.mSkill;
return ESM::Skill::refIdToIndex(effect.mSkill);
else
return QVariant();
}
case 2:
{
if (targetAttribute)
return effect.mAttribute;
return ESM::Attribute::refIdToIndex(effect.mAttribute);
else
return QVariant();
}
@ -389,19 +389,19 @@ namespace CSMWorld
targetAttribute = mgef.mData.mFlags & ESM::MagicEffect::TargetAttribute;
}
if (!targetSkill)
effect.mSkill = -1;
effect.mSkill = ESM::RefId();
if (!targetAttribute)
effect.mAttribute = -1;
effect.mAttribute = ESM::RefId();
break;
}
case 1:
{
effect.mSkill = static_cast<signed char>(value.toInt());
effect.mSkill = ESM::Skill::indexToRefId(value.toInt());
break;
}
case 2:
{
effect.mAttribute = static_cast<signed char>(value.toInt());
effect.mAttribute = ESM::Attribute::indexToRefId(value.toInt());
break;
}
case 3:

View file

@ -160,14 +160,14 @@ QVariant CSMWorld::IngredEffectRefIdAdapter::getNestedData(
case 1:
{
if (targetSkill)
return record.get().mData.mSkills[subRowIndex];
return ESM::Skill::refIdToIndex(record.get().mData.mSkills[subRowIndex]);
else
return QVariant();
}
case 2:
{
if (targetAttribute)
return record.get().mData.mAttributes[subRowIndex];
return ESM::Attribute::refIdToIndex(record.get().mData.mAttributes[subRowIndex]);
else
return QVariant();
}
@ -205,15 +205,15 @@ void CSMWorld::IngredEffectRefIdAdapter::setNestedData(
}
if (!targetSkill)
ingredient.mData.mSkills[subRowIndex] = -1;
ingredient.mData.mSkills[subRowIndex] = ESM::RefId();
if (!targetAttribute)
ingredient.mData.mAttributes[subRowIndex] = -1;
ingredient.mData.mAttributes[subRowIndex] = ESM::RefId();
break;
case 1:
ingredient.mData.mSkills[subRowIndex] = value.toInt();
ingredient.mData.mSkills[subRowIndex] = ESM::Skill::indexToRefId(value.toInt());
break;
case 2:
ingredient.mData.mAttributes[subRowIndex] = value.toInt();
ingredient.mData.mAttributes[subRowIndex] = ESM::Attribute::indexToRefId(value.toInt());
break;
default:
throw std::runtime_error("Trying to access non-existing column in the nested table!");

View file

@ -135,8 +135,8 @@ namespace MWClass
continue;
MWGui::Widgets::SpellEffectParams params;
params.mEffectID = ref->mBase->mData.mEffectID[i];
params.mAttribute = ESM::Attribute::indexToRefId(ref->mBase->mData.mAttributes[i]);
params.mSkill = ESM::Skill::indexToRefId(ref->mBase->mData.mSkills[i]);
params.mAttribute = ref->mBase->mData.mAttributes[i];
params.mSkill = ref->mBase->mData.mSkills[i];
params.mKnown = alchemySkill >= fWortChanceValue * (i + 1);
list.push_back(params);

View file

@ -48,8 +48,6 @@ namespace
effect.mMagnMax = 0;
effect.mMagnMin = 0;
effect.mRange = 0;
effect.mSkill = -1;
effect.mAttribute = -1;
}
}
@ -143,8 +141,8 @@ namespace MWGui
mEffect.mMagnMax = 1;
mEffect.mDuration = 1;
mEffect.mArea = 0;
mEffect.mSkill = -1;
mEffect.mAttribute = -1;
mEffect.mSkill = ESM::RefId();
mEffect.mAttribute = ESM::RefId();
eventEffectAdded(mEffect);
onRangeButtonClicked(mRangeButton);
@ -331,13 +329,13 @@ namespace MWGui
void EditEffectDialog::setSkill(ESM::RefId skill)
{
mEffect.mSkill = static_cast<signed char>(ESM::Skill::refIdToIndex(skill));
mEffect.mSkill = skill;
eventEffectModified(mEffect);
}
void EditEffectDialog::setAttribute(ESM::RefId attribute)
{
mEffect.mAttribute = static_cast<signed char>(ESM::Attribute::refIdToIndex(attribute));
mEffect.mAttribute = attribute;
eventEffectModified(mEffect);
}
@ -961,8 +959,8 @@ namespace MWGui
{
Widgets::SpellEffectParams params;
params.mEffectID = effectInfo.mEffectID;
params.mSkill = ESM::Skill::indexToRefId(effectInfo.mSkill);
params.mAttribute = ESM::Attribute::indexToRefId(effectInfo.mAttribute);
params.mSkill = effectInfo.mSkill;
params.mAttribute = effectInfo.mAttribute;
params.mDuration = effectInfo.mDuration;
params.mMagnMin = effectInfo.mMagnMin;
params.mMagnMax = effectInfo.mMagnMax;

View file

@ -53,9 +53,8 @@ namespace MWGui
if (!effectId.empty())
{
const ESM::MagicEffect* magicEffect = store.get<ESM::MagicEffect>().find(effectId);
const ESM::Attribute* attribute
= store.get<ESM::Attribute>().search(ESM::Attribute::indexToRefId(effect.mData.mAttribute));
const ESM::Skill* skill = store.get<ESM::Skill>().search(ESM::Skill::indexToRefId(effect.mData.mSkill));
const ESM::Attribute* attribute = store.get<ESM::Attribute>().search(effect.mData.mAttribute);
const ESM::Skill* skill = store.get<ESM::Skill>().search(effect.mData.mSkill);
std::string fullEffectName = MWMechanics::getMagicEffectString(*magicEffect, attribute, skill);
std::string convert = Utf8Stream::lowerCaseUtf8(fullEffectName);

View file

@ -228,8 +228,8 @@ namespace MWGui
{
Widgets::SpellEffectParams params;
params.mEffectID = spellEffect.mData.mEffectID;
params.mSkill = ESM::Skill::indexToRefId(spellEffect.mData.mSkill);
params.mAttribute = ESM::Attribute::indexToRefId(spellEffect.mData.mAttribute);
params.mSkill = spellEffect.mData.mSkill;
params.mAttribute = spellEffect.mData.mAttribute;
params.mDuration = spellEffect.mData.mDuration;
params.mMagnMin = spellEffect.mData.mMagnMin;
params.mMagnMax = spellEffect.mData.mMagnMax;

View file

@ -216,8 +216,8 @@ namespace MWGui::Widgets
= creator->createWidget<MWSpellEffect>("MW_EffectImage", coord, MyGUI::Align::Default);
SpellEffectParams params;
params.mEffectID = effectInfo.mData.mEffectID;
params.mSkill = ESM::Skill::indexToRefId(effectInfo.mData.mSkill);
params.mAttribute = ESM::Attribute::indexToRefId(effectInfo.mData.mAttribute);
params.mSkill = effectInfo.mData.mSkill;
params.mAttribute = effectInfo.mData.mAttribute;
params.mDuration = effectInfo.mData.mDuration;
params.mMagnMin = effectInfo.mData.mMagnMin;
params.mMagnMax = effectInfo.mData.mMagnMax;
@ -333,8 +333,8 @@ namespace MWGui::Widgets
{
SpellEffectParams params;
params.mEffectID = effectInfo.mData.mEffectID;
params.mSkill = ESM::Skill::indexToRefId(effectInfo.mData.mSkill);
params.mAttribute = ESM::Attribute::indexToRefId(effectInfo.mData.mAttribute);
params.mSkill = effectInfo.mData.mSkill;
params.mAttribute = effectInfo.mData.mAttribute;
params.mDuration = effectInfo.mData.mDuration;
params.mMagnMin = effectInfo.mData.mMagnMin;
params.mMagnMax = effectInfo.mData.mMagnMax;

View file

@ -323,16 +323,14 @@ namespace MWLua
[](const ESM::IndexedENAMstruct& params) -> ESM::RefId { return params.mData.mEffectID; });
effectParamsT["affectedSkill"]
= sol::readonly_property([](const ESM::IndexedENAMstruct& params) -> sol::optional<std::string> {
ESM::RefId id = ESM::Skill::indexToRefId(params.mData.mSkill);
if (!id.empty())
return id.serializeText();
if (!params.mData.mSkill.empty())
return params.mData.mSkill.serializeText();
return sol::nullopt;
});
effectParamsT["affectedAttribute"]
= sol::readonly_property([](const ESM::IndexedENAMstruct& params) -> sol::optional<std::string> {
ESM::RefId id = ESM::Attribute::indexToRefId(params.mData.mAttribute);
if (!id.empty())
return id.serializeText();
if (!params.mData.mAttribute.empty())
return params.mData.mAttribute.serializeText();
return sol::nullopt;
});
effectParamsT["range"]

View file

@ -50,8 +50,8 @@ namespace MWLua
continue;
ESM::IndexedENAMstruct effect;
effect.mData.mEffectID = rec.mData.mEffectID[i];
effect.mData.mSkill = static_cast<signed char>(rec.mData.mSkills[i]);
effect.mData.mAttribute = static_cast<signed char>(rec.mData.mAttributes[i]);
effect.mData.mSkill = rec.mData.mSkills[i];
effect.mData.mAttribute = rec.mData.mAttributes[i];
effect.mData.mRange = ESM::RT_Self;
effect.mData.mArea = 0;
effect.mData.mDuration = 0;

View file

@ -33,9 +33,9 @@ namespace
{
if (ingredient.mData.mEffectID[i].empty())
return {};
ESM::RefId arg = ESM::Skill::indexToRefId(ingredient.mData.mSkills[i]);
ESM::RefId arg = ingredient.mData.mSkills[i];
if (arg.empty())
arg = ESM::Attribute::indexToRefId(ingredient.mData.mAttributes[i]);
arg = ingredient.mData.mAttributes[i];
return MWMechanics::EffectKey(ingredient.mData.mEffectID[i], arg);
}
@ -220,13 +220,10 @@ void MWMechanics::Alchemy::updateEffects()
ESM::ENAMstruct effect;
effect.mEffectID = effectKey.mId;
effect.mAttribute = -1;
effect.mSkill = -1;
if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill)
effect.mSkill = static_cast<signed char>(ESM::Skill::refIdToIndex(effectKey.mArg));
effect.mSkill = effectKey.mArg;
else if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute)
effect.mAttribute = static_cast<signed char>(ESM::Attribute::refIdToIndex(effectKey.mArg));
effect.mAttribute = effectKey.mArg;
effect.mRange = 0;
effect.mArea = 0;
@ -624,9 +621,8 @@ std::vector<std::string> MWMechanics::Alchemy::effectsDescription(
if (!effectID.empty())
{
const ESM::Attribute* attribute
= store->get<ESM::Attribute>().search(ESM::Attribute::indexToRefId(data.mAttributes[i]));
const ESM::Skill* skill = store->get<ESM::Skill>().search(ESM::Skill::indexToRefId(data.mSkills[i]));
const ESM::Attribute* attribute = store->get<ESM::Attribute>().search(data.mAttributes[i]);
const ESM::Skill* skill = store->get<ESM::Skill>().search(data.mSkills[i]);
std::string effect = getMagicEffectString(*mgef.find(effectID), attribute, skill);
effects.push_back(std::move(effect));

View file

@ -230,16 +230,14 @@ namespace MWMechanics
if ((magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill))
{
ESM::RefId skill = ESM::Skill::indexToRefId(spellEffect.mData.mSkill);
auto found = actorSkills.find(skill);
auto found = actorSkills.find(spellEffect.mData.mSkill);
if (found == actorSkills.end() || found->second.getBase() < iAutoSpellAttSkillMin)
return false;
}
if ((magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute))
{
ESM::RefId attribute = ESM::Attribute::indexToRefId(spellEffect.mData.mAttribute);
auto found = actorAttributes.find(attribute);
auto found = actorAttributes.find(spellEffect.mData.mAttribute);
if (found == actorAttributes.end() || found->second.getBase() < iAutoSpellAttSkillMin)
return false;
}

View file

@ -33,15 +33,14 @@ namespace MWMechanics
EffectKey::EffectKey(const ESM::ENAMstruct& effect)
{
mId = effect.mEffectID;
mArg = ESM::Skill::indexToRefId(effect.mSkill);
mArg = effect.mSkill;
ESM::RefId attribute = ESM::Attribute::indexToRefId(effect.mAttribute);
if (!attribute.empty())
if (!effect.mAttribute.empty())
{
if (!mArg.empty())
throw std::runtime_error("magic effect can't have both a skill and an attribute argument");
mArg = attribute;
mArg = effect.mAttribute;
}
}

View file

@ -541,14 +541,11 @@ namespace MWMechanics
|| effect.mEffectID == ESM::MagicEffect::DrainAttribute)
{
if (!enemy.isEmpty()
&& enemy.getClass()
.getCreatureStats(enemy)
.getAttribute(ESM::Attribute::indexToRefId(effect.mAttribute))
.getModified()
<= 0)
&& enemy.getClass().getCreatureStats(enemy).getAttribute(effect.mAttribute).getModified() <= 0)
return 0.f;
{
if (effect.mAttribute >= 0 && effect.mAttribute < ESM::Attribute::Length)
int attributeIdx = ESM::Attribute::refIdToIndex(effect.mAttribute);
if (attributeIdx >= 0 && attributeIdx < ESM::Attribute::Length)
{
const float attributePriorities[ESM::Attribute::Length] = {
1.0f, // Strength
@ -560,7 +557,7 @@ namespace MWMechanics
0.7f, // Personality
0.3f // Luck
};
rating *= attributePriorities[effect.mAttribute];
rating *= attributePriorities[attributeIdx];
}
}
}
@ -569,7 +566,7 @@ namespace MWMechanics
{
if (enemy.isEmpty() || !enemy.getClass().isNpc())
return 0.f;
if (enemy.getClass().getSkill(enemy, ESM::Skill::indexToRefId(effect.mSkill)) <= 0)
if (enemy.getClass().getSkill(enemy, effect.mSkill) <= 0)
return 0.f;
}

View file

@ -167,8 +167,8 @@ namespace MWMechanics
ESM::ENAMstruct effect;
effect.mEffectID = ingredient->mData.mEffectID[index];
effect.mSkill = static_cast<signed char>(ingredient->mData.mSkills[index]);
effect.mAttribute = static_cast<signed char>(ingredient->mData.mAttributes[index]);
effect.mSkill = ingredient->mData.mSkills[index];
effect.mAttribute = ingredient->mData.mAttributes[index];
effect.mRange = ESM::RT_Self;
effect.mArea = 0;

View file

@ -181,18 +181,18 @@ namespace
continue;
}
if (!(mgef->mData.mFlags & ESM::MagicEffect::TargetAttribute) && iter->mData.mAttribute != -1)
if (!(mgef->mData.mFlags & ESM::MagicEffect::TargetAttribute) && !iter->mData.mAttribute.empty())
{
iter->mData.mAttribute = -1;
iter->mData.mAttribute = ESM::RefId();
Log(Debug::Verbose) << RecordType::getRecordType() << " " << spell.mId
<< ": dropping unexpected attribute argument of " << iter->mData.mEffectID
<< " effect";
changed = true;
}
if (!(mgef->mData.mFlags & ESM::MagicEffect::TargetSkill) && iter->mData.mSkill != -1)
if (!(mgef->mData.mFlags & ESM::MagicEffect::TargetSkill) && !iter->mData.mSkill.empty())
{
iter->mData.mSkill = -1;
iter->mData.mSkill = ESM::RefId();
Log(Debug::Verbose) << RecordType::getRecordType() << " " << spell.mId
<< ": dropping unexpected skill argument of " << iter->mData.mEffectID
<< " effect";

View file

@ -48,7 +48,7 @@ namespace MWWorld
for (auto& effect : spell->mEffects.mList)
{
if (effect.mData.mEffectID == ESM::MagicEffect::DrainAttribute)
stats.mWorsenings[effect.mData.mAttribute] = oldStats.mWorsenings;
stats.mWorsenings[ESM::Attribute::refIdToIndex(effect.mData.mAttribute)] = oldStats.mWorsenings;
}
creatureStats.mCorprusSpells[id] = stats;
}

View file

@ -34,8 +34,8 @@ namespace ESM
if (index < 0 || index >= ESM::MagicEffect::Length)
throw std::runtime_error(std::format("Cannot serialize effect {}", src.mEffectID.toDebugString()));
dst.mEffectID = index;
dst.mSkill = src.mSkill;
dst.mAttribute = src.mAttribute;
dst.mSkill = static_cast<signed char>(ESM::Skill::refIdToIndex(src.mSkill));
dst.mAttribute = static_cast<signed char>(ESM::Attribute::refIdToIndex(src.mAttribute));
dst.mRange = src.mRange;
dst.mArea = src.mArea;
dst.mDuration = src.mDuration;
@ -49,8 +49,8 @@ namespace ESM
if (index < 0 || index >= ESM::MagicEffect::Length)
throw std::runtime_error(std::format("Cannot deserialize effect into ENAM with index {}.", index));
dst.mEffectID = ESM::MagicEffect::indexToRefId(index);
dst.mSkill = src.mSkill;
dst.mAttribute = src.mAttribute;
dst.mSkill = ESM::Skill::indexToRefId(src.mSkill);
dst.mAttribute = ESM::Attribute::indexToRefId(src.mAttribute);
dst.mRange = src.mRange;
dst.mArea = src.mArea;
dst.mDuration = src.mDuration;
@ -118,8 +118,8 @@ namespace ESM
esm.getSubComposite(p);
setEffectParams(p, s);
s.mEffectID = esm.getHNRefId("ENID");
s.mSkill = static_cast<signed char>(ESM::Skill::refIdToIndex(esm.getHNORefId("ENSK")));
s.mAttribute = static_cast<signed char>(ESM::Attribute::refIdToIndex(esm.getHNORefId("ENAT")));
s.mSkill = esm.getHNORefId("ENSK");
s.mAttribute = esm.getHNORefId("ENAT");
}
mList.push_back({ s, static_cast<uint32_t>(mList.size()) });
}
@ -142,8 +142,8 @@ namespace ESM
setEffectParams(enam.mData, p);
esm.writeNamedComposite("ENAM", p);
esm.writeHNRefId("ENID", enam.mData.mEffectID);
esm.writeHNORefId("ENSK", ESM::Skill::indexToRefId(enam.mData.mSkill));
esm.writeHNORefId("ENAT", ESM::Attribute::indexToRefId(enam.mData.mAttribute));
esm.writeHNORefId("ENSK", enam.mData.mSkill);
esm.writeHNORefId("ENAT", enam.mData.mAttribute);
}
}
}

View file

@ -21,7 +21,7 @@ namespace ESM
// Which skills/attributes are affected (for restore/drain spells
// etc.)
signed char mSkill, mAttribute; // -1 if N/A
ESM::RefId mSkill, mAttribute; // EmptyRefId if N/A
// Other spell parameters
int32_t mRange; // 0 - self, 1 - touch, 2 - target (RangeType enum)

View file

@ -3,7 +3,9 @@
#include "esmreader.hpp"
#include "esmwriter.hpp"
#include <components/esm/attr.hpp>
#include <components/esm3/loadmgef.hpp>
#include <components/esm3/loadskil.hpp>
#include <components/misc/concepts.hpp>
namespace ESM
@ -24,8 +26,8 @@ namespace ESM
for (int i = 0; i < 4; ++i)
{
dst.mEffectID[i] = ESM::MagicEffect::refIdToIndex(src.mEffectID[i]);
dst.mSkills[i] = src.mSkills[i];
dst.mAttributes[i] = src.mAttributes[i];
dst.mSkills[i] = ESM::Skill::refIdToIndex(src.mSkills[i]);
dst.mAttributes[i] = ESM::Attribute::refIdToIndex(src.mAttributes[i]);
}
}
@ -36,8 +38,8 @@ namespace ESM
for (int i = 0; i < 4; ++i)
{
dst.mEffectID[i] = ESM::MagicEffect::indexToRefId(src.mEffectID[i]);
dst.mSkills[i] = src.mSkills[i];
dst.mAttributes[i] = src.mAttributes[i];
dst.mSkills[i] = ESM::Skill::indexToRefId(src.mSkills[i]);
dst.mAttributes[i] = ESM::Attribute::indexToRefId(src.mAttributes[i]);
}
}
}
@ -106,7 +108,7 @@ namespace ESM
&& mData.mEffectID[i] != ESM::MagicEffect::FortifyAttribute
&& mData.mEffectID[i] != ESM::MagicEffect::RestoreAttribute)
{
mData.mAttributes[i] = -1;
mData.mAttributes[i] = ESM::RefId();
}
// is this relevant in cycle from 0 to 4?
@ -116,7 +118,7 @@ namespace ESM
&& mData.mEffectID[i] != ESM::MagicEffect::FortifySkill
&& mData.mEffectID[i] != ESM::MagicEffect::RestoreSkill)
{
mData.mSkills[i] = -1;
mData.mSkills[i] = ESM::RefId();
}
}
}
@ -148,8 +150,8 @@ namespace ESM
for (int i = 0; i < 4; ++i)
{
mData.mEffectID[i] = ESM::MagicEffect::WaterBreathing;
mData.mSkills[i] = 0;
mData.mAttributes[i] = 0;
mData.mSkills[i] = ESM::RefId();
mData.mAttributes[i] = ESM::RefId();
}
mName.clear();

View file

@ -28,8 +28,8 @@ namespace ESM
float mWeight;
int32_t mValue;
RefId mEffectID[4]; // Effect, EmptyRefId means none
int32_t mSkills[4]; // SkillEnum related to effect
int32_t mAttributes[4]; // Attribute related to effect
RefId mSkills[4]; // SkillEnum related to effect
RefId mAttributes[4]; // Attribute related to effect
};
IRDTstruct mData;