mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-12 07:43:43 +00:00
fix(zone): scenes of version 30-32 zone files are numbered like the client
Zone files before version 33 have no scene IDs. The client gives each scene its index in the file as its ID, -1 past 255, with layer 0 (LuzReader::ReadScenes, 1.10.64, via the LWOSceneID from the loop index); the reader left every such scene at ID 0, so a zone with several scenes had them all collide on one ID. The version 30 zones on disk have one scene each, so what they read is unchanged. Check in game: nothing to check on live worlds (all are version 36+). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -33,7 +33,7 @@ void ZoneFile::ReadHeader(std::istream& file) {
|
||||
} else BinaryIO::BinaryRead(file, sceneCount);
|
||||
|
||||
for (uint32_t i = 0; i < sceneCount; ++i) {
|
||||
ReadScene(file);
|
||||
ReadScene(file, i);
|
||||
}
|
||||
|
||||
ReadZoneBoundaries(file);
|
||||
@@ -70,7 +70,7 @@ void ZoneFile::Read(std::istream& file) {
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneFile::ReadScene(std::istream& file) {
|
||||
void ZoneFile::ReadScene(std::istream& file, uint32_t index) {
|
||||
ZoneScene scene;
|
||||
|
||||
// Before PrePreAlpha a scene is only its SceneTable ID; ResolveSceneTable finds its file (LuzReader::ReadScenes)
|
||||
@@ -82,6 +82,8 @@ void ZoneFile::ReadScene(std::istream& file) {
|
||||
}
|
||||
|
||||
BinaryIO::ReadString<uint8_t>(file, scene.filename, BinaryIO::ReadType::String);
|
||||
// Until LatePreAlpha the file has no scene IDs: a scene's ID is its index (-1 past 255) in the file
|
||||
scene.id = index < 256 ? index : UINT32_MAX;
|
||||
|
||||
if (fileFormatVersion >= FileFormatVersion::LatePreAlpha) {
|
||||
BinaryIO::BinaryRead(file, scene.id);
|
||||
|
||||
@@ -255,7 +255,7 @@ struct ZoneFile {
|
||||
void ResolveSceneTable(const std::function<std::optional<std::string>(uint32_t)>& sceneName);
|
||||
|
||||
private:
|
||||
void ReadScene(std::istream& file);
|
||||
void ReadScene(std::istream& file, uint32_t index);
|
||||
void ReadZoneBoundaries(std::istream& file);
|
||||
void ReadSceneTransition(std::istream& file);
|
||||
SceneTransitionInfo ReadSceneTransitionInfo(std::istream& file);
|
||||
|
||||
@@ -243,7 +243,7 @@ void Zone::LoadScene(ZoneScene&& zoneScene) {
|
||||
SceneRef scene;
|
||||
static_cast<ZoneScene&>(scene) = std::move(zoneScene);
|
||||
scene.level = nullptr;
|
||||
// Older files have no scene ID or layer; those stay 0
|
||||
// Older files have no scene ID or layer: ZoneFile numbers their scenes, and the layer stays General
|
||||
LWOSCENEID lwoSceneID(scene.id, scene.sceneType);
|
||||
|
||||
std::string luTriggersPath = scene.filename.substr(0, scene.filename.size() - 4) + ".lutriggers";
|
||||
|
||||
@@ -167,6 +167,22 @@ TEST(ZoneFileTests, ReadsVersionsBeforePrePreAlpha) {
|
||||
EXPECT_EQ(zone.scenes[1].filename, "scene9.lvl");
|
||||
}
|
||||
|
||||
// Versions 30-32 have no scene IDs: the client numbers the scenes in file order
|
||||
TEST(ZoneFileTests, EarlyScenesAreNumberedInOrder) {
|
||||
ZoneBytes w;
|
||||
w.Put<uint32_t>(32).Put<uint32_t>(70).Put<uint8_t>(3).Text("a.lvl").Text("b.lvl").Text("c.lvl");
|
||||
w.Put<uint8_t>(0).Text("zone.raw").Text("Name").Text("Description").Put<uint32_t>(0);
|
||||
std::istringstream stream(w.data);
|
||||
ZoneFile zone;
|
||||
zone.Read(stream);
|
||||
EXPECT_FALSE(stream.fail());
|
||||
ASSERT_EQ(zone.scenes.size(), 3u);
|
||||
EXPECT_EQ(zone.scenes[0].id, 0u);
|
||||
EXPECT_EQ(zone.scenes[1].id, 1u);
|
||||
EXPECT_EQ(zone.scenes[2].id, 2u);
|
||||
EXPECT_EQ(zone.scenes[2].filename, "c.lvl");
|
||||
}
|
||||
|
||||
// A PrePreAlpha (30) file ends at its terrain file's name: no zone name, description, transitions or paths
|
||||
TEST(ZoneFileTests, PrePreAlphaHasNoZoneName) {
|
||||
ZoneBytes w;
|
||||
|
||||
Reference in New Issue
Block a user