From 5bb088218ee26c11aba682631efb6b14a35a47f1 Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 28 Jan 2023 18:28:43 +0100 Subject: [PATCH 1/3] Restore original formId To make sure esmtool prints original value and not a result of conversion. --- apps/esmtool/tes4.cpp | 10 +++++----- components/esm4/loadcell.cpp | 8 ++++---- components/esm4/loadcell.hpp | 7 ++++--- components/esm4/loadrefr.cpp | 9 +++++---- components/esm4/loadrefr.hpp | 9 ++++++--- components/esm4/loadstat.cpp | 6 +++--- components/esm4/loadstat.hpp | 4 +++- 7 files changed, 30 insertions(+), 23 deletions(-) diff --git a/apps/esmtool/tes4.cpp b/apps/esmtool/tes4.cpp index 1b85c37c11..533600788e 100644 --- a/apps/esmtool/tes4.cpp +++ b/apps/esmtool/tes4.cpp @@ -71,17 +71,17 @@ namespace EsmTool constexpr bool hasFormId = HasFormId::value; template > - struct HasRefId : std::false_type + struct HasId : std::false_type { }; template - struct HasRefId> : std::true_type + struct HasId> : std::true_type { }; template - constexpr bool hasRefId = HasRefId::value; + constexpr bool hasId = HasId::value; template > struct HasFlags : std::false_type @@ -183,8 +183,8 @@ namespace EsmTool std::cout << "\n Record: " << ESM::NAME(reader.hdr().record.typeId).toStringView(); if constexpr (hasFormId) std::cout << "\n FormId: " << value.mFormId; - if constexpr (hasRefId) - std::cout << "\n FormId: " << value.mId; + if constexpr (hasId) + std::cout << "\n Id: " << value.mId; if constexpr (hasFlags) std::cout << "\n Record flags: " << recordFlags(value.mFlags); if constexpr (hasEditorId) diff --git a/components/esm4/loadcell.cpp b/components/esm4/loadcell.cpp index 0b829d657f..1b61b746cf 100644 --- a/components/esm4/loadcell.cpp +++ b/components/esm4/loadcell.cpp @@ -49,9 +49,9 @@ // longer/shorter/same as loading the subrecords. void ESM4::Cell::load(ESM4::Reader& reader) { - auto formId = reader.hdr().record.id; - reader.adjustFormId(formId); - mId = ESM::RefId::formIdRefId(formId); + mFormId = reader.hdr().record.id; + reader.adjustFormId(mFormId); + mId = ESM::RefId::formIdRefId(mFormId); mFlags = reader.hdr().record.flags; mParent = reader.currWorld(); @@ -73,7 +73,7 @@ void ESM4::Cell::load(ESM4::Reader& reader) // WARN: we need to call setCurrCell (and maybe setCurrCellGrid?) again before loading // cell child groups if we are loading them after restoring the context // (may be easier to update the context before saving?) - reader.setCurrCell(formId); // save for LAND (and other children) to access later + reader.setCurrCell(mFormId); // save for LAND (and other children) to access later std::uint32_t esmVer = reader.esmVersion(); bool isFONV = esmVer == ESM::VER_132 || esmVer == ESM::VER_133 || esmVer == ESM::VER_134; diff --git a/components/esm4/loadcell.hpp b/components/esm4/loadcell.hpp index 49e5d048b0..96e6c745c9 100644 --- a/components/esm4/loadcell.hpp +++ b/components/esm4/loadcell.hpp @@ -62,11 +62,12 @@ namespace ESM4 // The cells need to be organised under world spaces. struct Cell { - FormId mParent; // world formId (for grouping cells), from the loading sequence - - ESM::RefId mId; // from the header + FormId mFormId; // from the header + ESM::RefId mId; std::uint32_t mFlags; // from the header, see enum type RecordFlag for details + FormId mParent; // world formId (for grouping cells), from the loading sequence + std::string mEditorId; std::string mFullName; std::uint16_t mCellFlags; // TES5 can also be 8 bits diff --git a/components/esm4/loadrefr.cpp b/components/esm4/loadrefr.cpp index b95f24e73a..de6c19c626 100644 --- a/components/esm4/loadrefr.cpp +++ b/components/esm4/loadrefr.cpp @@ -34,11 +34,12 @@ void ESM4::Reference::load(ESM4::Reader& reader) { - auto formId = reader.hdr().record.id; - reader.adjustFormId(formId); - mId = ESM::RefId::formIdRefId(formId); + mFormId = reader.hdr().record.id; + reader.adjustFormId(mFormId); + mId = ESM::RefId::formIdRefId(mFormId); mFlags = reader.hdr().record.flags; - mParent = ESM::RefId::formIdRefId(reader.currCell()); // NOTE: only for persistent refs? + mParentFormId = reader.currCell(); // NOTE: only for persistent refs? + mParent = ESM::RefId::formIdRefId(mParentFormId); // TODO: Let the engine apply this? Saved games? // mInitiallyDisabled = ((mFlags & ESM4::Rec_Disabled) != 0) ? true : false; diff --git a/components/esm4/loadrefr.hpp b/components/esm4/loadrefr.hpp index fb54c35863..4751336d02 100644 --- a/components/esm4/loadrefr.hpp +++ b/components/esm4/loadrefr.hpp @@ -74,10 +74,13 @@ namespace ESM4 struct Reference { - ESM::RefId mParent; // cell FormId (currently persistent refs only), from the loading sequence - // NOTE: for exterior cells it will be the dummy cell FormId + FormId mFormId; // from the header + ESM::RefId mId; + + FormId mParentFormId; // cell FormId (currently persistent refs only), from the loading sequence + // NOTE: for exterior cells it will be the dummy cell FormId + ESM::RefId mParent; - ESM::RefId mId; // from the header std::uint32_t mFlags; // from the header, see enum type RecordFlag for details std::string mEditorId; diff --git a/components/esm4/loadstat.cpp b/components/esm4/loadstat.cpp index edfbf0e4e6..c0ab630a13 100644 --- a/components/esm4/loadstat.cpp +++ b/components/esm4/loadstat.cpp @@ -34,9 +34,9 @@ void ESM4::Static::load(ESM4::Reader& reader) { - FormId formId = reader.hdr().record.id; - reader.adjustFormId(formId); - mId = ESM::RefId::formIdRefId(formId); + mFormId = reader.hdr().record.id; + reader.adjustFormId(mFormId); + mId = ESM::RefId::formIdRefId(mFormId); mFlags = reader.hdr().record.flags; while (reader.getSubRecordHeader()) diff --git a/components/esm4/loadstat.hpp b/components/esm4/loadstat.hpp index 3b8a78d8fb..00f4d08c49 100644 --- a/components/esm4/loadstat.hpp +++ b/components/esm4/loadstat.hpp @@ -43,7 +43,9 @@ namespace ESM4 struct Static { - ESM::RefId mId; // from the header + FormId mFormId; // from the header + ESM::RefId mId; + std::uint32_t mFlags; // from the header, see enum type RecordFlag for details std::string mEditorId; From e7acced5e903e3d7049633e19ca4bb03fcea6c50 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 29 Jan 2023 03:00:48 +0100 Subject: [PATCH 2/3] Move metafunctions to check ESM4 field existence to a separate header --- apps/esmtool/tes4.cpp | 106 +++------------------------------ components/esm4/typetraits.hpp | 100 +++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 98 deletions(-) create mode 100644 components/esm4/typetraits.hpp diff --git a/apps/esmtool/tes4.cpp b/apps/esmtool/tes4.cpp index 533600788e..3c7d03e67b 100644 --- a/apps/esmtool/tes4.cpp +++ b/apps/esmtool/tes4.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include namespace EsmTool @@ -57,97 +58,6 @@ namespace EsmTool return "Unknown (" + std::to_string(type) + ")"; } - template > - struct HasFormId : std::false_type - { - }; - - template - struct HasFormId> : std::true_type - { - }; - - template - constexpr bool hasFormId = HasFormId::value; - - template > - struct HasId : std::false_type - { - }; - - template - struct HasId> : std::true_type - { - }; - - template - constexpr bool hasId = HasId::value; - - template > - struct HasFlags : std::false_type - { - }; - - template - struct HasFlags> : std::true_type - { - }; - - template - constexpr bool hasFlags = HasFlags::value; - - template > - struct HasEditorId : std::false_type - { - }; - - template - struct HasEditorId> : std::true_type - { - }; - - template - constexpr bool hasEditorId = HasEditorId::value; - - template > - struct HasModel : std::false_type - { - }; - - template - struct HasModel> : std::true_type - { - }; - - template - constexpr bool hasModel = HasModel::value; - - template > - struct HasNif : std::false_type - { - }; - - template - struct HasNif> : std::true_type - { - }; - - template - constexpr bool hasNif = HasNif::value; - - template > - struct HasKf : std::false_type - { - }; - - template - struct HasKf> : std::true_type - { - }; - - template - constexpr bool hasKf = HasKf::value; - template struct WriteArray { @@ -181,19 +91,19 @@ namespace EsmTool return; std::cout << "\n Record: " << ESM::NAME(reader.hdr().record.typeId).toStringView(); - if constexpr (hasFormId) + if constexpr (ESM4::hasFormId) std::cout << "\n FormId: " << value.mFormId; - if constexpr (hasId) + if constexpr (ESM4::hasId) std::cout << "\n Id: " << value.mId; - if constexpr (hasFlags) + if constexpr (ESM4::hasFlags) std::cout << "\n Record flags: " << recordFlags(value.mFlags); - if constexpr (hasEditorId) + if constexpr (ESM4::hasEditorId) std::cout << "\n EditorId: " << value.mEditorId; - if constexpr (hasModel) + if constexpr (ESM4::hasModel) std::cout << "\n Model: " << value.mModel; - if constexpr (hasNif) + if constexpr (ESM4::hasNif) std::cout << "\n Nif:" << WriteArray("\n - ", value.mNif); - if constexpr (hasKf) + if constexpr (ESM4::hasKf) std::cout << "\n Kf:" << WriteArray("\n - ", value.mKf); std::cout << '\n'; } diff --git a/components/esm4/typetraits.hpp b/components/esm4/typetraits.hpp new file mode 100644 index 0000000000..65e56e891d --- /dev/null +++ b/components/esm4/typetraits.hpp @@ -0,0 +1,100 @@ +#ifndef OPENMW_COMPONENTS_ESM4_TYPETRAITS +#define OPENMW_COMPONENTS_ESM4_TYPETRAITS + +#include + +namespace ESM4 +{ + template > + struct HasFormId : std::false_type + { + }; + + template + struct HasFormId> : std::true_type + { + }; + + template + inline constexpr bool hasFormId = HasFormId::value; + + template > + struct HasId : std::false_type + { + }; + + template + struct HasId> : std::true_type + { + }; + + template + inline constexpr bool hasId = HasId::value; + + template > + struct HasFlags : std::false_type + { + }; + + template + struct HasFlags> : std::true_type + { + }; + + template + inline constexpr bool hasFlags = HasFlags::value; + + template > + struct HasEditorId : std::false_type + { + }; + + template + struct HasEditorId> : std::true_type + { + }; + + template + inline constexpr bool hasEditorId = HasEditorId::value; + + template > + struct HasModel : std::false_type + { + }; + + template + struct HasModel> : std::true_type + { + }; + + template + inline constexpr bool hasModel = HasModel::value; + + template > + struct HasNif : std::false_type + { + }; + + template + struct HasNif> : std::true_type + { + }; + + template + inline constexpr bool hasNif = HasNif::value; + + template > + struct HasKf : std::false_type + { + }; + + template + struct HasKf> : std::true_type + { + }; + + template + inline constexpr bool hasKf = HasKf::value; +} + +#endif // OPENMW_COMPONENTS_ESM4_TYPETRAITS From d541436b1585d9409bf7afbc228b2e82813f16fb Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 28 Jan 2023 18:37:15 +0100 Subject: [PATCH 3/3] Support parent, type and value fields in esmtool for ESM4 --- apps/esmtool/labels.cpp | 2 +- apps/esmtool/tes4.cpp | 8 +++++ components/CMakeLists.txt | 1 + components/esm4/readerutils.hpp | 2 +- components/esm4/typetraits.hpp | 52 +++++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 2 deletions(-) diff --git a/apps/esmtool/labels.cpp b/apps/esmtool/labels.cpp index d88a608466..5f2026b724 100644 --- a/apps/esmtool/labels.cpp +++ b/apps/esmtool/labels.cpp @@ -986,4 +986,4 @@ std::string recordFlags(uint32_t flags) properties += "Invalid "; properties += Misc::StringUtils::format("(0x%08X)", flags); return properties; -} \ No newline at end of file +} diff --git a/apps/esmtool/tes4.cpp b/apps/esmtool/tes4.cpp index 3c7d03e67b..6b13aa705c 100644 --- a/apps/esmtool/tes4.cpp +++ b/apps/esmtool/tes4.cpp @@ -97,6 +97,10 @@ namespace EsmTool std::cout << "\n Id: " << value.mId; if constexpr (ESM4::hasFlags) std::cout << "\n Record flags: " << recordFlags(value.mFlags); + if constexpr (ESM4::hasParentFormId) + std::cout << "\n ParentFormId: " << value.mParentFormId; + if constexpr (ESM4::hasParent) + std::cout << "\n Parent: " << value.mParent; if constexpr (ESM4::hasEditorId) std::cout << "\n EditorId: " << value.mEditorId; if constexpr (ESM4::hasModel) @@ -105,6 +109,10 @@ namespace EsmTool std::cout << "\n Nif:" << WriteArray("\n - ", value.mNif); if constexpr (ESM4::hasKf) std::cout << "\n Kf:" << WriteArray("\n - ", value.mKf); + if constexpr (ESM4::hasType) + std::cout << "\n Type: " << value.mType; + if constexpr (ESM4::hasValue) + std::cout << "\n Value: " << value.mValue; std::cout << '\n'; } diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 405c36b18e..89188215e8 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -194,6 +194,7 @@ add_component_dir (esm4 reference script readerutils + typetraits ) add_component_dir (misc diff --git a/components/esm4/readerutils.hpp b/components/esm4/readerutils.hpp index dd202a5f71..541568d3d2 100644 --- a/components/esm4/readerutils.hpp +++ b/components/esm4/readerutils.hpp @@ -81,4 +81,4 @@ namespace ESM4 }; } -#endif // !OPENMW_COMPONENTS_ESM4_READERUTILS +#endif // OPENMW_COMPONENTS_ESM4_READERUTILS diff --git a/components/esm4/typetraits.hpp b/components/esm4/typetraits.hpp index 65e56e891d..95e6f607e6 100644 --- a/components/esm4/typetraits.hpp +++ b/components/esm4/typetraits.hpp @@ -31,6 +31,32 @@ namespace ESM4 template inline constexpr bool hasId = HasId::value; + template > + struct HasParentFormId : std::false_type + { + }; + + template + struct HasParentFormId> : std::true_type + { + }; + + template + inline constexpr bool hasParentFormId = HasParentFormId::value; + + template > + struct HasParent : std::false_type + { + }; + + template + struct HasParent> : std::true_type + { + }; + + template + inline constexpr bool hasParent = HasParent::value; + template > struct HasFlags : std::false_type { @@ -95,6 +121,32 @@ namespace ESM4 template inline constexpr bool hasKf = HasKf::value; + + template > + struct HasType : std::false_type + { + }; + + template + struct HasType> : std::true_type + { + }; + + template + inline constexpr bool hasType = HasType::value; + + template > + struct HasValue : std::false_type + { + }; + + template + struct HasValue> : std::true_type + { + }; + + template + inline constexpr bool hasValue = HasValue::value; } #endif // OPENMW_COMPONENTS_ESM4_TYPETRAITS