mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-05-09 03:57:51 +03: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
|
@ -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…
Add table
Add a link
Reference in a new issue