mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-06 20:07:13 +00:00
The world read only a scene's objects and skipped the rest with file.ignore. Level now reads a .lvl the way SceneLoader::LoadLvlFile does (1.10.64) and keeps what it reads. Chunked files: the file info chunk gives where the environment, object and particle chunks start (the chunks were walked in order before); the environment chunk gives where the lighting, skydome and editor settings start, and the client reads all three only when there is lighting. Files from before chunks: the no-editor-settings byte only from version 32, the revision from 37, a file newer than 48 is not read, a file older than 3 has no objects; then lighting, skydome, editor settings and objects in turn. Kept, by version: - lighting: blend time (45 on, default 10), ambient, specular, upper hemisphere, position, min and max draw distances (31 on; before 39 fog near and far only), cull settings (40 on), fog colour (31 on), directional colour (36 on), and before 42 the zone's spawn point (before 33 the fixed one the client uses); - the skydome and its five other files (34 on; they were skipped from 33); - the editor's colours (37 on, the first 32); - each object's node type (38 on), glom ID (32 on) and render techniques (7 on: a 64 byte name, then per technique a 64 byte name, u32, u8 and 16 floats); before, a count of techniques was read and the techniques themselves were not, so an object with any misread the rest of the file. Object config is split at line breaks as before. A file that ends early keeps the objects read before its end. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
139 lines
4.3 KiB
C++
139 lines
4.3 KiB
C++
#pragma once
|
|
#include "dZMCommon.h"
|
|
#include <map>
|
|
#include <iostream>
|
|
#include "NiColor.h"
|
|
#include "Zone.h"
|
|
|
|
// Fog and object draw distances (SceneDrawDistances); -1 is the client's default for a value the file doesn't have
|
|
struct SceneDrawDistances {
|
|
float fogNear = -1.0f;
|
|
float fogFar = -1.0f;
|
|
float postFogSolid = -1.0f;
|
|
float postFogFade = -1.0f;
|
|
float staticObjectDistance = -1.0f;
|
|
float dynamicObjectDistance = -1.0f;
|
|
};
|
|
|
|
// The draw distances of a group of objects (version 40 on)
|
|
struct SceneCullSetting {
|
|
uint32_t group{};
|
|
float minDistance{};
|
|
float maxDistance{};
|
|
};
|
|
|
|
// A scene's light environment (SceneLoader::ReadLightingInfo); the defaults are the client's for what older files don't have
|
|
struct LevelLighting {
|
|
float blendTime = 10.0f; // version 45 on
|
|
NiColor ambient;
|
|
NiColor specular;
|
|
NiColor upperHemi;
|
|
NiPoint3 position;
|
|
// Version 31 on; before 39 only the fog distances, the same in both
|
|
SceneDrawDistances minDrawDistances;
|
|
SceneDrawDistances maxDrawDistances;
|
|
std::vector<SceneCullSetting> cullSettings; // version 40 on
|
|
NiColor fogColor{ 0.75f, 0.88f, 0.91f }; // version 31 on
|
|
NiColor directional; // version 36 on
|
|
|
|
// Before version 42 the zone's spawn point is here. Before 33 the file has only a position, which the client
|
|
// ignores: it uses a fixed spawn point instead
|
|
bool hasSpawnPoint = false;
|
|
NiPoint3 filePosition;
|
|
NiPoint3 spawnPosition;
|
|
NiQuaternion spawnRotation = QuatUtils::IDENTITY;
|
|
};
|
|
|
|
// The skydome's file and five more (version 34 on) the client reads and doesn't use (SceneLoader::ReadSkydomeInfo)
|
|
struct LevelSkydome {
|
|
std::string filename;
|
|
std::array<std::string, 5> extraFilenames;
|
|
};
|
|
|
|
// A scene file (.lvl), read as the client reads it (SceneLoader::LoadLvlFile)
|
|
class Level {
|
|
public:
|
|
enum ChunkTypeID : uint16_t {
|
|
FileInfo = 1000,
|
|
SceneEnviroment = 2000,
|
|
SceneObjectData,
|
|
SceneParticleData
|
|
};
|
|
|
|
enum ChunkTypes {
|
|
Enviroment,
|
|
Objects,
|
|
Particles
|
|
};
|
|
|
|
struct FileInfoChunk {
|
|
uint32_t version{};
|
|
uint32_t revision{};
|
|
uint32_t enviromentChunkStart{};
|
|
uint32_t objectChunkStart{};
|
|
uint32_t particleChunkStart{};
|
|
};
|
|
|
|
struct Header {
|
|
uint32_t id{};
|
|
uint16_t chunkVersion{};
|
|
ChunkTypeID chunkType{};
|
|
uint32_t size{};
|
|
uint32_t startPosition{};
|
|
FileInfoChunk fileInfo;
|
|
LWOSCENEID lwoSceneID;
|
|
};
|
|
|
|
// The environment chunk: where its parts start in the file (0 for none)
|
|
struct EnviromentChunk {
|
|
uint32_t lightingStart{};
|
|
uint32_t skydomeStart{};
|
|
uint32_t editorSettingsStart{};
|
|
};
|
|
|
|
public:
|
|
// Reads the scene file and loads its objects into the world
|
|
Level(Zone* parentZone, const std::string& filepath);
|
|
// Only reads the scene 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)
|
|
explicit Level(std::istream& file);
|
|
|
|
static void MakeSpawner(const SceneObject& obj);
|
|
|
|
uint32_t GetVersion() const { return m_Version; }
|
|
uint32_t GetRevision() const { return m_Revision; }
|
|
const EnviromentChunk& GetEnviroment() const { return m_Enviroment; }
|
|
bool HasLighting() const { return m_HasLighting; }
|
|
const LevelLighting& GetLighting() const { return m_Lighting; }
|
|
const LevelSkydome& GetSkydome() const { return m_Skydome; }
|
|
const std::vector<NiColor>& GetEditorColors() const { return m_EditorColors; }
|
|
const std::vector<SceneObject>& GetObjects() const { return m_Objects; }
|
|
|
|
std::map<uint32_t, Header> m_ChunkHeaders;
|
|
private:
|
|
Zone* m_ParentZone = nullptr;
|
|
|
|
// The file's version: from the file info chunk, or the header of a file from before chunks
|
|
uint32_t m_Version{};
|
|
uint32_t m_Revision{};
|
|
// Before chunks, from version 32: set when the file has no editor settings
|
|
uint8_t m_NoEditorSettings{};
|
|
EnviromentChunk m_Enviroment;
|
|
bool m_HasLighting = false;
|
|
LevelLighting m_Lighting;
|
|
LevelSkydome m_Skydome;
|
|
// Version 37 on: the editor's saved colours (the client keeps at most 32)
|
|
std::vector<NiColor> m_EditorColors;
|
|
std::vector<SceneObject> m_Objects;
|
|
|
|
//private functions:
|
|
void ReadChunks(std::istream& file);
|
|
static Header ReadChunkHeader(std::istream& file, uint32_t start);
|
|
void ReadFileInfoChunk(std::istream& file, Header& header);
|
|
void ReadLightingInfo(std::istream& file);
|
|
void ReadSkydomeInfo(std::istream& file);
|
|
void ReadEditorSettings(std::istream& file);
|
|
void ReadSceneObjectDataChunk(std::istream& file);
|
|
void LoadSceneObjects();
|
|
};
|