1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-12-13 23:13:05 +00:00

Merge branch 'esm4_reading_fixes' into 'master'

ESM4 reading fixes

See merge request OpenMW/openmw!3026
This commit is contained in:
Petr Mikheev 2023-05-17 22:36:02 +00:00
commit b1409182bc
14 changed files with 53 additions and 36 deletions

View file

@ -116,13 +116,18 @@ namespace EsmTool
std::cout << "\n Record: " << ESM::NAME(reader.hdr().record.typeId).toStringView(); std::cout << "\n Record: " << ESM::NAME(reader.hdr().record.typeId).toStringView();
if constexpr (ESM4::hasFormId<T>) if constexpr (ESM4::hasFormId<T>)
std::cout << "\n FormId: " << value.mFormId; std::cout << "\n FormId: 0x" << ESM4::formIdToString(value.mFormId);
if constexpr (ESM::hasId<T>) if constexpr (ESM::hasId<T>)
std::cout << "\n Id: " << value.mId; {
if constexpr (std::is_same_v<decltype(value.mId), ESM4::FormId>)
std::cout << "\n FormId: 0x" << ESM4::formIdToString(value.mId);
else
std::cout << "\n Id: " << value.mId;
}
if constexpr (ESM4::hasFlags<T>) if constexpr (ESM4::hasFlags<T>)
std::cout << "\n Record flags: " << recordFlags(value.mFlags); std::cout << "\n Record flags: " << recordFlags(value.mFlags);
if constexpr (ESM4::hasParentFormId<T>) if constexpr (ESM4::hasParentFormId<T>)
std::cout << "\n ParentFormId: " << value.mParentFormId; std::cout << "\n ParentFormId: 0x" << ESM4::formIdToString(value.mParentFormId);
if constexpr (ESM4::hasParent<T>) if constexpr (ESM4::hasParent<T>)
std::cout << "\n Parent: " << value.mParent; std::cout << "\n Parent: " << value.mParent;
if constexpr (ESM4::hasEditorId<T>) if constexpr (ESM4::hasEditorId<T>)

View file

@ -60,7 +60,7 @@ void ESM4::ActorCharacter::load(ESM4::Reader& reader)
reader.get(mScale); reader.get(mScale);
break; break;
case ESM4::SUB_XOWN: case ESM4::SUB_XOWN:
reader.get(mOwner); reader.getFormId(mOwner);
break; break;
case ESM4::SUB_XESP: case ESM4::SUB_XESP:
{ {

View file

@ -65,8 +65,8 @@ void ESM4::ActorCreature::load(ESM4::Reader& reader)
reader.getFormId(mOwner); reader.getFormId(mOwner);
break; break;
case ESM4::SUB_XGLB: case ESM4::SUB_XGLB:
reader.get(mGlobal); reader.getFormId(mGlobal);
break; // FIXME: formId? break;
case ESM4::SUB_XRNK: case ESM4::SUB_XRNK:
reader.get(mFactionRank); reader.get(mFactionRank);
break; break;

View file

@ -177,12 +177,12 @@ void ESM4::Creature::load(ESM4::Reader& reader)
break; break;
} }
case ESM4::SUB_TPLT: case ESM4::SUB_TPLT:
reader.get(mBaseTemplate); reader.getFormId(mBaseTemplate);
break; // FO3 break; // FO3
case ESM4::SUB_PNAM: // FO3/FONV/TES5 case ESM4::SUB_PNAM: // FO3/FONV/TES5
{ {
FormId bodyPart; FormId bodyPart;
reader.get(bodyPart); reader.getFormId(bodyPart);
mBodyParts.push_back(bodyPart); mBodyParts.push_back(bodyPart);
break; break;

View file

@ -15,6 +15,12 @@ namespace ESM4
const char type = editorId[0]; const char type = editorId[0];
switch (type) switch (type)
{ {
case 'b':
{
std::uint32_t value = 0;
reader.get(value);
return value != 0;
}
case 'i': case 'i':
{ {
std::int32_t value = 0; std::int32_t value = 0;

View file

@ -13,7 +13,7 @@ namespace ESM4
struct GameSetting struct GameSetting
{ {
using Data = std::variant<float, std::int32_t, std::string>; using Data = std::variant<bool, float, std::int32_t, std::string>;
FormId mFormId; // from the header FormId mFormId; // from the header
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details std::uint32_t mFlags; // from the header, see enum type RecordFlag for details

View file

@ -53,8 +53,8 @@ void ESM4::IdleAnimation::load(ESM4::Reader& reader)
break; break;
case ESM4::SUB_ANAM: case ESM4::SUB_ANAM:
{ {
reader.get(mParent); reader.getFormId(mParent);
reader.get(mPrevious); reader.getFormId(mPrevious);
break; break;
} }
case ESM4::SUB_CTDA: // formId case ESM4::SUB_CTDA: // formId
@ -64,8 +64,15 @@ void ESM4::IdleAnimation::load(ESM4::Reader& reader)
reader.skipSubRecordData(); reader.skipSubRecordData();
break; break;
} }
case ESM4::SUB_MODL:
reader.getZString(mModel);
break;
case ESM4::SUB_MODB:
reader.get(mBoundRadius);
break;
default: default:
throw std::runtime_error("ESM4::IDLE::load - Unknown subrecord " + ESM::printName(subHdr.typeId)); throw std::runtime_error("ESM4::IDLE::load - Unknown subrecord " + std::to_string(subHdr.typeId) + " "
+ ESM::printName(subHdr.typeId));
} }
} }
} }

