Files
DarkflameServer/dCommon/LevelFile.h
Aaron Kimbrell 458fb601c9 fix(level): find a scene file's chunks and sections as the client does
SceneLoader::ReadLvlFile (1.10.64):
- chunked files: the file info chunk starts the file and gives where
  the environment, object and particle chunks start, 0 for none
  (DoLvlChunk, ReadLvlChunk1000); the reader walked the chunks one after
  another by their sizes instead;
- older files: the editor settings are a u32 size and that many bytes
  (SceneLoader::ReadEditorSettings, skipped by size); the reader took
  them for a u32 and then a count of 12 byte points;
- older files before version 3 have no objects for the client ("Level
  file is unsupported").

LevelFile now does the same. Every scene file on disk reads the same
objects as before.

Check in game: every world spawns its objects as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 08:39:37 -05:00

69 lines
1.8 KiB
C++

#pragma once
#include <cstdint>
#include <iosfwd>
#include <map>
#include <vector>
#include "dCommonVars.h"
#include "NiPoint3.h"
#include "NiQuaternion.h"
#include "LDFFormat.h"
struct SceneObject {
LWOOBJID id;
LOT lot;
uint32_t nodeType = 1; // the client's default when the file has none, or one outside 0-10
uint32_t glomId = 1;
NiPoint3 position;
NiQuaternion rotation = QuatUtils::IDENTITY;
float scale = 1.0f;
uint32_t renderTechniqueCount{};
LwoNameValue settings;
};
/**
* A scene file (.lvl) as the world server loads it (Level): its chunk headers and every object in it, with the object's
* settings parsed. Only reads; which objects the world spawns (feature gating, client-only objects, spawners) stays in
* dZoneManager, so the dashboard reads scenes with the same code.
*/
struct LevelFile {
enum ChunkTypeID : uint16_t {
FileInfo = 1000,
SceneEnviroment = 2000,
SceneObjectData,
SceneParticleData
};
struct FileInfoChunk {
uint32_t version{};
uint32_t revision{};
uint32_t enviromentChunkStart{};
uint32_t objectChunkStart{};
uint32_t particleChunkStart{};
};
struct ChunkHeader {
uint32_t id{};
uint16_t chunkVersion{};
ChunkTypeID chunkType{};
uint32_t size{};
uint32_t startPosition{};
FileInfoChunk fileInfo;
};
std::map<uint32_t, ChunkHeader> chunkHeaders;
std::vector<SceneObject> objects;
/**
* Reads the whole file. Throws std::runtime_error (BinaryIO) if it ends early; what was read before that stays
* (an object is only added once all of it was read).
*/
void Read(std::istream& file);
private:
static ChunkHeader ReadChunkHeader(std::istream& file, uint32_t start);
void ReadFileInfoChunk(std::istream& file, ChunkHeader& header);
void ReadSceneObjectDataChunk(std::istream& file, uint32_t version);
};