diff --git a/dCommon/ZoneFile.cpp b/dCommon/ZoneFile.cpp index 43d02bda0..c19147f3d 100644 --- a/dCommon/ZoneFile.cpp +++ b/dCommon/ZoneFile.cpp @@ -227,7 +227,7 @@ void ZoneFile::ReadPath(std::istream& file) { BinaryIO::BinaryRead(file, path.spawner.maxToSpawn); BinaryIO::BinaryRead(file, path.spawner.amountMaintained); BinaryIO::BinaryRead(file, path.spawner.spawnerObjID); - BinaryIO::BinaryRead(file, path.spawner.spawnerNetActive); + if (path.pathVersion >= 9) BinaryIO::BinaryRead(file, path.spawner.spawnerNetActive); } // Read waypoints diff --git a/dCommon/ZoneFile.h b/dCommon/ZoneFile.h index 621e6fade..1f3e09a76 100644 --- a/dCommon/ZoneFile.h +++ b/dCommon/ZoneFile.h @@ -178,7 +178,7 @@ struct SpawnerPath { int32_t maxToSpawn{}; uint32_t amountMaintained{}; LWOOBJID spawnerObjID; - uint8_t spawnerNetActive{}; + uint8_t spawnerNetActive = 1; // not in paths before version 9; the client then activates it on load }; diff --git a/tests/dCommonTests/ZoneFileTests.cpp b/tests/dCommonTests/ZoneFileTests.cpp index 6b38f3932..b63c8f6d6 100644 --- a/tests/dCommonTests/ZoneFileTests.cpp +++ b/tests/dCommonTests/ZoneFileTests.cpp @@ -204,6 +204,33 @@ TEST(ZoneFileTests, ReadsLegacyPaths) { EXPECT_EQ(platform.pathWaypoints[0].movingPlatform.wait, 1.5f); } +// Spawner paths before version 9 have no activate-on-load byte; the client then activates them on load +TEST(ZoneFileTests, SpawnerNetActiveFromVersion9) { + ZoneBytes w; + w.Put(41).Put(3).Put(1150); + w.Point(0, 0, 0).Put(1.0f).Put(0.0f).Put(0.0f).Put(0.0f); + w.Put(1); + w.Text("scene.lvl").Put(0).Put(0).Text("Global").Put(0).Put(0).Put(0); + w.Put(0).Text("zone.raw").Text("Name").Text("Description"); + w.Put(0).Put(0).Put(1).Put(2); + for (const uint32_t version : { 8u, 9u }) { + w.Put(version).Wide("Spawner").Put(4).Put(0).Put(0); + w.Put(6010).Put(10).Put(1).Put(1).Put(123); + if (version >= 9) w.Put(0); + w.Put(1).Point(1, 1, 1).Put(1.0f).Put(0.0f).Put(0.0f).Put(0.0f).Put(0); + } + + std::istringstream stream(w.data); + ZoneFile zone; + zone.Read(stream); + EXPECT_FALSE(stream.fail()); + EXPECT_EQ(stream.peek(), std::char_traits::eof()); + ASSERT_EQ(zone.paths.size(), 2u); + EXPECT_EQ(zone.paths[0].spawner.spawnerNetActive, 1); + EXPECT_EQ(zone.paths[0].pathWaypoints.at(0).position, NiPoint3(1, 1, 1)); + EXPECT_EQ(zone.paths[1].spawner.spawnerNetActive, 0); +} + TEST(ZoneFileTests, ShortFilesThrowOrFail) { const auto zone = SampleZone(); for (const size_t length : { size_t{ 3 }, size_t{ 40 }, zone.size() / 2, zone.size() - 1 }) {