View file

@ -45,10 +45,13 @@ namespace ESM4
std::string mEditorId; std::string mEditorId;
std::string mCollision; std::string mCollision;
std::string mEvent; std::string mEvent;
std::string mModel;
FormId mParent; // IDLE or AACT FormId mParent; // IDLE or AACT
FormId mPrevious; FormId mPrevious;
float mBoundRadius;
void load(ESM4::Reader& reader); void load(ESM4::Reader& reader);
// void save(ESM4::Writer& writer) const; // void save(ESM4::Writer& writer) const;

View file

@ -75,8 +75,8 @@ void ESM4::IdleMarker::load(ESM4::Reader& reader)
} }
mIdleAnim.resize(mIdleCount); mIdleAnim.resize(mIdleCount);
for (unsigned int i = 0; i < static_cast<unsigned int>(mIdleCount); ++i) for (FormId& value : mIdleAnim)
reader.get(mIdleAnim.at(i)); reader.getFormId(value);
break; break;
} }
case ESM4::SUB_OBND: // object bounds case ESM4::SUB_OBND: // object bounds

View file

@ -53,7 +53,7 @@ void ESM4::MovableStatic::load(ESM4::Reader& reader)
reader.get(mData); reader.get(mData);
break; break;
case ESM4::SUB_SNAM: case ESM4::SUB_SNAM:
reader.get(mLoopingSound); reader.getFormId(mLoopingSound);
break; break;
case ESM4::SUB_DEST: // destruction data case ESM4::SUB_DEST: // destruction data
case ESM4::SUB_OBND: // object bounds case ESM4::SUB_OBND: // object bounds

View file

