mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-28 13:09:42 +00:00
Merge branch 'stringrefidskills' into 'master'
Assign StringRefIds to skills See merge request OpenMW/openmw!3146
This commit is contained in:
commit
03dbe1c9f3
21 changed files with 444 additions and 325 deletions
|
@ -1264,7 +1264,8 @@ namespace EsmTool
|
|||
template <>
|
||||
void Record<ESM::Skill>::print()
|
||||
{
|
||||
std::cout << " ID: " << skillLabel(mData.mIndex) << " (" << mData.mIndex << ")" << std::endl;
|
||||
int index = ESM::Skill::refIdToIndex(mData.mId);
|
||||
std::cout << " ID: " << skillLabel(index) << " (" << index << ")" << std::endl;
|
||||
std::cout << " Description: " << mData.mDescription << std::endl;
|
||||
std::cout << " Governing Attribute: " << attributeLabel(mData.mData.mAttribute) << " ("
|
||||
<< mData.mData.mAttribute << ")" << std::endl;
|
||||
|
|
|
@ -201,11 +201,10 @@ void CSMDoc::Document::createBase()
|
|||
|
||||
addGmsts();
|
||||
|
||||
for (int i = 0; i < 27; ++i)
|
||||
for (int i = 0; i < ESM::Skill::Length; ++i)
|
||||
{
|
||||
ESM::Skill record;
|
||||
record.mIndex = i;
|
||||
record.mId = ESM::Skill::indexToRefId(record.mIndex);
|
||||
record.mId = *ESM::Skill::indexToRefId(i).getIf<ESM::SkillId>();
|
||||
record.blank();
|
||||
|
||||
getData().getSkills().add(record);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <QVariant>
|
||||
|
||||
#include <components/esm3/loaddial.hpp>
|
||||
#include <components/esm3/loadskil.hpp>
|
||||
#include <components/misc/strings/lower.hpp>
|
||||
|
||||
#include "collectionbase.hpp"
|
||||
|
@ -86,6 +87,13 @@ namespace CSMWorld
|
|||
return ESM::RefId::stringRefId(LandTexture::createUniqueRecordId(record.mPluginIndex, record.mIndex));
|
||||
}
|
||||
|
||||
inline void setRecordId(const ESM::RefId& id, ESM::Skill& record)
|
||||
{
|
||||
if (const auto* skillId = id.getIf<ESM::SkillId>())
|
||||
record.mId = *skillId;
|
||||
throw std::runtime_error("Invalid skill id: " + id.toDebugString());
|
||||
}
|
||||
|
||||
/// \brief Single-type record collection
|
||||
template <typename ESXRecordT>
|
||||
class Collection : public CollectionBase
|
||||
|
|
|
@ -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<std::uint32_t> 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<std::uint32_t>(it - std::begin(ESM::Skill::sSkillNames));
|
||||
return static_cast<std::uint32_t>(index);
|
||||
}
|
||||
|
||||
std::string getStringId(ESM::RefId value)
|
||||
|
|
|
@ -409,7 +409,8 @@ namespace CSMWorld
|
|||
|
||||
QVariant get(const Record<ESXRecordT>& 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<ESXRecordT>& record, const QVariant& data) override
|
||||
|
|
|
@ -121,11 +121,12 @@ namespace
|
|||
|
||||
// is this a minor or major skill?
|
||||
float add = 0.2f;
|
||||
int index = ESM::Skill::refIdToIndex(skill.mId);
|
||||
for (const auto& skills : class_->mData.mSkills)
|
||||
{
|
||||
if (skills[0] == skill.mIndex)
|
||||
if (skills[0] == index)
|
||||
add = 0.5;
|
||||
if (skills[1] == skill.mIndex)
|
||||
if (skills[1] == index)
|
||||
add = 1.0;
|
||||
}
|
||||
modifierSum += add;
|
||||
|
@ -199,15 +200,16 @@ namespace
|
|||
int raceBonus = 0;
|
||||
int specBonus = 0;
|
||||
|
||||
int index = ESM::Skill::refIdToIndex(skill.mId);
|
||||
auto bonusIt = std::find_if(race->mData.mBonus.begin(), race->mData.mBonus.end(),
|
||||
[&](const auto& bonus) { return bonus.mSkill == skill.mIndex; });
|
||||
[&](const auto& bonus) { return bonus.mSkill == index; });
|
||||
if (bonusIt != race->mData.mBonus.end())
|
||||
raceBonus = bonusIt->mBonus;
|
||||
|
||||
for (const auto& skills : class_->mData.mSkills)
|
||||
{
|
||||
// is this a minor or major skill?
|
||||
if (std::find(skills.begin(), skills.end(), skill.mIndex) != skills.end())
|
||||
if (std::find(skills.begin(), skills.end(), index) != skills.end())
|
||||
{
|
||||
majorMultiplier = 1.0f;
|
||||
break;
|
||||
|
|
|
@ -471,8 +471,8 @@ namespace MWGui
|
|||
assert(minorSkills.size() >= klass.mData.mSkills.size());
|
||||
for (size_t i = 0; i < klass.mData.mSkills.size(); ++i)
|
||||
{
|
||||
klass.mData.mSkills[i][1] = majorSkills[i].getIf<ESM::IndexRefId>()->getValue();
|
||||
klass.mData.mSkills[i][0] = minorSkills[i].getIf<ESM::IndexRefId>()->getValue();
|
||||
klass.mData.mSkills[i][1] = ESM::Skill::refIdToIndex(majorSkills[i]);
|
||||
klass.mData.mSkills[i][0] = ESM::Skill::refIdToIndex(minorSkills[i]);
|
||||
}
|
||||
|
||||
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(klass);
|
||||
|
|
|
@ -287,7 +287,7 @@ namespace MWGui
|
|||
|
||||
void EditEffectDialog::setSkill(ESM::RefId skill)
|
||||
{
|
||||
mEffect.mSkill = skill.getIf<ESM::IndexRefId>()->getValue();
|
||||
mEffect.mSkill = ESM::Skill::refIdToIndex(skill);
|
||||
eventEffectModified(mEffect);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <components/lua/l10n.hpp>
|
||||
#include <components/lua/luastate.hpp>
|
||||
#include <components/lua/utilpackage.hpp>
|
||||
#include <components/misc/strings/lower.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/statemanager.hpp"
|
||||
|
@ -156,10 +157,18 @@ namespace MWLua
|
|||
return sol::nil;
|
||||
};
|
||||
|
||||
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]);
|
||||
// TODO: deprecate this and provide access to the store instead
|
||||
sol::table skills(context.mLua->sol(), sol::create);
|
||||
api["SKILL"] = LuaUtil::makeStrictReadOnly(skills);
|
||||
for (int i = 0; i < ESM::Skill::Length; ++i)
|
||||
{
|
||||
ESM::RefId skill = ESM::Skill::indexToRefId(i);
|
||||
std::string id = skill.serializeText();
|
||||
std::string key = Misc::StringUtils::lowerCase(skill.getRefIdString());
|
||||
// force first character to uppercase for backwards compatability
|
||||
key[0] += 'A' - 'a';
|
||||
skills[key] = id;
|
||||
}
|
||||
|
||||
sol::table attribute(context.mLua->sol(), sol::create);
|
||||
api["ATTRIBUTE"] = LuaUtil::makeStrictReadOnly(attribute);
|
||||
|
|
|
@ -309,10 +309,10 @@ namespace MWLua
|
|||
});
|
||||
effectParamsT["affectedSkill"]
|
||||
= sol::readonly_property([](const ESM::ENAMstruct& params) -> sol::optional<std::string> {
|
||||
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<std::string> {
|
||||
|
@ -383,11 +383,12 @@ namespace MWLua
|
|||
activeEffectT["affectedSkill"]
|
||||
= sol::readonly_property([magicEffectStore](const ActiveEffect& effect) -> sol::optional<std::string> {
|
||||
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<std::string> {
|
||||
|
@ -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::deserializeText(argStr.value());
|
||||
key = MWMechanics::EffectKey(id, ESM::Skill::refIdToIndex(skill));
|
||||
}
|
||||
}
|
||||
|
||||
return key;
|
||||
|
|
|
@ -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<ESM::Skill>())
|
||||
skills[Misc::StringUtils::lowerCase(ESM::Skill::sSkillNames[skill.mIndex])]
|
||||
= addIndexedAccessor<SkillStat>(skill.mId);
|
||||
skills[ESM::RefId(skill.mId).serializeText()] = addIndexedAccessor<SkillStat>(skill.mId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,18 +41,14 @@ namespace
|
|||
book.mData.mValue = rec["value"];
|
||||
book.mData.mIsScroll = rec["isScroll"];
|
||||
|
||||
std::string_view skill = rec["skill"].get<std::string_view>();
|
||||
ESM::RefId skill = ESM::RefId::deserializeText(rec["skill"].get<std::string_view>());
|
||||
|
||||
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<std::string> {
|
||||
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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,9 +158,9 @@ namespace MWMechanics
|
|||
for (const ESM::Skill& skill : esmStore.get<ESM::Skill>())
|
||||
{
|
||||
int bonus = 0;
|
||||
|
||||
int index = ESM::Skill::refIdToIndex(skill.mId);
|
||||
auto bonusIt = std::find_if(race->mData.mBonus.begin(), race->mData.mBonus.end(),
|
||||
[&](const auto& bonus) { return bonus.mSkill == skill.mIndex; });
|
||||
[&](const auto& bonus) { return bonus.mSkill == index; });
|
||||
if (bonusIt != race->mData.mBonus.end())
|
||||
bonus = bonusIt->mBonus;
|
||||
|
||||
|
|
|
@ -155,15 +155,15 @@ float MWMechanics::NpcStats::getSkillProgressRequirement(ESM::RefId id, const ES
|
|||
const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get<ESM::Skill>().find(id);
|
||||
|
||||
float typeFactor = gmst.find("fMiscSkillBonus")->mValue.getFloat();
|
||||
|
||||
int index = ESM::Skill::refIdToIndex(skill->mId);
|
||||
for (const auto& skills : class_.mData.mSkills)
|
||||
{
|
||||
if (skills[0] == skill->mIndex)
|
||||
if (skills[0] == index)
|
||||
{
|
||||
typeFactor = gmst.find("fMinorSkillBonus")->mValue.getFloat();
|
||||
break;
|
||||
}
|
||||
else if (skills[1] == skill->mIndex)
|
||||
else if (skills[1] == index)
|
||||
{
|
||||
typeFactor = gmst.find("fMajorSkillBonus")->mValue.getFloat();
|
||||
break;
|
||||
|
@ -228,15 +228,16 @@ void MWMechanics::NpcStats::increaseSkill(ESM::RefId id, const ESM::Class& class
|
|||
|
||||
// is this a minor or major skill?
|
||||
int increase = gmst.find("iLevelupMiscMultAttriubte")->mValue.getInteger(); // Note: GMST has a typo
|
||||
int index = ESM::Skill::refIdToIndex(skill->mId);
|
||||
for (const auto& skills : class_.mData.mSkills)
|
||||
{
|
||||
if (skills[0] == skill->mIndex)
|
||||
if (skills[0] == index)
|
||||
{
|
||||
mLevelProgress += gmst.find("iLevelUpMinorMult")->mValue.getInteger();
|
||||
increase = gmst.find("iLevelUpMinorMultAttribute")->mValue.getInteger();
|
||||
break;
|
||||
}
|
||||
else if (skills[1] == skill->mIndex)
|
||||
else if (skills[1] == index)
|
||||
{
|
||||
mLevelProgress += gmst.find("iLevelUpMajorMult")->mValue.getInteger();
|
||||
increase = gmst.find("iLevelUpMajorMultAttribute")->mValue.getInteger();
|
||||
|
@ -463,7 +464,7 @@ void MWMechanics::NpcStats::writeState(ESM::NpcStats& state) const
|
|||
for (const auto& [id, value] : mSkills)
|
||||
{
|
||||
// TODO extend format
|
||||
auto index = id.getIf<ESM::IndexRefId>()->getValue();
|
||||
auto index = ESM::Skill::refIdToIndex(id);
|
||||
value.writeState(state.mSkills[index]);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,253 +18,325 @@ namespace MWMechanics
|
|||
template <>
|
||||
struct Weapon<ESM::Weapon::None>
|
||||
{
|
||||
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<ESM::Weapon::PickProbe>
|
||||
{
|
||||
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<ESM::Weapon::Spell>
|
||||
{
|
||||
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<ESM::Weapon::HandToHand>
|
||||
{
|
||||
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<ESM::Weapon::ShortBladeOneHand>
|
||||
{
|
||||
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<ESM::Weapon::LongBladeOneHand>
|
||||
{
|
||||
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<ESM::Weapon::BluntOneHand>
|
||||
{
|
||||
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<ESM::Weapon::AxeOneHand>
|
||||
{
|
||||
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<ESM::Weapon::LongBladeTwoHand>
|
||||
{
|
||||
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<ESM::Weapon::AxeTwoHand>
|
||||
{
|
||||
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<ESM::Weapon::BluntTwoClose>
|
||||
{
|
||||
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<ESM::Weapon::BluntTwoWide>
|
||||
{
|
||||
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<ESM::Weapon::SpearTwoWide>
|
||||
{
|
||||
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<ESM::Weapon::MarksmanBow>
|
||||
{
|
||||
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<ESM::Weapon::MarksmanCrossbow>
|
||||
{
|
||||
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<ESM::Weapon::MarksmanThrown>
|
||||
{
|
||||
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<ESM::Weapon::Arrow>
|
||||
{
|
||||
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<ESM::Weapon::Bolt>
|
||||
{
|
||||
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<ESM::Weapon::Type>(weaponType))
|
||||
{
|
||||
case ESM::Weapon::PickProbe:
|
||||
return &Weapon<ESM::Weapon::PickProbe>::sValue;
|
||||
return &Weapon<ESM::Weapon::PickProbe>::getValue();
|
||||
case ESM::Weapon::HandToHand:
|
||||
return &Weapon<ESM::Weapon::HandToHand>::sValue;
|
||||
return &Weapon<ESM::Weapon::HandToHand>::getValue();
|
||||
case ESM::Weapon::Spell:
|
||||
return &Weapon<ESM::Weapon::Spell>::sValue;
|
||||
return &Weapon<ESM::Weapon::Spell>::getValue();
|
||||
case ESM::Weapon::None:
|
||||
return &Weapon<ESM::Weapon::None>::sValue;
|
||||
return &Weapon<ESM::Weapon::None>::getValue();
|
||||
case ESM::Weapon::ShortBladeOneHand:
|
||||
return &Weapon<ESM::Weapon::ShortBladeOneHand>::sValue;
|
||||
return &Weapon<ESM::Weapon::ShortBladeOneHand>::getValue();
|
||||
case ESM::Weapon::LongBladeOneHand:
|
||||
return &Weapon<ESM::Weapon::LongBladeOneHand>::sValue;
|
||||
return &Weapon<ESM::Weapon::LongBladeOneHand>::getValue();
|
||||
case ESM::Weapon::LongBladeTwoHand:
|
||||
return &Weapon<ESM::Weapon::LongBladeTwoHand>::sValue;
|
||||
return &Weapon<ESM::Weapon::LongBladeTwoHand>::getValue();
|
||||
case ESM::Weapon::BluntOneHand:
|
||||
return &Weapon<ESM::Weapon::BluntOneHand>::sValue;
|
||||
return &Weapon<ESM::Weapon::BluntOneHand>::getValue();
|
||||
case ESM::Weapon::BluntTwoClose:
|
||||
return &Weapon<ESM::Weapon::BluntTwoClose>::sValue;
|
||||
return &Weapon<ESM::Weapon::BluntTwoClose>::getValue();
|
||||
case ESM::Weapon::BluntTwoWide:
|
||||
return &Weapon<ESM::Weapon::BluntTwoWide>::sValue;
|
||||
return &Weapon<ESM::Weapon::BluntTwoWide>::getValue();
|
||||
case ESM::Weapon::SpearTwoWide:
|
||||
return &Weapon<ESM::Weapon::SpearTwoWide>::sValue;
|
||||
return &Weapon<ESM::Weapon::SpearTwoWide>::getValue();
|
||||
case ESM::Weapon::AxeOneHand:
|
||||
return &Weapon<ESM::Weapon::AxeOneHand>::sValue;
|
||||
return &Weapon<ESM::Weapon::AxeOneHand>::getValue();
|
||||
case ESM::Weapon::AxeTwoHand:
|
||||
return &Weapon<ESM::Weapon::AxeTwoHand>::sValue;
|
||||
return &Weapon<ESM::Weapon::AxeTwoHand>::getValue();
|
||||
case ESM::Weapon::MarksmanBow:
|
||||
return &Weapon<ESM::Weapon::MarksmanBow>::sValue;
|
||||
return &Weapon<ESM::Weapon::MarksmanBow>::getValue();
|
||||
case ESM::Weapon::MarksmanCrossbow:
|
||||
return &Weapon<ESM::Weapon::MarksmanCrossbow>::sValue;
|
||||
return &Weapon<ESM::Weapon::MarksmanCrossbow>::getValue();
|
||||
case ESM::Weapon::MarksmanThrown:
|
||||
return &Weapon<ESM::Weapon::MarksmanThrown>::sValue;
|
||||
return &Weapon<ESM::Weapon::MarksmanThrown>::getValue();
|
||||
case ESM::Weapon::Arrow:
|
||||
return &Weapon<ESM::Weapon::Arrow>::sValue;
|
||||
return &Weapon<ESM::Weapon::Arrow>::getValue();
|
||||
case ESM::Weapon::Bolt:
|
||||
return &Weapon<ESM::Weapon::Bolt>::sValue;
|
||||
return &Weapon<ESM::Weapon::Bolt>::getValue();
|
||||
}
|
||||
|
||||
return &Weapon<ESM::Weapon::ShortBladeOneHand>::sValue;
|
||||
return &Weapon<ESM::Weapon::ShortBladeOneHand>::getValue();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -962,12 +962,14 @@ namespace MWWorld
|
|||
};
|
||||
for (ESM::Skill* skill : mShared)
|
||||
{
|
||||
if (skill->mIndex >= 0)
|
||||
int index = ESM::Skill::refIdToIndex(skill->mId);
|
||||
if (index >= 0)
|
||||
{
|
||||
skill->mName = getGMSTString(settings, skillValues[skill->mIndex][0]);
|
||||
skill->mIcon = skillValues[skill->mIndex][1];
|
||||
skill->mWerewolfValue = getGMSTFloat(settings, skillValues[skill->mIndex][2]);
|
||||
const auto& school = skillValues[skill->mIndex][3];
|
||||
const auto& values = skillValues[index];
|
||||
skill->mName = getGMSTString(settings, values[0]);
|
||||
skill->mIcon = values[1];
|
||||
skill->mWerewolfValue = getGMSTFloat(settings, values[2]);
|
||||
const auto& school = values[3];
|
||||
if (!school.empty())
|
||||
{
|
||||
if (!skill->mSchool)
|
||||
|
|
|
@ -462,6 +462,8 @@ namespace
|
|||
{
|
||||
refId = ESM::RefId::esm3ExteriorCell(0, 0);
|
||||
}
|
||||
else if constexpr (std::is_same_v<RecordType, ESM::Skill>)
|
||||
refId = ESM::Skill::Block;
|
||||
else
|
||||
refId = ESM::StringRefId(stringId);
|
||||
|
||||
|
@ -496,7 +498,7 @@ namespace
|
|||
const RecordType* result = nullptr;
|
||||
if constexpr (std::is_same_v<RecordType, ESM::LandTexture>)
|
||||
result = esmStore.get<RecordType>().search(index, 0);
|
||||
else if constexpr (ESM::hasIndex<RecordType> && !std::is_same_v<RecordType, ESM::Skill>)
|
||||
else if constexpr (ESM::hasIndex<RecordType>)
|
||||
result = esmStore.get<RecordType>().search(index);
|
||||
else
|
||||
result = esmStore.get<RecordType>().search(refId);
|
||||
|
|
|
@ -5,46 +5,37 @@
|
|||
|
||||
#include <components/misc/strings/algorithm.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
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 SkillId Skill::Block("Block");
|
||||
const SkillId Skill::Armorer("Armorer");
|
||||
const SkillId Skill::MediumArmor("MediumArmor");
|
||||
const SkillId Skill::HeavyArmor("HeavyArmor");
|
||||
const SkillId Skill::BluntWeapon("BluntWeapon");
|
||||
const SkillId Skill::LongBlade("LongBlade");
|
||||
const SkillId Skill::Axe("Axe");
|
||||
const SkillId Skill::Spear("Spear");
|
||||
const SkillId Skill::Athletics("Athletics");
|
||||
const SkillId Skill::Enchant("Enchant");
|
||||
const SkillId Skill::Destruction("Destruction");
|
||||
const SkillId Skill::Alteration("Alteration");
|
||||
const SkillId Skill::Illusion("Illusion");
|
||||
const SkillId Skill::Conjuration("Conjuration");
|
||||
const SkillId Skill::Mysticism("Mysticism");
|
||||
const SkillId Skill::Restoration("Restoration");
|
||||
const SkillId Skill::Alchemy("Alchemy");
|
||||
const SkillId Skill::Unarmored("Unarmored");
|
||||
const SkillId Skill::Security("Security");
|
||||
const SkillId Skill::Sneak("Sneak");
|
||||
const SkillId Skill::Acrobatics("Acrobatics");
|
||||
const SkillId Skill::LightArmor("LightArmor");
|
||||
const SkillId Skill::ShortBlade("ShortBlade");
|
||||
const SkillId Skill::Marksman("Marksman");
|
||||
const SkillId Skill::Mercantile("Mercantile");
|
||||
const SkillId Skill::Speechcraft("Speechcraft");
|
||||
const SkillId Skill::HandToHand("HandToHand");
|
||||
|
||||
void Skill::load(ESMReader& esm, bool& isDeleted)
|
||||
{
|
||||
|
@ -53,13 +44,14 @@ namespace ESM
|
|||
|
||||
bool hasIndex = false;
|
||||
bool hasData = false;
|
||||
int32_t index = -1;
|
||||
while (esm.hasMoreSubs())
|
||||
{
|
||||
esm.getSubName();
|
||||
switch (esm.retSubName().toInt())
|
||||
{
|
||||
case fourCC("INDX"):
|
||||
esm.getHT(mIndex);
|
||||
esm.getHT(index);
|
||||
hasIndex = true;
|
||||
break;
|
||||
case fourCC("SKDT"):
|
||||
|
@ -75,19 +67,17 @@ namespace ESM
|
|||
}
|
||||
if (!hasIndex)
|
||||
esm.fail("Missing INDX");
|
||||
else if (mIndex < 0 || mIndex >= Length)
|
||||
else if (index < 0 || index >= Length)
|
||||
esm.fail("Invalid INDX");
|
||||
if (!hasData)
|
||||
esm.fail("Missing SKDT");
|
||||
|
||||
// create an ID from the index and the name (only used in the editor and likely to change in the
|
||||
// future)
|
||||
mId = indexToRefId(mIndex);
|
||||
mId = *indexToRefId(index).getIf<SkillId>();
|
||||
}
|
||||
|
||||
void Skill::save(ESMWriter& esm, bool /*isDeleted*/) const
|
||||
{
|
||||
esm.writeHNT("INDX", mIndex);
|
||||
esm.writeHNT("INDX", refIdToIndex(mId));
|
||||
esm.writeHNT("SKDT", mData, 24);
|
||||
esm.writeHNOString("DESC", mDescription);
|
||||
}
|
||||
|
@ -101,11 +91,51 @@ namespace ESM
|
|||
mDescription.clear();
|
||||
}
|
||||
|
||||
static const RefId sSkills[Skill::Length] = {
|
||||
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<std::uint32_t>(index));
|
||||
return sSkills[index];
|
||||
}
|
||||
|
||||
int Skill::refIdToIndex(RefId id)
|
||||
{
|
||||
for (int i = 0; i < Length; ++i)
|
||||
{
|
||||
if (sSkills[i] == id)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
const std::array<RefId, MagicSchool::Length> sMagicSchools = {
|
||||
|
|
|
@ -14,6 +14,8 @@ namespace ESM
|
|||
class ESMReader;
|
||||
class ESMWriter;
|
||||
|
||||
using SkillId = StringRefId;
|
||||
|
||||
struct MagicSchool
|
||||
{
|
||||
ESM::RefId mAreaSound;
|
||||
|
@ -43,7 +45,7 @@ namespace ESM
|
|||
static std::string_view getRecordType() { return "Skill"; }
|
||||
|
||||
unsigned int mRecordFlags;
|
||||
RefId mId;
|
||||
SkillId mId;
|
||||
|
||||
struct SKDTstruct
|
||||
{
|
||||
|
@ -55,48 +57,40 @@ namespace ESM
|
|||
}; // Total size: 24 bytes
|
||||
SKDTstruct mData;
|
||||
|
||||
// Skill index. Skils don't have an id ("NAME") like most records,
|
||||
// they only have a numerical index that matches one of the
|
||||
// hard-coded skills in the game.
|
||||
int mIndex{ -1 };
|
||||
|
||||
std::string mDescription;
|
||||
std::string mName;
|
||||
std::string mIcon;
|
||||
float mWerewolfValue{};
|
||||
std::optional<MagicSchool> 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 SkillId Block;
|
||||
static const SkillId Armorer;
|
||||
static const SkillId MediumArmor;
|
||||
static const SkillId HeavyArmor;
|
||||
static const SkillId BluntWeapon;
|
||||
static const SkillId LongBlade;
|
||||
static const SkillId Axe;
|
||||
static const SkillId Spear;
|
||||
static const SkillId Athletics;
|
||||
static const SkillId Enchant;
|
||||
static const SkillId Destruction;
|
||||
static const SkillId Alteration;
|
||||
static const SkillId Illusion;
|
||||
static const SkillId Conjuration;
|
||||
static const SkillId Mysticism;
|
||||
static const SkillId Restoration;
|
||||
static const SkillId Alchemy;
|
||||
static const SkillId Unarmored;
|
||||
static const SkillId Security;
|
||||
static const SkillId Sneak;
|
||||
static const SkillId Acrobatics;
|
||||
static const SkillId LightArmor;
|
||||
static const SkillId ShortBlade;
|
||||
static const SkillId Marksman;
|
||||
static const SkillId Mercantile;
|
||||
static const SkillId Speechcraft;
|
||||
static const SkillId 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;
|
||||
|
@ -105,6 +99,7 @@ namespace ESM
|
|||
///< Set record to default state (does not touch the ID/index).
|
||||
|
||||
static RefId indexToRefId(int index);
|
||||
static int refIdToIndex(RefId id);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace ESM
|
|||
mWerewolfDeprecatedData = true;
|
||||
std::vector<StatState<float>> skills(mSkills.begin(), mSkills.end());
|
||||
|
||||
for (int i = 0; i < ESM::Skill::Length; ++i)
|
||||
for (size_t i = 0; i < std::size(mSkills); ++i)
|
||||
{
|
||||
StatState<float> skill;
|
||||
skill.load(esm, intFallback);
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace ESM
|
|||
= esm.getFormatVersion() <= MaxClearModifiersFormatVersion && !mObject.mNpcStats.mIsWerewolf;
|
||||
if (esm.hasMoreSubs())
|
||||
{
|
||||
for (int i = 0; i < Attribute::Length; ++i)
|
||||
for (size_t i = 0; i < std::size(mSaveAttributes); ++i)
|
||||
{
|
||||
StatState<float> attribute;
|
||||
attribute.load(esm, intFallback);
|
||||
|
@ -64,7 +64,7 @@ namespace ESM
|
|||
if (mObject.mNpcStats.mIsWerewolf)
|
||||
mObject.mCreatureStats.mAttributes[i] = attribute;
|
||||
}
|
||||
for (int i = 0; i < Skill::Length; ++i)
|
||||
for (size_t i = 0; i < std::size(mSaveSkills); ++i)
|
||||
{
|
||||
StatState<float> skill;
|
||||
skill.load(esm, intFallback);
|
||||
|
|
Loading…
Reference in a new issue