diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 0ab33065b..210d63803 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -2286,13 +2286,16 @@ namespace CSMWorld struct NestedStringColumn : public NestableColumn { - NestedStringColumn (Columns::ColumnId id) + bool mIsEditable; + + NestedStringColumn (Columns::ColumnId id, bool isEditable = true) : NestableColumn (id, ColumnBase::Display_String, ColumnBase::Flag_Dialogue) + , mIsEditable(isEditable) {} virtual bool isEditable() const { - return true; + return mIsEditable; } }; diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index efe9a5116..fca16ec0b 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -242,8 +242,8 @@ namespace CSMWorld { ColumnId_FactionReaction, "Reaction"}, { ColumnId_EffectList, "Effects"}, - { ColumnId_EffectId, "ID"}, - { ColumnId_EffectAttribute, "Attrib"}, + { ColumnId_EffectId, "Effect"}, + //{ ColumnId_EffectAttribute, "Attrib"}, { ColumnId_EffectRange, "Range"}, { ColumnId_EffectArea, "Area"}, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 6b3791042..4f77ee23a 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -232,7 +232,7 @@ namespace CSMWorld ColumnId_EffectList = 214, ColumnId_EffectId = 215, - ColumnId_EffectAttribute = 216, + //ColumnId_EffectAttribute = 216, ColumnId_EffectRange = 217, ColumnId_EffectArea = 218, diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 86cf3bb44..538b240dc 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -195,15 +195,15 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mSpells.addColumn (spellEffect); mSpells.addAdapter (std::make_pair(spellEffect, new EffectsListAdapter ())); mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_EffectId)); + new NestedStringColumn (Columns::ColumnId_EffectId/*, false*/)); // false means no edit mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_Skill)); + new NestedStringColumn (Columns::ColumnId_Skill)); mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_EffectAttribute)); + new NestedStringColumn (Columns::ColumnId_Attribute)); // reuse attribute mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( new NestedIntegerColumn (Columns::ColumnId_EffectRange)); mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_EffectArea)); + new NestedStringColumn (Columns::ColumnId_EffectArea)); mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( new NestedIntegerColumn (Columns::ColumnId_Duration)); // reuse from light mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( @@ -269,15 +269,15 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mEnchantments.addColumn (enchantmentEffect); mEnchantments.addAdapter (std::make_pair(enchantmentEffect, new EffectsListAdapter ())); mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_EffectId)); + new NestedStringColumn (Columns::ColumnId_EffectId/*, false*/)); mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_Skill)); + new NestedStringColumn (Columns::ColumnId_Skill)); mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_EffectAttribute)); + new NestedStringColumn (Columns::ColumnId_Attribute)); // reuse attribute mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( new NestedIntegerColumn (Columns::ColumnId_EffectRange)); mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_EffectArea)); + new NestedStringColumn (Columns::ColumnId_EffectArea)); mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( new NestedIntegerColumn (Columns::ColumnId_Duration)); // reuse from light mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp index 219032dd3..d5bf83a2d 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -7,6 +7,9 @@ #include #include #include +#include // for converting magic effect id to string & back +#include // for converting skill names +#include // for converting attributes #include "idadapter.hpp" #include "nestedtablewrapper.hpp" @@ -651,10 +654,82 @@ namespace CSMWorld ESM::ENAMstruct effect = effectsList[subRowIndex]; switch (subColIndex) { - case 0: return effect.mEffectID; - case 1: return effect.mSkill; - case 2: return effect.mAttribute; - case 3: return effect.mRange; + case 0: + { + // indexToId() prepends "#d+" hence not so user friendly + QString effectId(ESM::MagicEffect::effectIdToString(effect.mEffectID).c_str()); + return effectId.remove(0, 7); // 7 == sizeof("sEffect") - 1 + } + case 1: + { + switch (effect.mSkill) + { + // see ESM::Skill::SkillEnum in + case ESM::Skill::Block: + case ESM::Skill::Armorer: + case ESM::Skill::MediumArmor: + case ESM::Skill::HeavyArmor: + case ESM::Skill::BluntWeapon: + case ESM::Skill::LongBlade: + case ESM::Skill::Axe: + case ESM::Skill::Spear: + case ESM::Skill::Athletics: + case ESM::Skill::Enchant: + case ESM::Skill::Destruction: + case ESM::Skill::Alteration: + case ESM::Skill::Illusion: + case ESM::Skill::Conjuration: + case ESM::Skill::Mysticism: + case ESM::Skill::Restoration: + case ESM::Skill::Alchemy: + case ESM::Skill::Unarmored: + case ESM::Skill::Security: + case ESM::Skill::Sneak: + case ESM::Skill::Acrobatics: + case ESM::Skill::LightArmor: + case ESM::Skill::ShortBlade: + case ESM::Skill::Marksman: + case ESM::Skill::Mercantile: + case ESM::Skill::Speechcraft: + case ESM::Skill::HandToHand: + { + return QString(ESM::Skill::sSkillNames[effect.mSkill].c_str()); + } + case -1: return QString("N/A"); + default: return QVariant(); + } + } + case 2: + { + switch (effect.mAttribute) + { + // see ESM::Attribute::AttributeID in + case ESM::Attribute::Strength: + case ESM::Attribute::Intelligence: + case ESM::Attribute::Willpower: + case ESM::Attribute::Agility: + case ESM::Attribute::Speed: + case ESM::Attribute::Endurance: + case ESM::Attribute::Personality: + case ESM::Attribute::Luck: + { + return QString(ESM::Attribute::sAttributeNames[effect.mAttribute].c_str()); + } + case -1: return QString("N/A"); + default: return QVariant(); + } + } + case 3: + { + switch (effect.mRange) + { + // see ESM::RangeType in + case ESM::RT_Self: return QString("Self"); + case ESM::RT_Touch: return QString("Touch"); + case ESM::RT_Target: return QString("Target"); + default: return QVariant(); + } + } case 4: return effect.mArea; case 5: return effect.mDuration; case 6: return effect.mMagnMin; @@ -676,10 +751,62 @@ namespace CSMWorld ESM::ENAMstruct effect = effectsList[subRowIndex]; switch (subColIndex) { - case 0: effect.mEffectID = static_cast(value.toInt()); break; - case 1: effect.mSkill = static_cast(value.toInt()); break; - case 2: effect.mAttribute = static_cast(value.toInt()); break; - case 3: effect.mRange = value.toInt(); break; + case 0: + { + effect.mEffectID = + ESM::MagicEffect::effectStringToId("sEffect"+value.toString().toStdString()); + break; + } + case 1: + { + std::string skillName = value.toString().toStdString(); + if ("N/A" == skillName) + { + effect.mSkill = -1; + break; + } + + for (unsigned int i = 0; i < ESM::Skill::Length; ++i) + { + if (ESM::Skill::sSkillNames[i] == skillName) + { + effect.mSkill = static_cast(i); + break; + } + } + break; + } + case 2: + { + std::string attr = value.toString().toStdString(); + if ("N/A" == attr) + { + effect.mAttribute = -1; + break; + } + + for (unsigned int i = 0; i < ESM::Attribute::Length; ++i) + { + if (ESM::Attribute::sAttributeNames[i] == attr) + { + effect.mAttribute = static_cast(i); + break; + } + } + break; + } + case 3: + { + std::string effectId = value.toString().toStdString(); + if (effectId == "Self") + effect.mRange = ESM::RT_Self; + else if (effectId == "Touch") + effect.mRange = ESM::RT_Touch; + else if (effectId == "Target") + effect.mRange = ESM::RT_Target; + // else leave unchanged + break; + } case 4: effect.mArea = value.toInt(); break; case 5: effect.mDuration = value.toInt(); break; case 6: effect.mMagnMin = value.toInt(); break;