@ -80,7 +80,7 @@ void ESM4::Navigation::NavMeshInfo::load(ESM4::Reader& reader)
{ {
std::uint32_t count; std::uint32_t count;
reader.get(formId); reader.getFormId(formId);
reader.get(flags); reader.get(flags);
reader.get(x); reader.get(x);
reader.get(y); reader.get(y);
@ -107,10 +107,8 @@ void ESM4::Navigation::NavMeshInfo::load(ESM4::Reader& reader)
{ {
// std::cout << "NVMI countMerged " << std::dec << count << std::endl; // std::cout << "NVMI countMerged " << std::dec << count << std::endl;
formIdMerged.resize(count); formIdMerged.resize(count);
for (std::vector<FormId>::iterator it = formIdMerged.begin(); it != formIdMerged.end(); ++it) for (FormId& value : formIdMerged)
{ reader.getFormId(value);
reader.get(*it);
}
} }
reader.get(count); // countPrefMerged; reader.get(count); // countPrefMerged;
@ -118,10 +116,8 @@ void ESM4::Navigation::NavMeshInfo::load(ESM4::Reader& reader)
{ {
// std::cout << "NVMI countPrefMerged " << std::dec << count << std::endl; // std::cout << "NVMI countPrefMerged " << std::dec << count << std::endl;
formIdPrefMerged.resize(count); formIdPrefMerged.resize(count);
for (std::vector<FormId>::iterator it = formIdPrefMerged.begin(); it != formIdPrefMerged.end(); ++it) for (FormId& value : formIdPrefMerged)
{ reader.getFormId(value);
reader.get(*it);
}
} }
reader.get(count); // countLinkedDoors; reader.get(count); // countLinkedDoors;
@ -148,7 +144,7 @@ void ESM4::Navigation::NavMeshInfo::load(ESM4::Reader& reader)
reader.get(locationMarker); reader.get(locationMarker);
reader.get(worldSpaceId); reader.getFormId(worldSpaceId);
// FLG_Tamriel = 0x0000003c, // grid info follows, possibly Tamriel? // FLG_Tamriel = 0x0000003c, // grid info follows, possibly Tamriel?
// FLG_Morrowind = 0x01380000, // grid info follows, probably Skywind // FLG_Morrowind = 0x01380000, // grid info follows, probably Skywind
if (worldSpaceId == FormId{ 0x3c, 0 } || worldSpaceId == FormId{ 0x380000, 1 }) if (worldSpaceId == FormId{ 0x3c, 0 } || worldSpaceId == FormId{ 0x380000, 1 })
@ -170,7 +166,7 @@ void ESM4::Navigation::NavMeshInfo::load(ESM4::Reader& reader)
else else
{ {
FormId cellId; FormId cellId;
reader.get(cellId); reader.getFormId(cellId);
cellGrid = cellId; cellGrid = cellId;
#if 0 #if 0
@ -279,14 +275,11 @@ void ESM4::Navigation::load(ESM4::Reader& reader)
reader.get(node); reader.get(node);
reader.get(count); reader.get(count);
} }
if (count) if (count > 0)
{ {
preferredPaths.resize(count); preferredPaths.resize(count);
for (std::vector<FormId>::iterator it = preferredPaths.begin(); it != preferredPaths.end(); for (FormId& value : preferredPaths)
++it) reader.getFormId(value);
{
reader.get(*it);
}
} }
mPreferredPaths.push_back(std::make_pair(node, preferredPaths)); mPreferredPaths.push_back(std::make_pair(node, preferredPaths));
#if 0 #if 0

View file

@ -44,7 +44,7 @@ void ESM4::NavMesh::NVNMstruct::load(ESM4::Reader& reader)
reader.get(unknownNVER); reader.get(unknownNVER);
reader.get(unknownLCTN); reader.get(unknownLCTN);
reader.get(worldSpaceId); reader.getFormId(worldSpaceId);
// FLG_Tamriel = 0x0000003c, // grid info follows, possibly Tamriel? // FLG_Tamriel = 0x0000003c, // grid info follows, possibly Tamriel?
// FLG_Morrowind = 0x01380000, // grid info follows, probably Skywind // FLG_Morrowind = 0x01380000, // grid info follows, probably Skywind
if (worldSpaceId == FormId{ 0x3c, 0 } || worldSpaceId == FormId{ 380000, 1 }) if (worldSpaceId == FormId{ 0x3c, 0 } || worldSpaceId == FormId{ 380000, 1 })
@ -82,7 +82,7 @@ void ESM4::NavMesh::NVNMstruct::load(ESM4::Reader& reader)
else else
{ {
FormId cellId; FormId cellId;
reader.get(cellId); reader.getFormId(cellId);
cellGrid = cellId; cellGrid = cellId;
#if 0 #if 0

View file

@ -161,7 +161,7 @@ void ESM4::Npc::load(ESM4::Reader& reader)
case ESM4::SUB_WNAM: case ESM4::SUB_WNAM:
{ {
if (reader.esmVersion() == ESM::VER_094 || reader.esmVersion() == ESM::VER_170) if (reader.esmVersion() == ESM::VER_094 || reader.esmVersion() == ESM::VER_170)
reader.get(mWornArmor); reader.getFormId(mWornArmor);
else else
reader.get(mFootWeight); reader.get(mFootWeight);
break; break;
@ -192,7 +192,7 @@ void ESM4::Npc::load(ESM4::Reader& reader)
break; break;
} }
case ESM4::SUB_TPLT: case ESM4::SUB_TPLT:
reader.get(mBaseTemplate); reader.getFormId(mBaseTemplate);
break; break;
case ESM4::SUB_FGGS: case ESM4::SUB_FGGS:
{ {

View file

@ -226,6 +226,9 @@ namespace ESM4
mStream->read((char*)&t, sizeof(T)); mStream->read((char*)&t, sizeof(T));
} }
// Use getFormId instead
void get(FormId& value) = delete;
template <typename T> template <typename T>
bool getExact(T& t) bool getExact(T& t)
{ {