diff --git a/apps/openmw_test_suite/esm/testrefid.cpp b/apps/openmw_test_suite/esm/testrefid.cpp index 4fb62bcb62..6c7afb05cc 100644 --- a/apps/openmw_test_suite/esm/testrefid.cpp +++ b/apps/openmw_test_suite/esm/testrefid.cpp @@ -342,6 +342,12 @@ namespace ESM static RefId call() { return RefId::index(REC_BOOK, 7); } }; + template <> + struct GenerateRefId + { + static RefId call() { return RefId::esm3ExteriorCell(-12, 7); } + }; + template struct ESMRefIdTypesTest : Test { diff --git a/apps/openmw_test_suite/esm3/testsaveload.cpp b/apps/openmw_test_suite/esm3/testsaveload.cpp index 049fcb6f1d..8742495b3b 100644 --- a/apps/openmw_test_suite/esm3/testsaveload.cpp +++ b/apps/openmw_test_suite/esm3/testsaveload.cpp @@ -248,16 +248,10 @@ namespace ESM record.mObject.mRef.mRefID = generateRandomRefId(); std::generate_n(std::inserter(record.mPreviousItems, record.mPreviousItems.end()), 2, [&] { return std::make_pair(generateRandomRefId(), generateRandomRefId()); }); - record.mCellId.mWorldspace = "worldspace1"; - record.mCellId.mIndex.mX = 42; - record.mCellId.mIndex.mY = 13; - record.mCellId.mPaged = true; + record.mCellId = ESM::RefId::esm3ExteriorCell(0, 0); generateArray(record.mLastKnownExteriorPosition); record.mHasMark = true; - record.mMarkedCell.mWorldspace = "worldspace2"; - record.mMarkedCell.mIndex.mX = 0; - record.mMarkedCell.mIndex.mY = 0; - record.mMarkedCell.mPaged = false; + record.mMarkedCell = ESM::RefId::esm3ExteriorCell(0, 0); generateArray(record.mMarkedPosition.pos); generateArray(record.mMarkedPosition.rot); record.mCurrentCrimeId = 42; @@ -267,16 +261,11 @@ namespace ESM EXPECT_EQ(record.mBirthsign, result.mBirthsign); EXPECT_EQ(record.mPreviousItems, result.mPreviousItems); EXPECT_EQ(record.mPreviousItems, result.mPreviousItems); - EXPECT_EQ(record.mCellId.mWorldspace, result.mCellId.mWorldspace); - EXPECT_EQ(record.mCellId.mIndex.mX, result.mCellId.mIndex.mX); - EXPECT_EQ(record.mCellId.mIndex.mY, result.mCellId.mIndex.mY); - EXPECT_EQ(record.mCellId.mPaged, result.mCellId.mPaged); + EXPECT_EQ(record.mCellId, result.mCellId); + EXPECT_THAT(record.mLastKnownExteriorPosition, ElementsAreArray(result.mLastKnownExteriorPosition)); EXPECT_EQ(record.mHasMark, result.mHasMark); - EXPECT_EQ(record.mMarkedCell.mWorldspace, result.mMarkedCell.mWorldspace); - EXPECT_EQ(record.mMarkedCell.mIndex.mX, result.mMarkedCell.mIndex.mX); - EXPECT_EQ(record.mMarkedCell.mIndex.mY, result.mMarkedCell.mIndex.mY); - EXPECT_EQ(record.mMarkedCell.mPaged, result.mMarkedCell.mPaged); + EXPECT_EQ(record.mMarkedCell, result.mMarkedCell); EXPECT_THAT(record.mMarkedPosition.pos, ElementsAreArray(result.mMarkedPosition.pos)); EXPECT_THAT(record.mMarkedPosition.rot, ElementsAreArray(result.mMarkedPosition.rot)); EXPECT_EQ(record.mCurrentCrimeId, result.mCurrentCrimeId); diff --git a/components/esm/esm3exteriorcellrefid.cpp b/components/esm/esm3exteriorcellrefid.cpp index c4c210032a..72b540cfdb 100644 --- a/components/esm/esm3exteriorcellrefid.cpp +++ b/components/esm/esm3exteriorcellrefid.cpp @@ -1,4 +1,5 @@ #include "esm3exteriorcellrefid.hpp" +#include "serializerefid.hpp" #include #include @@ -7,16 +8,25 @@ namespace ESM { std::string ESM3ExteriorCellRefId::toString() const { - std::ostringstream stream; - stream << "# " << mY << ", " << mY; - return stream.str(); + std::string result; + std::size_t integralSizeX = getIntegralSize(mX); + result.resize(integralSizeX + getIntegralSize(mY) + 3, '\0'); + serializeIntegral(mX, 0, result); + result[integralSizeX] = ':'; + serializeIntegral(mY, integralSizeX + 1, result); + return result; } std::string ESM3ExteriorCellRefId::toDebugString() const { - std::ostringstream stream; - stream << *this; - return stream.str(); + std::string result; + std::size_t integralSizeX = getIntegralSize(mX); + + serializeRefIdPrefix(integralSizeX + getIntegralSize(mY) + 1, esm3ExteriorCellRefIdPrefix, result); + serializeIntegral(mX, esm3ExteriorCellRefIdPrefix.size(), result); + result[esm3ExteriorCellRefIdPrefix.size() + integralSizeX] = ':'; + serializeIntegral(mY, esm3ExteriorCellRefIdPrefix.size() + integralSizeX + 1, result); + return result; } std::ostream& operator<<(std::ostream& stream, ESM3ExteriorCellRefId value) diff --git a/components/esm/refid.cpp b/components/esm/refid.cpp index d04ad4a845..880b6da7e2 100644 --- a/components/esm/refid.cpp +++ b/components/esm/refid.cpp @@ -237,6 +237,13 @@ namespace ESM return ESM::RefId::index(recordType, deserializeIntegral(indexRefIdPrefix.size() + sizeof(recordType) + 1, value)); } + if (value.starts_with(esm3ExteriorCellRefIdPrefix)) + { + std::int32_t x = deserializeIntegral(esm3ExteriorCellRefIdPrefix.size(), value); + std::int32_t y + = deserializeIntegral(esm3ExteriorCellRefIdPrefix.size() + getIntegralSize(x) + 1, value); + return ESM::ESM3ExteriorCellRefId(x, y); + } return ESM::RefId::stringRefId(value); } diff --git a/components/esm/refid.hpp b/components/esm/refid.hpp index e4b97ceb7b..3fafdb0b74 100644 --- a/components/esm/refid.hpp +++ b/components/esm/refid.hpp @@ -50,7 +50,8 @@ namespace ESM public: const static RefId sEmpty; - using Value = std::variant; + using Value + = std::variant; // Constructs RefId from a serialized string containing byte by byte copy of RefId::mValue. static ESM::RefId deserialize(std::string_view value); diff --git a/components/esm/serializerefid.hpp b/components/esm/serializerefid.hpp index 9f43511622..d8c5fa982a 100644 --- a/components/esm/serializerefid.hpp +++ b/components/esm/serializerefid.hpp @@ -12,6 +12,7 @@ namespace ESM constexpr std::string_view formIdRefIdPrefix = "FormId:"; constexpr std::string_view generatedRefIdPrefix = "Generated:"; constexpr std::string_view indexRefIdPrefix = "Index:"; + constexpr std::string_view esm3ExteriorCellRefIdPrefix = "Esm3ExteriorCell:"; template std::size_t getIntegralSize(T value)