feat: scene ghosting, as the client streams a zone's scenes

The client keeps the scene under the player loaded, the scenes the zone
file's transitions connect to it, and the global scene
(Zone::StreamScenesAroundPosition 0x0108a3f0, TerrainManager::GetSceneAtPos
0x01069010, the connected scenes at 0x01066500; transitions naming a
missing scene dropped as Zone::FixupInvalidTransitions 0x010842e0 does).

- ZoneScenes (dCommon): the terrain's scene map lookup and the scene graph,
  shared by the world server and the dashboard.
- Objects remember the scene they were placed in (spawners pass theirs on).
- ghosting_scenes=1 (world config, off by default): players get the objects
  of their loaded scenes instead of the ones within the ghosting distances;
  objects from no scene go by the scene under them. Zones without a scene
  map keep distance ghosting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-27 22:02:20 -05:00
parent 696580cce5
commit 1b9724a7ec
20 changed files with 363 additions and 19 deletions

View File

@@ -19,8 +19,9 @@
#include "dConfig.h"
#include <ranges>
Level::Level(Zone* parentZone, const std::string& filepath) {
Level::Level(Zone* parentZone, const std::string& filepath, int32_t sceneID) {
m_ParentZone = parentZone;
m_SceneID = sceneID;
auto stream = Game::assetManager->GetFile(filepath.c_str());
@@ -40,8 +41,9 @@ Level::Level(Zone* parentZone, const std::string& filepath) {
LoadSceneObjects(levelFile.objects);
}
void Level::MakeSpawner(const SceneObject& obj) {
void Level::MakeSpawner(const SceneObject& obj, int32_t sceneID) {
SpawnerInfo spawnInfo = SpawnerInfo();
spawnInfo.scene = sceneID;
SpawnerNode* node = new SpawnerNode();
spawnInfo.templateID = obj.lot;
spawnInfo.spawnerID = obj.id;
@@ -162,7 +164,7 @@ void Level::LoadSceneObjects(const std::vector<SceneObject>& objects) {
}
if (obj.lot == 176) { //Spawner
MakeSpawner(obj);
MakeSpawner(obj, m_SceneID);
} else { //Regular object
EntityInfo info;
info.spawnerID = 0;
@@ -172,6 +174,7 @@ void Level::LoadSceneObjects(const std::vector<SceneObject>& objects) {
info.rot = obj.rotation;
info.settings = obj.settings;
info.scale = obj.scale;
info.scene = m_SceneID;
Game::entityManager->CreateEntity(info);
}
}