mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-03 07:09:40 +00:00
Support index RefId as pair of record type and std::uint32_t
This commit is contained in:
parent
86293af084
commit
e6cf516e12
16 changed files with 139 additions and 208 deletions
|
@ -134,7 +134,7 @@ void CSMDoc::Document::addOptionalMagicEffects()
|
|||
{
|
||||
ESM::MagicEffect effect;
|
||||
effect.mIndex = i;
|
||||
effect.mId = ESM::RefId::stringRefId(ESM::MagicEffect::indexToId(i));
|
||||
effect.mId = ESM::MagicEffect::indexToRefId(i);
|
||||
effect.blank();
|
||||
|
||||
addOptionalMagicEffect(effect);
|
||||
|
@ -207,7 +207,7 @@ void CSMDoc::Document::createBase()
|
|||
{
|
||||
ESM::Skill record;
|
||||
record.mIndex = i;
|
||||
record.mId = ESM::RefId::stringRefId(ESM::Skill::indexToId(record.mIndex));
|
||||
record.mId = ESM::Skill::indexToRefId(record.mIndex);
|
||||
record.blank();
|
||||
|
||||
getData().getSkills().add(record);
|
||||
|
@ -288,7 +288,7 @@ void CSMDoc::Document::createBase()
|
|||
ESM::MagicEffect record;
|
||||
|
||||
record.mIndex = i;
|
||||
record.mId = ESM::RefId::stringRefId(ESM::MagicEffect::indexToId(i));
|
||||
record.mId = ESM::MagicEffect::indexToRefId(i);
|
||||
|
||||
record.blank();
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ void CSMTools::ClassCheckStage::perform(int stage, CSMDoc::Messages& messages)
|
|||
for (auto& skill : skills)
|
||||
if (skill.second > 1)
|
||||
{
|
||||
messages.add(id, "Skill " + ESM::Skill::indexToId(skill.first) + " is listed more than once", "",
|
||||
CSMDoc::Message::Severity_Error);
|
||||
messages.add(id, "Skill " + ESM::Skill::indexToRefId(skill.first).toString() + " is listed more than once",
|
||||
"", CSMDoc::Message::Severity_Error);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,8 +61,8 @@ void CSMTools::FactionCheckStage::perform(int stage, CSMDoc::Messages& messages)
|
|||
for (auto& skill : skills)
|
||||
if (skill.second > 1)
|
||||
{
|
||||
messages.add(id, "Skill " + ESM::Skill::indexToId(skill.first) + " is listed more than once", "",
|
||||
CSMDoc::Message::Severity_Error);
|
||||
messages.add(id, "Skill " + ESM::Skill::indexToRefId(skill.first).toString() + " is listed more than once",
|
||||
"", CSMDoc::Message::Severity_Error);
|
||||
}
|
||||
|
||||
/// \todo check data members that can't be edited in the table view
|
||||
|
|
|
@ -404,7 +404,7 @@ namespace CSMWorld
|
|||
{
|
||||
int skill = record.get().mData.getSkill(mIndex, mMajor);
|
||||
|
||||
return QString::fromUtf8(ESM::Skill::indexToId(skill).c_str());
|
||||
return QString::fromStdString(ESM::Skill::indexToRefId(skill).toString());
|
||||
}
|
||||
|
||||
void set(Record<ESXRecordT>& record, const QVariant& data) override
|
||||
|
|
|
@ -213,6 +213,7 @@ namespace ESM
|
|||
{ RefId::stringRefId(std::string({ 'a', 0, -1, '\n', '\t' })), { 'a', 0, -1, '\n', '\t' } },
|
||||
{ RefId::formIdRefId(42), "42" },
|
||||
{ RefId::generated(42), "42" },
|
||||
{ RefId::index(ESM::REC_ARMO, 42), "ARMO, 42" },
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ESMRefIdToString, ESMRefIdToStringTest, ValuesIn(toStringParams));
|
||||
|
@ -243,6 +244,7 @@ namespace ESM
|
|||
{ RefId::stringRefId(std::string({ 'a', 0, -1, '\n', '\t' })), "String{a\\x0\\xFF\\xA\\x9}" },
|
||||
{ RefId::formIdRefId(42), "FormId{42}" },
|
||||
{ RefId::generated(42), "Generated{42}" },
|
||||
{ RefId::index(ESM::REC_ARMO, 42), "Index{ARMO, 42}" },
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ESMRefIdToDebugString, ESMRefIdToDebugStringTest, ValuesIn(toDebugStringParams));
|
||||
|
|
|
@ -450,7 +450,7 @@ namespace
|
|||
const int index = 3;
|
||||
decltype(RecordType::mId) refId;
|
||||
if constexpr (hasIndex<RecordType> && !std::is_same_v<RecordType, ESM::LandTexture>)
|
||||
refId = ESM::RefId::stringRefId(RecordType::indexToId(index));
|
||||
refId = RecordType::indexToRefId(index);
|
||||
else
|
||||
refId = ESM::StringRefId("foobar");
|
||||
|
||||
|
|
|
@ -89,7 +89,8 @@ add_component_dir(esm attr common defs esmcommon records util luascripts format
|
|||
formidrefid
|
||||
stringrefid
|
||||
generatedrefid
|
||||
)
|
||||
indexrefid
|
||||
)
|
||||
|
||||
add_component_dir(fx pass technique lexer widgets stateupdater)
|
||||
|
||||
|
|
26
components/esm/indexrefid.cpp
Normal file
26
components/esm/indexrefid.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include "indexrefid.hpp"
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "esmcommon.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
std::string IndexRefId::toString() const
|
||||
{
|
||||
return ESM::NAME(mRecordType).toString() + ", " + std::to_string(mValue);
|
||||
}
|
||||
|
||||
std::string IndexRefId::toDebugString() const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << *this;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, IndexRefId value)
|
||||
{
|
||||
return stream << "Index{" << ESM::NAME(value.mRecordType).toStringView() << ", " << value.mValue << '}';
|
||||
}
|
||||
}
|
61
components/esm/indexrefid.hpp
Normal file
61
components/esm/indexrefid.hpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
#ifndef OPENMW_COMPONENTS_ESM_INDEXREFID_HPP
|
||||
#define OPENMW_COMPONENTS_ESM_INDEXREFID_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <iosfwd>
|
||||
|
||||
#include "defs.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
class IndexRefId
|
||||
{
|
||||
public:
|
||||
constexpr explicit IndexRefId(RecNameInts recordType, std::uint32_t value) noexcept
|
||||
: mRecordType(recordType)
|
||||
, mValue(value)
|
||||
{
|
||||
}
|
||||
|
||||
constexpr RecNameInts getRecordType() const { return mRecordType; }
|
||||
|
||||
constexpr std::uint32_t getValue() const { return mValue; }
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
std::string toDebugString() const;
|
||||
|
||||
friend inline constexpr auto tie(const IndexRefId& value) noexcept
|
||||
{
|
||||
return std::tie(value.mRecordType, value.mValue);
|
||||
}
|
||||
|
||||
constexpr bool operator==(IndexRefId rhs) const noexcept { return tie(*this) == tie(rhs); }
|
||||
|
||||
constexpr bool operator<(IndexRefId rhs) const noexcept { return tie(*this) < tie(rhs); }
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& stream, IndexRefId value);
|
||||
|
||||
friend struct std::hash<IndexRefId>;
|
||||
|
||||
private:
|
||||
RecNameInts mRecordType;
|
||||
std::uint32_t mValue;
|
||||
};
|
||||
|
||||
static_assert(sizeof(IndexRefId) <= sizeof(std::uint64_t));
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct hash<ESM::IndexRefId>
|
||||
{
|
||||
std::size_t operator()(ESM::IndexRefId value) const noexcept
|
||||
{
|
||||
return std::hash<std::uint64_t>{}(static_cast<std::uint64_t>(value.mRecordType) | value.mValue);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "formidrefid.hpp"
|
||||
#include "generatedrefid.hpp"
|
||||
#include "indexrefid.hpp"
|
||||
#include "stringrefid.hpp"
|
||||
|
||||
namespace ESM
|
||||
|
@ -36,6 +37,7 @@ namespace ESM
|
|||
UnsizedString = 2,
|
||||
FormId = 3,
|
||||
Generated = 4,
|
||||
Index = 5,
|
||||
};
|
||||
|
||||
// RefId is used to represent an Id that identifies an ESM record. These Ids can then be used in
|
||||
|
@ -56,6 +58,10 @@ namespace ESM
|
|||
// global counter.
|
||||
static RefId generated(std::uint64_t value) { return RefId(GeneratedRefId{ value }); }
|
||||
|
||||
// Constructs RefId from record type and 32bit index storing the value in-place. Should be used for records
|
||||
// identified by index (i.e. ESM3 SKIL).
|
||||
static RefId index(RecNameInts recordType, std::uint32_t value) { return RefId(IndexRefId(recordType, value)); }
|
||||
|
||||
constexpr RefId() = default;
|
||||
|
||||
constexpr RefId(EmptyRefId value) noexcept
|
||||
|
@ -78,6 +84,11 @@ namespace ESM
|
|||
{
|
||||
}
|
||||
|
||||
constexpr RefId(IndexRefId value) noexcept
|
||||
: mValue(value)
|
||||
{
|
||||
}
|
||||
|
||||
// Returns a reference to the value of StringRefId if it's the underlying value or throws an exception.
|
||||
const std::string& getRefIdString() const;
|
||||
|
||||
|
@ -120,7 +131,7 @@ namespace ESM
|
|||
friend struct std::hash<ESM::RefId>;
|
||||
|
||||
private:
|
||||
std::variant<EmptyRefId, StringRefId, FormIdRefId, GeneratedRefId> mValue{ EmptyRefId{} };
|
||||
std::variant<EmptyRefId, StringRefId, FormIdRefId, GeneratedRefId, IndexRefId> mValue{ EmptyRefId{} };
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -463,6 +463,14 @@ namespace ESM
|
|||
getExact(&generated, sizeof(std::uint64_t));
|
||||
return RefId::generated(generated);
|
||||
}
|
||||
case RefIdType::Index:
|
||||
{
|
||||
RecNameInts recordType{};
|
||||
getExact(&recordType, sizeof(std::uint32_t));
|
||||
std::uint32_t index{};
|
||||
getExact(&index, sizeof(std::uint32_t));
|
||||
return RefId::index(recordType, index);
|
||||
}
|
||||
}
|
||||
|
||||
fail("Unsupported RefIdType: " + std::to_string(static_cast<unsigned>(refIdType)));
|
||||
|
|
|
@ -53,6 +53,13 @@ namespace ESM
|
|||
mWriter.writeT(RefIdType::Generated);
|
||||
mWriter.writeT(v.getValue());
|
||||
}
|
||||
|
||||
void operator()(IndexRefId v) const
|
||||
{
|
||||
mWriter.writeT(RefIdType::Generated);
|
||||
mWriter.writeT(v.getRecordType());
|
||||
mWriter.writeT(v.getValue());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "loadmgef.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "esmreader.hpp"
|
||||
#include "esmwriter.hpp"
|
||||
|
||||
|
@ -11,156 +9,6 @@ namespace ESM
|
|||
{
|
||||
namespace
|
||||
{
|
||||
static const char* sIds[MagicEffect::Length] = {
|
||||
"WaterBreathing",
|
||||
"SwiftSwim",
|
||||
"WaterWalking",
|
||||
"Shield",
|
||||
"FireShield",
|
||||
"LightningShield",
|
||||
"FrostShield",
|
||||
"Burden",
|
||||
"Feather",
|
||||
"Jump",
|
||||
"Levitate",
|
||||
"SlowFall",
|
||||
"Lock",
|
||||
"Open",
|
||||
"FireDamage",
|
||||
"ShockDamage",
|
||||
"FrostDamage",
|
||||
"DrainAttribute",
|
||||
"DrainHealth",
|
||||
"DrainMagicka",
|
||||
"DrainFatigue",
|
||||
"DrainSkill",
|
||||
"DamageAttribute",
|
||||
"DamageHealth",
|
||||
"DamageMagicka",
|
||||
"DamageFatigue",
|
||||
"DamageSkill",
|
||||
"Poison",
|
||||
"WeaknessToFire",
|
||||
"WeaknessToFrost",
|
||||
"WeaknessToShock",
|
||||
"WeaknessToMagicka",
|
||||
"WeaknessToCommonDisease",
|
||||
"WeaknessToBlightDisease",
|
||||
"WeaknessToCorprusDisease",
|
||||
"WeaknessToPoison",
|
||||
"WeaknessToNormalWeapons",
|
||||
"DisintegrateWeapon",
|
||||
"DisintegrateArmor",
|
||||
"Invisibility",
|
||||
"Chameleon",
|
||||
"Light",
|
||||
"Sanctuary",
|
||||
"NightEye",
|
||||
"Charm",
|
||||
"Paralyze",
|
||||
"Silence",
|
||||
"Blind",
|
||||
"Sound",
|
||||
"CalmHumanoid",
|
||||
"CalmCreature",
|
||||
"FrenzyHumanoid",
|
||||
"FrenzyCreature",
|
||||
"DemoralizeHumanoid",
|
||||
"DemoralizeCreature",
|
||||
"RallyHumanoid",
|
||||
"RallyCreature",
|
||||
"Dispel",
|
||||
"Soultrap",
|
||||
"Telekinesis",
|
||||
"Mark",
|
||||
"Recall",
|
||||
"DivineIntervention",
|
||||
"AlmsiviIntervention",
|
||||
"DetectAnimal",
|
||||
"DetectEnchantment",
|
||||
"DetectKey",
|
||||
"SpellAbsorption",
|
||||
"Reflect",
|
||||
"CureCommonDisease",
|
||||
"CureBlightDisease",
|
||||
"CureCorprusDisease",
|
||||
"CurePoison",
|
||||
"CureParalyzation",
|
||||
"RestoreAttribute",
|
||||
"RestoreHealth",
|
||||
"RestoreMagicka",
|
||||
"RestoreFatigue",
|
||||
"RestoreSkill",
|
||||
"FortifyAttribute",
|
||||
"FortifyHealth",
|
||||
"FortifyMagicka",
|
||||
"FortifyFatigue",
|
||||
"FortifySkill",
|
||||
"FortifyMaximumMagicka",
|
||||
"AbsorbAttribute",
|
||||
"AbsorbHealth",
|
||||
"AbsorbMagicka",
|
||||
"AbsorbFatigue",
|
||||
"AbsorbSkill",
|
||||
"ResistFire",
|
||||
"ResistFrost",
|
||||
"ResistShock",
|
||||
"ResistMagicka",
|
||||
"ResistCommonDisease",
|
||||
"ResistBlightDisease",
|
||||
"ResistCorprusDisease",
|
||||
"ResistPoison",
|
||||
"ResistNormalWeapons",
|
||||
"ResistParalysis",
|
||||
"RemoveCurse",
|
||||
"TurnUndead",
|
||||
"SummonScamp",
|
||||
"SummonClannfear",
|
||||
"SummonDaedroth",
|
||||
"SummonDremora",
|
||||
"SummonAncestralGhost",
|
||||
"SummonSkeletalMinion",
|
||||
"SummonBonewalker",
|
||||
"SummonGreaterBonewalker",
|
||||
"SummonBonelord",
|
||||
"SummonWingedTwilight",
|
||||
"SummonHunger",
|
||||
"SummonGoldenSaint",
|
||||
"SummonFlameAtronach",
|
||||
"SummonFrostAtronach",
|
||||
"SummonStormAtronach",
|
||||
"FortifyAttack",
|
||||
"CommandCreature",
|
||||
"CommandHumanoid",
|
||||
"BoundDagger",
|
||||
"BoundLongsword",
|
||||
"BoundMace",
|
||||
"BoundBattleAxe",
|
||||
"BoundSpear",
|
||||
"BoundLongbow",
|
||||
"ExtraSpell",
|
||||
"BoundCuirass",
|
||||
"BoundHelm",
|
||||
"BoundBoots",
|
||||
"BoundShield",
|
||||
"BoundGloves",
|
||||
"Corprus",
|
||||
"Vampirism",
|
||||
"SummonCenturionSphere",
|
||||
"SunDamage",
|
||||
"StuntedMagicka",
|
||||
|
||||
// Tribunal only
|
||||
"SummonFabricant",
|
||||
|
||||
// Bloodmoon only
|
||||
"SummonWolf",
|
||||
"SummonBear",
|
||||
"SummonBonewolf",
|
||||
"SummonCreature04",
|
||||
"SummonCreature05",
|
||||
};
|
||||
|
||||
const int NumberOfHardcodedFlags = 143;
|
||||
const int HardcodedFlags[NumberOfHardcodedFlags] = { 0x11c8, 0x11c0, 0x11c8, 0x11e0, 0x11e0, 0x11e0, 0x11e0,
|
||||
0x11d0, 0x11c0, 0x11c0, 0x11e0, 0x11c0, 0x11184, 0x11184, 0x1f0, 0x1f0, 0x1f0, 0x11d2, 0x11f0, 0x11d0,
|
||||
|
@ -186,7 +34,7 @@ namespace ESM
|
|||
|
||||
esm.getHNT(mIndex, "INDX");
|
||||
|
||||
mId = ESM::RefId::stringRefId(indexToId(mIndex));
|
||||
mId = indexToRefId(mIndex);
|
||||
|
||||
esm.getHNTSized<36>(mData, "MEDT");
|
||||
if (esm.getFormatVersion() == DefaultFormatVersion)
|
||||
|
@ -592,28 +440,10 @@ namespace ESM
|
|||
mDescription.clear();
|
||||
}
|
||||
|
||||
std::string MagicEffect::indexToId(int index)
|
||||
RefId MagicEffect::indexToRefId(int index)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
stream << "#";
|
||||
|
||||
if (index < 100)
|
||||
{
|
||||
stream << "0";
|
||||
|
||||
if (index < 10)
|
||||
stream << "0";
|
||||
}
|
||||
|
||||
stream << index;
|
||||
|
||||
if (index >= 0 && index < Length)
|
||||
stream << sIds[index];
|
||||
}
|
||||
|
||||
return stream.str();
|
||||
if (index == -1)
|
||||
return RefId();
|
||||
return RefId::index(sRecordId, static_cast<std::uint32_t>(index));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -269,7 +269,7 @@ namespace ESM
|
|||
Length
|
||||
};
|
||||
|
||||
static std::string indexToId(int index);
|
||||
static RefId indexToRefId(int index);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "loadskil.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "esmreader.hpp"
|
||||
#include "esmwriter.hpp"
|
||||
|
||||
|
@ -133,7 +131,7 @@ namespace ESM
|
|||
|
||||
// create an ID from the index and the name (only used in the editor and likely to change in the
|
||||
// future)
|
||||
mId = ESM::RefId::stringRefId(indexToId(mIndex));
|
||||
mId = indexToRefId(mIndex);
|
||||
}
|
||||
|
||||
void Skill::save(ESMWriter& esm, bool /*isDeleted*/) const
|
||||
|
@ -152,23 +150,10 @@ namespace ESM
|
|||
mDescription.clear();
|
||||
}
|
||||
|
||||
std::string Skill::indexToId(int index)
|
||||
RefId Skill::indexToRefId(int index)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
stream << "#";
|
||||
|
||||
if (index < 10)
|
||||
stream << "0";
|
||||
|
||||
stream << index;
|
||||
|
||||
if (index >= 0 && index < Length)
|
||||
stream << sSkillNameIds[index].substr(6);
|
||||
}
|
||||
|
||||
return stream.str();
|
||||
if (index == -1)
|
||||
return RefId();
|
||||
return RefId::index(sRecordId, static_cast<std::uint32_t>(index));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace ESM
|
|||
void blank();
|
||||
///< Set record to default state (does not touch the ID/index).
|
||||
|
||||
static std::string indexToId(int index);
|
||||
static RefId indexToRefId(int index);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue