mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-06 03:47:13 +00:00
fix: keep the zone boundary lines and read the luz scene count as the client does
Each boundary line's destination is read as a map ID and an instance ID into a LWOZONEID. The scene count is a byte before version 37 and a u32 from it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -132,16 +132,20 @@ namespace TerrainTestWriter {
|
||||
NiPoint3 position;
|
||||
};
|
||||
|
||||
// A Latest (41) version .luz with no paths
|
||||
// A .luz (version 36 to 41) with no paths
|
||||
inline std::string WriteLuz(uint32_t worldID, const std::vector<TestScene>& scenes, uint8_t boundaryCount, const std::string& rawName,
|
||||
const std::vector<std::pair<TestTransitionPoint, TestTransitionPoint>>& transitions) {
|
||||
const std::vector<std::pair<TestTransitionPoint, TestTransitionPoint>>& transitions, uint32_t version = 41) {
|
||||
std::ostringstream stream;
|
||||
Write<uint32_t>(stream, 41); // version
|
||||
Write(stream, version);
|
||||
Write<uint32_t>(stream, 5); // revision
|
||||
Write(stream, worldID);
|
||||
Write(stream, NiPoint3(1.0f, 2.0f, 3.0f)); // spawn position
|
||||
for (const float value : { 1.0f, 0.0f, 0.0f, 0.0f }) Write(stream, value); // spawn rotation
|
||||
Write<uint32_t>(stream, static_cast<uint32_t>(scenes.size()));
|
||||
if (version >= 38) {
|
||||
Write(stream, NiPoint3(1.0f, 2.0f, 3.0f)); // spawn position
|
||||
for (const float value : { 1.0f, 0.0f, 0.0f, 0.0f }) Write(stream, value); // spawn rotation
|
||||
}
|
||||
// the scene count is a byte before version 37
|
||||
if (version >= 37) Write<uint32_t>(stream, static_cast<uint32_t>(scenes.size()));
|
||||
else Write<uint8_t>(stream, static_cast<uint8_t>(scenes.size()));
|
||||
for (const auto& scene : scenes) {
|
||||
WriteString8(stream, scene.filename);
|
||||
Write(stream, scene.id);
|
||||
@@ -157,7 +161,8 @@ namespace TerrainTestWriter {
|
||||
for (uint8_t i = 0; i < boundaryCount; ++i) {
|
||||
Write(stream, NiPoint3(0.0f, 0.0f, 1.0f));
|
||||
Write(stream, NiPoint3(10.0f, 0.0f, static_cast<float>(i)));
|
||||
Write<uint32_t>(stream, 1100);
|
||||
Write<uint16_t>(stream, 1100); // map
|
||||
Write<uint16_t>(stream, i + 1); // instance
|
||||
Write<uint32_t>(stream, 2);
|
||||
Write(stream, NiPoint3(5.0f, 6.0f, 7.0f));
|
||||
}
|
||||
@@ -168,7 +173,15 @@ namespace TerrainTestWriter {
|
||||
|
||||
Write<uint32_t>(stream, static_cast<uint32_t>(transitions.size()));
|
||||
for (const auto& [from, to] : transitions) {
|
||||
for (const auto& point : { from, to }) {
|
||||
// before version 40 a transition has a name and a width
|
||||
if (version < 40) {
|
||||
WriteString8(stream, "transition");
|
||||
Write(stream, 2.5f);
|
||||
}
|
||||
// five points from version 34 to 38 (the last three repeat the second here), two otherwise
|
||||
const size_t pointCount = version >= 34 && version < 39 ? 5 : 2;
|
||||
for (size_t i = 0; i < pointCount; ++i) {
|
||||
const auto& point = i == 0 ? from : to;
|
||||
Write(stream, point.sceneID);
|
||||
Write(stream, point.layerID);
|
||||
Write(stream, point.position);
|
||||
|
||||
@@ -54,7 +54,7 @@ protected:
|
||||
}
|
||||
|
||||
// Scenes 0 (global), 1, 2 and 3 (general) and 5 (audio, layer 1); transitions 1 <-> 2 and 2 <-> 3
|
||||
void WriteZone(const std::string& rawName = "test.raw", uint8_t boundaryCount = 2) const {
|
||||
void WriteZone(const std::string& rawName = "test.raw", uint8_t boundaryCount = 2, uint32_t version = 41) const {
|
||||
const std::vector<TestScene> scenes = {
|
||||
{ "global.lvl", 0, 0, "Global", 10, 20, 30 },
|
||||
{ "one.lvl", 1, 0, "Scene One", 255, 0, 0 },
|
||||
@@ -65,7 +65,7 @@ protected:
|
||||
WriteFile("test.luz", WriteLuz(TEST_MAP, scenes, boundaryCount, rawName, {
|
||||
{ { 1, 0, NiPoint3(1.0f, 0.0f, 0.0f) }, { 2, 0, NiPoint3(2.0f, 0.0f, 0.0f) } },
|
||||
{ { 2, 0, NiPoint3(3.0f, 0.0f, 0.0f) }, { 3, 0, NiPoint3(4.0f, 0.0f, 0.0f) } },
|
||||
}));
|
||||
}, version));
|
||||
}
|
||||
|
||||
// One 3x3 point chunk from (0, 0) to (4, 4) whose 2x2 scene map holds scenes 1 2 / 3 1
|
||||
@@ -99,9 +99,20 @@ TEST_F(ZoneSceneTest, ReadsScenesBoundariesAndTransitions) {
|
||||
|
||||
EXPECT_EQ(zone->GetWorldID(), TEST_MAP);
|
||||
EXPECT_EQ(zone->GetZoneRawPath(), "test.raw");
|
||||
EXPECT_EQ(zone->GetZoneName(), "Test Zone"); // read after the skipped boundary lines
|
||||
EXPECT_EQ(zone->GetZoneName(), "Test Zone"); // read after the boundary lines
|
||||
EXPECT_EQ(zone->GetZonePath(), "maps/testzone/");
|
||||
|
||||
const auto& boundaries = zone->GetBoundaries();
|
||||
ASSERT_EQ(boundaries.size(), 2);
|
||||
EXPECT_FLOAT_EQ(boundaries[1].normal.z, 1.0f);
|
||||
EXPECT_FLOAT_EQ(boundaries[1].point.x, 10.0f);
|
||||
EXPECT_FLOAT_EQ(boundaries[1].point.z, 1.0f);
|
||||
EXPECT_EQ(boundaries[1].destinationZone.GetMapID(), 1100);
|
||||
EXPECT_EQ(boundaries[1].destinationZone.GetInstanceID(), 2);
|
||||
EXPECT_EQ(boundaries[1].destinationZone.GetCloneID(), 0);
|
||||
EXPECT_EQ(boundaries[1].destinationSceneID, 2);
|
||||
EXPECT_FLOAT_EQ(boundaries[1].spawnLocation.y, 6.0f);
|
||||
|
||||
ASSERT_EQ(zone->GetScenes().size(), 5);
|
||||
const SceneRef* one = zone->GetScene(LWOSCENEID(1, 0));
|
||||
ASSERT_NE(one, nullptr);
|
||||
@@ -132,9 +143,32 @@ TEST_F(ZoneSceneTest, ZoneWithoutBoundaryLines) {
|
||||
WriteFile("test.raw", MakeRaw());
|
||||
const Zone* zone = LoadZone();
|
||||
EXPECT_EQ(zone->GetZoneName(), "Test Zone");
|
||||
EXPECT_TRUE(zone->GetBoundaries().empty());
|
||||
EXPECT_EQ(zone->GetSceneTransitions().size(), 2);
|
||||
}
|
||||
|
||||
// Version 37 has a u32 scene count (a byte before it) and no spawn point; 36 and 37 have named five point transitions
|
||||
TEST_F(ZoneSceneTest, ReadsOlderZoneVersions) {
|
||||
for (const uint32_t version : { 36u, 37u, 38u, 39u, 40u }) {
|
||||
WriteZone("test.raw", 2, version);
|
||||
WriteFile("test.raw", MakeRaw());
|
||||
const Zone* zone = LoadZone();
|
||||
EXPECT_EQ(zone->GetScenes().size(), 5) << version;
|
||||
EXPECT_EQ(zone->GetBoundaries().size(), 2) << version;
|
||||
EXPECT_EQ(zone->GetZoneRawPath(), "test.raw") << version;
|
||||
EXPECT_EQ(zone->GetZoneName(), "Test Zone") << version;
|
||||
ASSERT_EQ(zone->GetSceneTransitions().size(), 2) << version;
|
||||
const auto& transition = zone->GetSceneTransitions()[1];
|
||||
EXPECT_EQ(transition.points.size(), version < 39 ? 5 : 2) << version;
|
||||
EXPECT_EQ(transition.points[1].sceneID, LWOSCENEID(3, 0)) << version;
|
||||
if (version < 40) {
|
||||
EXPECT_EQ(transition.name, "transition") << version;
|
||||
EXPECT_FLOAT_EQ(transition.width, 2.5f) << version;
|
||||
}
|
||||
EXPECT_FALSE(zone->GetZoneRaw().chunks.empty()) << version;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ZoneSceneTest, SceneAtPosition) {
|
||||
WriteZone();
|
||||
WriteFile("test.raw", MakeRaw());
|
||||
|
||||
Reference in New Issue
Block a user