From 967b5d205bce782df43e526aba1d338dc1d78c9f Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Thu, 15 Jun 2023 21:38:46 +0200 Subject: [PATCH] Use StringRefId for skills --- apps/opencs/model/world/columnimp.cpp | 8 +- apps/opencs/model/world/columnimp.hpp | 3 +- apps/openmw/mwlua/luabindings.cpp | 11 +- apps/openmw/mwlua/magicbindings.cpp | 24 +- apps/openmw/mwlua/stats.cpp | 3 +- apps/openmw/mwlua/types/book.cpp | 22 +- apps/openmw/mwmechanics/weapontype.cpp | 434 ++++++++++++++----------- components/esm3/loadskil.cpp | 103 +++--- components/esm3/loadskil.hpp | 57 ++-- 9 files changed, 379 insertions(+), 286 deletions(-) diff --git a/apps/opencs/model/world/columnimp.cpp b/apps/opencs/model/world/columnimp.cpp index 7d43d1e4f3..b514550479 100644 --- a/apps/opencs/model/world/columnimp.cpp +++ b/apps/opencs/model/world/columnimp.cpp @@ -26,8 +26,6 @@ namespace CSMWorld { switch (value.getRecordType()) { - case ESM::REC_SKIL: - return ESM::Skill::sSkillNames[value.getValue()]; case ESM::REC_MGEF: return std::string(ESM::MagicEffect::sIndexNames[value.getValue()]); default: @@ -335,10 +333,10 @@ namespace CSMWorld std::optional getSkillIndex(std::string_view value) { - const auto it = std::find(std::begin(ESM::Skill::sSkillNames), std::end(ESM::Skill::sSkillNames), value); - if (it == std::end(ESM::Skill::sSkillNames)) + int index = ESM::Skill::refIdToIndex(ESM::RefId::stringRefId(value)); + if (index < 0) return std::nullopt; - return static_cast(it - std::begin(ESM::Skill::sSkillNames)); + return static_cast(index); } std::string getStringId(ESM::RefId value) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 3f137fadb7..5e5ff83fcf 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -409,7 +409,8 @@ namespace CSMWorld QVariant get(const Record& record) const override { - return QString::fromStdString(ESM::Skill::sSkillNames[record.get().mData.getSkill(mIndex, mMajor)]); + return QString::fromStdString( + ESM::Skill::indexToRefId(record.get().mData.getSkill(mIndex, mMajor)).getRefIdString()); } void set(Record& record, const QVariant& data) override diff --git a/apps/openmw/mwlua/luabindings.cpp b/apps/openmw/mwlua/luabindings.cpp index 1804ea4004..a204287b88 100644 --- a/apps/openmw/mwlua/luabindings.cpp +++ b/apps/openmw/mwlua/luabindings.cpp @@ -156,10 +156,17 @@ namespace MWLua return sol::nil; }; + // TODO: deprecate this and provide access to the store instead sol::table skill(context.mLua->sol(), sol::create); api["SKILL"] = LuaUtil::makeStrictReadOnly(skill); - for (int id = 0; id < ESM::Skill::Length; ++id) - skill[ESM::Skill::sSkillNames[id]] = Misc::StringUtils::lowerCase(ESM::Skill::sSkillNames[id]); + for (int i = 0; i < ESM::Skill::Length; ++i) + { + std::string id = ESM::Skill::indexToRefId(i).serializeText(); + std::string key = id; + // force first character to uppercase for backwards compatability + key[0] += 'A' - 'a'; + skill[key] = id; + } sol::table attribute(context.mLua->sol(), sol::create); api["ATTRIBUTE"] = LuaUtil::makeStrictReadOnly(attribute); diff --git a/apps/openmw/mwlua/magicbindings.cpp b/apps/openmw/mwlua/magicbindings.cpp index 51d43b8523..6247fc6216 100644 --- a/apps/openmw/mwlua/magicbindings.cpp +++ b/apps/openmw/mwlua/magicbindings.cpp @@ -309,10 +309,10 @@ namespace MWLua }); effectParamsT["affectedSkill"] = sol::readonly_property([](const ESM::ENAMstruct& params) -> sol::optional { - if (params.mSkill >= 0 && params.mSkill < ESM::Skill::Length) - return Misc::StringUtils::lowerCase(ESM::Skill::sSkillNames[params.mSkill]); - else - return sol::nullopt; + ESM::RefId id = ESM::Skill::indexToRefId(params.mSkill); + if (!id.empty()) + return id.serializeText(); + return sol::nullopt; }); effectParamsT["affectedAttribute"] = sol::readonly_property([](const ESM::ENAMstruct& params) -> sol::optional { @@ -383,11 +383,12 @@ namespace MWLua activeEffectT["affectedSkill"] = sol::readonly_property([magicEffectStore](const ActiveEffect& effect) -> sol::optional { auto* rec = magicEffectStore->find(effect.key.mId); - if ((rec->mData.mFlags & ESM::MagicEffect::TargetSkill) && effect.key.mArg >= 0 - && effect.key.mArg < ESM::Skill::Length) - return Misc::StringUtils::lowerCase(ESM::Skill::sSkillNames[effect.key.mArg]); - else - return sol::nullopt; + if (rec->mData.mFlags & ESM::MagicEffect::TargetSkill) + { + ESM::RefId id = ESM::Skill::indexToRefId(effect.key.mArg); + return id.serializeText(); + } + return sol::nullopt; }); activeEffectT["affectedAttribute"] = sol::readonly_property([magicEffectStore](const ActiveEffect& effect) -> sol::optional { @@ -620,7 +621,10 @@ namespace MWLua key = MWMechanics::EffectKey(id, ESM::Attribute::stringToAttributeId(argStr.value())); if (rec->mData.mFlags & ESM::MagicEffect::TargetSkill) - key = MWMechanics::EffectKey(id, ESM::Skill::stringToSkillId(argStr.value())); + { + ESM::RefId skill = ESM::RefId::stringRefId(argStr.value()); + key = MWMechanics::EffectKey(id, ESM::Skill::refIdToIndex(skill)); + } } return key; diff --git a/apps/openmw/mwlua/stats.cpp b/apps/openmw/mwlua/stats.cpp index 552129c3fd..f8dde1e68d 100644 --- a/apps/openmw/mwlua/stats.cpp +++ b/apps/openmw/mwlua/stats.cpp @@ -392,7 +392,6 @@ namespace MWLua sol::table skills(context.mLua->sol(), sol::create); npcStats["skills"] = LuaUtil::makeReadOnly(skills); for (const ESM::Skill& skill : MWBase::Environment::get().getESMStore()->get()) - skills[Misc::StringUtils::lowerCase(ESM::Skill::sSkillNames[ESM::Skill::refIdToIndex(skill.mId)])] - = addIndexedAccessor(skill.mId); + skills[skill.mId.serializeText()] = addIndexedAccessor(skill.mId); } } diff --git a/apps/openmw/mwlua/types/book.cpp b/apps/openmw/mwlua/types/book.cpp index f7120e529a..97e51059d0 100644 --- a/apps/openmw/mwlua/types/book.cpp +++ b/apps/openmw/mwlua/types/book.cpp @@ -41,18 +41,14 @@ namespace book.mData.mValue = rec["value"]; book.mData.mIsScroll = rec["isScroll"]; - std::string_view skill = rec["skill"].get(); + ESM::RefId skill = ESM::RefId::stringRefId(rec["skill"].get()); book.mData.mSkillId = -1; - if (skill.length() > 0) + if (!skill.empty()) { - for (std::size_t i = 0; i < std::size(ESM::Skill::sSkillNames); ++i) - { - if (Misc::StringUtils::ciEqual(ESM::Skill::sSkillNames[i], skill)) - book.mData.mSkillId = i; - } + book.mData.mSkillId = ESM::Skill::refIdToIndex(skill); if (book.mData.mSkillId == -1) - throw std::runtime_error("Incorrect skill: " + std::string(skill)); + throw std::runtime_error("Incorrect skill: " + skill.toDebugString()); } return book; } @@ -69,7 +65,7 @@ namespace MWLua book["createRecordDraft"] = tableToBook; for (int id = 0; id < ESM::Skill::Length; ++id) { - std::string skillName = Misc::StringUtils::lowerCase(ESM::Skill::sSkillNames[id]); + std::string skillName = ESM::Skill::indexToRefId(id).serializeText(); skill[skillName] = skillName; } @@ -100,10 +96,10 @@ namespace MWLua record["enchantCapacity"] = sol::readonly_property([](const ESM::Book& rec) -> float { return rec.mData.mEnchant * 0.1f; }); record["skill"] = sol::readonly_property([](const ESM::Book& rec) -> sol::optional { - if (rec.mData.mSkillId >= 0) - return Misc::StringUtils::lowerCase(ESM::Skill::sSkillNames[rec.mData.mSkillId]); - else - return sol::nullopt; + ESM::RefId skill = ESM::Skill::indexToRefId(rec.mData.mSkillId); + if (!skill.empty()) + return skill.serializeText(); + return sol::nullopt; }); } } diff --git a/apps/openmw/mwmechanics/weapontype.cpp b/apps/openmw/mwmechanics/weapontype.cpp index 0612ca1a2e..9dd5842f58 100644 --- a/apps/openmw/mwmechanics/weapontype.cpp +++ b/apps/openmw/mwmechanics/weapontype.cpp @@ -18,253 +18,325 @@ namespace MWMechanics template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "", - /* long group */ "", - /* sound ID */ "", - /* attach bone */ "", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::HandToHand, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ 0 }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "", + /* long group */ "", + /* sound ID */ "", + /* attach bone */ "", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::HandToHand, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ 0 }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "1h", - /* long group */ "pickprobe", - /* sound ID */ "", - /* attach bone */ "", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::Security, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ 0 }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "1h", + /* long group */ "pickprobe", + /* sound ID */ "", + /* attach bone */ "", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::Security, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ 0 }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "spell", - /* long group */ "spellcast", - /* sound ID */ "", - /* attach bone */ "", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::HandToHand, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "spell", + /* long group */ "spellcast", + /* sound ID */ "", + /* attach bone */ "", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::HandToHand, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "hh", - /* long group */ "handtohand", - /* sound ID */ "", - /* attach bone */ "", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::HandToHand, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "hh", + /* long group */ "handtohand", + /* sound ID */ "", + /* attach bone */ "", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::HandToHand, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "1s", - /* long group */ "shortbladeonehand", - /* sound ID */ "Item Weapon Shortblade", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 ShortBladeOneHand", - /* usage skill */ ESM::Skill::ShortBlade, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "1s", + /* long group */ "shortbladeonehand", + /* sound ID */ "Item Weapon Shortblade", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 ShortBladeOneHand", + /* usage skill */ ESM::Skill::ShortBlade, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "1h", - /* long group */ "weapononehand", - /* sound ID */ "Item Weapon Longblade", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 LongBladeOneHand", - /* usage skill */ ESM::Skill::LongBlade, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "1h", + /* long group */ "weapononehand", + /* sound ID */ "Item Weapon Longblade", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 LongBladeOneHand", + /* usage skill */ ESM::Skill::LongBlade, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "1b", - /* long group */ "bluntonehand", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 BluntOneHand", - /* usage skill */ ESM::Skill::BluntWeapon, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "1b", + /* long group */ "bluntonehand", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 BluntOneHand", + /* usage skill */ ESM::Skill::BluntWeapon, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "1b", - /* long group */ "bluntonehand", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 LongBladeOneHand", - /* usage skill */ ESM::Skill::Axe, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "1b", + /* long group */ "bluntonehand", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 LongBladeOneHand", + /* usage skill */ ESM::Skill::Axe, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "2c", - /* long group */ "weapontwohand", - /* sound ID */ "Item Weapon Longblade", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 LongBladeTwoClose", - /* usage skill */ ESM::Skill::LongBlade, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "2c", + /* long group */ "weapontwohand", + /* sound ID */ "Item Weapon Longblade", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 LongBladeTwoClose", + /* usage skill */ ESM::Skill::LongBlade, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "2b", - /* long group */ "blunttwohand", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 AxeTwoClose", - /* usage skill */ ESM::Skill::Axe, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "2b", + /* long group */ "blunttwohand", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 AxeTwoClose", + /* usage skill */ ESM::Skill::Axe, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "2b", - /* long group */ "blunttwohand", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 BluntTwoClose", - /* usage skill */ ESM::Skill::BluntWeapon, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "2b", + /* long group */ "blunttwohand", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 BluntTwoClose", + /* usage skill */ ESM::Skill::BluntWeapon, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "2w", - /* long group */ "weapontwowide", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 BluntTwoWide", - /* usage skill */ ESM::Skill::BluntWeapon, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "2w", + /* long group */ "weapontwowide", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 BluntTwoWide", + /* usage skill */ ESM::Skill::BluntWeapon, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "2w", - /* long group */ "weapontwowide", - /* sound ID */ "Item Weapon Spear", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 SpearTwoWide", - /* usage skill */ ESM::Skill::Spear, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "2w", + /* long group */ "weapontwowide", + /* sound ID */ "Item Weapon Spear", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 SpearTwoWide", + /* usage skill */ ESM::Skill::Spear, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "bow", - /* long group */ "bowandarrow", - /* sound ID */ "Item Weapon Bow", - /* attach bone */ "Weapon Bone Left", - /* sheath bone */ "Bip01 MarksmanBow", - /* usage skill */ ESM::Skill::Marksman, - /* weapon class*/ ESM::WeaponType::Ranged, - /* ammo type */ ESM::Weapon::Arrow, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "bow", + /* long group */ "bowandarrow", + /* sound ID */ "Item Weapon Bow", + /* attach bone */ "Weapon Bone Left", + /* sheath bone */ "Bip01 MarksmanBow", + /* usage skill */ ESM::Skill::Marksman, + /* weapon class*/ ESM::WeaponType::Ranged, + /* ammo type */ ESM::Weapon::Arrow, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "crossbow", - /* long group */ "crossbow", - /* sound ID */ "Item Weapon Crossbow", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 MarksmanCrossbow", - /* usage skill */ ESM::Skill::Marksman, - /* weapon class*/ ESM::WeaponType::Ranged, - /* ammo type */ ESM::Weapon::Bolt, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "crossbow", + /* long group */ "crossbow", + /* sound ID */ "Item Weapon Crossbow", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 MarksmanCrossbow", + /* usage skill */ ESM::Skill::Marksman, + /* weapon class*/ ESM::WeaponType::Ranged, + /* ammo type */ ESM::Weapon::Bolt, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "1t", - /* long group */ "throwweapon", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 MarksmanThrown", - /* usage skill */ ESM::Skill::Marksman, - /* weapon class*/ ESM::WeaponType::Thrown, - /* ammo type */ ESM::Weapon::None, - /* flags */ 0 }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "1t", + /* long group */ "throwweapon", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 MarksmanThrown", + /* usage skill */ ESM::Skill::Marksman, + /* weapon class*/ ESM::WeaponType::Thrown, + /* ammo type */ ESM::Weapon::None, + /* flags */ 0 }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "", - /* long group */ "", - /* sound ID */ "Item Ammo", - /* attach bone */ "Bip01 Arrow", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::Marksman, - /* weapon class*/ ESM::WeaponType::Ammo, - /* ammo type */ ESM::Weapon::None, - /* flags */ 0 }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "", + /* long group */ "", + /* sound ID */ "Item Ammo", + /* attach bone */ "Bip01 Arrow", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::Marksman, + /* weapon class*/ ESM::WeaponType::Ammo, + /* ammo type */ ESM::Weapon::None, + /* flags */ 0 }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "", - /* long group */ "", - /* sound ID */ "Item Ammo", - /* attach bone */ "ArrowBone", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::Marksman, - /* weapon class*/ ESM::WeaponType::Ammo, - /* ammo type */ ESM::Weapon::None, - /* flags */ 0 }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "", + /* long group */ "", + /* sound ID */ "Item Ammo", + /* attach bone */ "ArrowBone", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::Marksman, + /* weapon class*/ ESM::WeaponType::Ammo, + /* ammo type */ ESM::Weapon::None, + /* flags */ 0 }; + return value; + } }; MWWorld::ContainerStoreIterator getActiveWeapon(const MWWorld::Ptr& actor, int* weaptype) @@ -305,43 +377,43 @@ namespace MWMechanics switch (static_cast(weaponType)) { case ESM::Weapon::PickProbe: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::HandToHand: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::Spell: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::None: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::ShortBladeOneHand: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::LongBladeOneHand: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::LongBladeTwoHand: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::BluntOneHand: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::BluntTwoClose: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::BluntTwoWide: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::SpearTwoWide: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::AxeOneHand: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::AxeTwoHand: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::MarksmanBow: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::MarksmanCrossbow: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::MarksmanThrown: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::Arrow: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::Bolt: - return &Weapon::sValue; + return &Weapon::getValue(); } - return &Weapon::sValue; + return &Weapon::getValue(); } } diff --git a/components/esm3/loadskil.cpp b/components/esm3/loadskil.cpp index 73fb7f34e3..21549df05b 100644 --- a/components/esm3/loadskil.cpp +++ b/components/esm3/loadskil.cpp @@ -7,44 +7,33 @@ namespace ESM { - const std::string Skill::sSkillNames[Length] = { - "Block", - "Armorer", - "Mediumarmor", - "Heavyarmor", - "Bluntweapon", - "Longblade", - "Axe", - "Spear", - "Athletics", - "Enchant", - "Destruction", - "Alteration", - "Illusion", - "Conjuration", - "Mysticism", - "Restoration", - "Alchemy", - "Unarmored", - "Security", - "Sneak", - "Acrobatics", - "Lightarmor", - "Shortblade", - "Marksman", - "Mercantile", - "Speechcraft", - "Handtohand", - }; - - int Skill::stringToSkillId(std::string_view skill) - { - for (int id = 0; id < Skill::Length; ++id) - if (Misc::StringUtils::ciEqual(sSkillNames[id], skill)) - return id; - - throw std::logic_error("No such skill: " + std::string(skill)); - } + const RefId Skill::Block = RefId::stringRefId("Block"); + const RefId Skill::Armorer = RefId::stringRefId("Armorer"); + const RefId Skill::MediumArmor = RefId::stringRefId("MediumArmor"); + const RefId Skill::HeavyArmor = RefId::stringRefId("HeavyArmor"); + const RefId Skill::BluntWeapon = RefId::stringRefId("BluntWeapon"); + const RefId Skill::LongBlade = RefId::stringRefId("LongBlade"); + const RefId Skill::Axe = RefId::stringRefId("Axe"); + const RefId Skill::Spear = RefId::stringRefId("Spear"); + const RefId Skill::Athletics = RefId::stringRefId("Athletics"); + const RefId Skill::Enchant = RefId::stringRefId("Enchant"); + const RefId Skill::Destruction = RefId::stringRefId("Destruction"); + const RefId Skill::Alteration = RefId::stringRefId("Alteration"); + const RefId Skill::Illusion = RefId::stringRefId("Illusion"); + const RefId Skill::Conjuration = RefId::stringRefId("Conjuration"); + const RefId Skill::Mysticism = RefId::stringRefId("Mysticism"); + const RefId Skill::Restoration = RefId::stringRefId("Restoration"); + const RefId Skill::Alchemy = RefId::stringRefId("Alchemy"); + const RefId Skill::Unarmored = RefId::stringRefId("Unarmored"); + const RefId Skill::Security = RefId::stringRefId("Security"); + const RefId Skill::Sneak = RefId::stringRefId("Sneak"); + const RefId Skill::Acrobatics = RefId::stringRefId("Acrobatics"); + const RefId Skill::LightArmor = RefId::stringRefId("LightArmor"); + const RefId Skill::ShortBlade = RefId::stringRefId("ShortBlade"); + const RefId Skill::Marksman = RefId::stringRefId("Marksman"); + const RefId Skill::Mercantile = RefId::stringRefId("Mercantile"); + const RefId Skill::Speechcraft = RefId::stringRefId("Speechcraft"); + const RefId Skill::HandToHand = RefId::stringRefId("HandToHand"); void Skill::load(ESMReader& esm, bool& isDeleted) { @@ -102,19 +91,49 @@ namespace ESM mDescription.clear(); } + static const RefId sSkills[] = { + Skill::Block, + Skill::Armorer, + Skill::MediumArmor, + Skill::HeavyArmor, + Skill::BluntWeapon, + Skill::LongBlade, + Skill::Axe, + Skill::Spear, + Skill::Athletics, + Skill::Enchant, + Skill::Destruction, + Skill::Alteration, + Skill::Illusion, + Skill::Conjuration, + Skill::Mysticism, + Skill::Restoration, + Skill::Alchemy, + Skill::Unarmored, + Skill::Security, + Skill::Sneak, + Skill::Acrobatics, + Skill::LightArmor, + Skill::ShortBlade, + Skill::Marksman, + Skill::Mercantile, + Skill::Speechcraft, + Skill::HandToHand, + }; + RefId Skill::indexToRefId(int index) { if (index < 0 || index >= Length) return RefId(); - return RefId::index(sRecordId, static_cast(index)); + return sSkills[index]; } int Skill::refIdToIndex(RefId id) { - if (const IndexRefId* index = id.getIf()) + for (int i = 0; i < Length; ++i) { - if (index->getRecordType() == sRecordId) - return index->getValue(); + if (sSkills[i] == id) + return i; } return -1; } diff --git a/components/esm3/loadskil.hpp b/components/esm3/loadskil.hpp index f8e3390fa1..57680e56eb 100644 --- a/components/esm3/loadskil.hpp +++ b/components/esm3/loadskil.hpp @@ -61,37 +61,34 @@ namespace ESM float mWerewolfValue{}; std::optional mSchool; - static constexpr IndexRefId Block{ sRecordId, 0 }; - static constexpr IndexRefId Armorer{ sRecordId, 1 }; - static constexpr IndexRefId MediumArmor{ sRecordId, 2 }; - static constexpr IndexRefId HeavyArmor{ sRecordId, 3 }; - static constexpr IndexRefId BluntWeapon{ sRecordId, 4 }; - static constexpr IndexRefId LongBlade{ sRecordId, 5 }; - static constexpr IndexRefId Axe{ sRecordId, 6 }; - static constexpr IndexRefId Spear{ sRecordId, 7 }; - static constexpr IndexRefId Athletics{ sRecordId, 8 }; - static constexpr IndexRefId Enchant{ sRecordId, 9 }; - static constexpr IndexRefId Destruction{ sRecordId, 10 }; - static constexpr IndexRefId Alteration{ sRecordId, 11 }; - static constexpr IndexRefId Illusion{ sRecordId, 12 }; - static constexpr IndexRefId Conjuration{ sRecordId, 13 }; - static constexpr IndexRefId Mysticism{ sRecordId, 14 }; - static constexpr IndexRefId Restoration{ sRecordId, 15 }; - static constexpr IndexRefId Alchemy{ sRecordId, 16 }; - static constexpr IndexRefId Unarmored{ sRecordId, 17 }; - static constexpr IndexRefId Security{ sRecordId, 18 }; - static constexpr IndexRefId Sneak{ sRecordId, 19 }; - static constexpr IndexRefId Acrobatics{ sRecordId, 20 }; - static constexpr IndexRefId LightArmor{ sRecordId, 21 }; - static constexpr IndexRefId ShortBlade{ sRecordId, 22 }; - static constexpr IndexRefId Marksman{ sRecordId, 23 }; - static constexpr IndexRefId Mercantile{ sRecordId, 24 }; - static constexpr IndexRefId Speechcraft{ sRecordId, 25 }; - static constexpr IndexRefId HandToHand{ sRecordId, 26 }; + static const RefId Block; + static const RefId Armorer; + static const RefId MediumArmor; + static const RefId HeavyArmor; + static const RefId BluntWeapon; + static const RefId LongBlade; + static const RefId Axe; + static const RefId Spear; + static const RefId Athletics; + static const RefId Enchant; + static const RefId Destruction; + static const RefId Alteration; + static const RefId Illusion; + static const RefId Conjuration; + static const RefId Mysticism; + static const RefId Restoration; + static const RefId Alchemy; + static const RefId Unarmored; + static const RefId Security; + static const RefId Sneak; + static const RefId Acrobatics; + static const RefId LightArmor; + static const RefId ShortBlade; + static const RefId Marksman; + static const RefId Mercantile; + static const RefId Speechcraft; + static const RefId HandToHand; static constexpr int Length = 27; - static const std::string sSkillNames[Length]; - - static int stringToSkillId(std::string_view skill); void load(ESMReader& esm, bool& isDeleted); void save(ESMWriter& esm, bool isDeleted = false) const;