mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-06-22 22:54:21 +00:00
feat: add eSceneType enum, filter scene graph to general scenes, zone parsing improvements
- Add eSceneType enum (General, Audio) replacing raw uint32_t in SceneRef - Filter BuildSceneGraph to only include General scenes - Skip transitions referencing non-general scenes in adjacency graph - Rename SceneRef unknown fields to scenePosition/sceneRadius - Zone parsing and Level improvements Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -85,11 +85,29 @@ void Zone::LoadZoneIntoMemory() {
|
||||
LoadScene(file);
|
||||
}
|
||||
|
||||
//Read generic zone info:
|
||||
BinaryIO::ReadString<uint8_t>(file, m_ZonePath, BinaryIO::ReadType::String);
|
||||
// Zone boundary lines
|
||||
uint8_t numBoundaries = 0;
|
||||
BinaryIO::BinaryRead(file, numBoundaries);
|
||||
m_Boundaries.reserve(numBoundaries);
|
||||
for (uint8_t i = 0; i < numBoundaries; ++i) {
|
||||
ZoneBoundary boundary;
|
||||
BinaryIO::BinaryRead(file, boundary.normal);
|
||||
BinaryIO::BinaryRead(file, boundary.point);
|
||||
uint32_t packed;
|
||||
BinaryIO::BinaryRead(file, packed);
|
||||
boundary.destMapID = static_cast<uint16_t>(packed & 0xFFFF);
|
||||
boundary.destInstanceID = static_cast<uint16_t>((packed >> 16) & 0xFFFF);
|
||||
BinaryIO::BinaryRead(file, boundary.destSceneID);
|
||||
BinaryIO::BinaryRead(file, boundary.spawnLocation);
|
||||
m_Boundaries.push_back(boundary);
|
||||
}
|
||||
|
||||
// Zone info strings
|
||||
BinaryIO::ReadString<uint8_t>(file, m_ZoneRawPath, BinaryIO::ReadType::String);
|
||||
BinaryIO::ReadString<uint8_t>(file, m_ZoneName, BinaryIO::ReadType::String);
|
||||
BinaryIO::ReadString<uint8_t>(file, m_ZoneDesc, BinaryIO::ReadType::String);
|
||||
if (m_FileFormatVersion > Zone::FileFormatVersion::PrePreAlpha) {
|
||||
BinaryIO::ReadString<uint8_t>(file, m_ZoneName, BinaryIO::ReadType::String);
|
||||
BinaryIO::ReadString<uint8_t>(file, m_ZoneDesc, BinaryIO::ReadType::String);
|
||||
}
|
||||
|
||||
auto zoneFolderPath = m_ZoneFilePath.substr(0, m_ZoneFilePath.rfind('/') + 1);
|
||||
if (!Game::assetManager->HasFile(zoneFolderPath + m_ZoneRawPath)) {
|
||||
@@ -271,14 +289,15 @@ void Zone::LoadScene(std::istream& file) {
|
||||
}
|
||||
if (m_FileFormatVersion >= Zone::FileFormatVersion::LatePreAlpha) {
|
||||
BinaryIO::BinaryRead(file, scene.sceneType);
|
||||
lwoSceneID.SetLayerID(scene.sceneType);
|
||||
lwoSceneID.SetLayerID(static_cast<uint32_t>(scene.sceneType));
|
||||
|
||||
|
||||
BinaryIO::ReadString<uint8_t>(file, scene.name, BinaryIO::ReadType::String);
|
||||
}
|
||||
|
||||
if (m_FileFormatVersion == Zone::FileFormatVersion::LatePreAlpha) {
|
||||
BinaryIO::BinaryRead(file, scene.unknown1);
|
||||
BinaryIO::BinaryRead(file, scene.unknown2);
|
||||
BinaryIO::BinaryRead(file, scene.scenePosition);
|
||||
BinaryIO::BinaryRead(file, scene.sceneRadius);
|
||||
}
|
||||
|
||||
if (m_FileFormatVersion >= Zone::FileFormatVersion::LatePreAlpha) {
|
||||
@@ -385,11 +404,39 @@ void Zone::LoadSceneTransition(std::istream& file) {
|
||||
|
||||
SceneTransitionInfo Zone::LoadSceneTransitionInfo(std::istream& file) {
|
||||
SceneTransitionInfo info;
|
||||
BinaryIO::BinaryRead(file, info.sceneID);
|
||||
uint32_t sceneID, layerID;
|
||||
BinaryIO::BinaryRead(file, sceneID);
|
||||
BinaryIO::BinaryRead(file, layerID);
|
||||
info.sceneID = LWOSCENEID(static_cast<int32_t>(sceneID), layerID);
|
||||
BinaryIO::BinaryRead(file, info.position);
|
||||
return info;
|
||||
}
|
||||
|
||||
static void ReadLdfConfig(std::istream& file, PathWaypoint& waypoint, PathType pathType) {
|
||||
uint32_t count;
|
||||
BinaryIO::BinaryRead(file, count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
std::string parameter;
|
||||
BinaryIO::ReadString<uint8_t>(file, parameter, BinaryIO::ReadType::WideString);
|
||||
|
||||
std::string value;
|
||||
BinaryIO::ReadString<uint8_t>(file, value, BinaryIO::ReadType::WideString);
|
||||
|
||||
if (pathType == PathType::Movement || pathType == PathType::Rail) {
|
||||
parameter.erase(std::remove_if(parameter.begin(), parameter.end(), ::isspace), parameter.end());
|
||||
auto waypointCommand = WaypointCommandType::StringToWaypointCommandType(parameter);
|
||||
if (waypointCommand == eWaypointCommandType::DELAY) value.erase(std::remove_if(value.begin(), value.end(), ::isspace), value.end());
|
||||
if (waypointCommand != eWaypointCommandType::INVALID) {
|
||||
auto& command = waypoint.commands.emplace_back();
|
||||
command.command = waypointCommand;
|
||||
command.data = value;
|
||||
} else LOG("Tried to load invalid waypoint command '%s'", parameter.c_str());
|
||||
} else {
|
||||
waypoint.config.ParseInsert(parameter + "=" + value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Zone::LoadPath(std::istream& file) {
|
||||
Path path = Path();
|
||||
|
||||
@@ -397,6 +444,34 @@ void Zone::LoadPath(std::istream& file) {
|
||||
|
||||
BinaryIO::ReadString<uint8_t>(file, path.pathName, BinaryIO::ReadType::WideString);
|
||||
|
||||
if (path.pathVersion <= 2) {
|
||||
// Legacy format: type_name string present, no behavior field,
|
||||
// unified waypoint format (pos + rot + lock + speed + wait + config).
|
||||
std::string typeName;
|
||||
BinaryIO::ReadString<uint8_t>(file, typeName, BinaryIO::ReadType::WideString);
|
||||
|
||||
BinaryIO::BinaryRead(file, path.pathType);
|
||||
BinaryIO::BinaryRead(file, path.flags);
|
||||
|
||||
BinaryIO::BinaryRead(file, path.waypointCount);
|
||||
path.pathWaypoints.reserve(path.waypointCount);
|
||||
for (uint32_t i = 0; i < path.waypointCount; ++i) {
|
||||
PathWaypoint waypoint = PathWaypoint();
|
||||
BinaryIO::BinaryRead(file, waypoint.position);
|
||||
BinaryIO::BinaryRead(file, waypoint.rotation.w);
|
||||
BinaryIO::BinaryRead(file, waypoint.rotation.x);
|
||||
BinaryIO::BinaryRead(file, waypoint.rotation.y);
|
||||
BinaryIO::BinaryRead(file, waypoint.rotation.z);
|
||||
BinaryIO::BinaryRead(file, waypoint.movingPlatform.lockPlayer);
|
||||
BinaryIO::BinaryRead(file, waypoint.speed);
|
||||
BinaryIO::BinaryRead(file, waypoint.movingPlatform.wait);
|
||||
ReadLdfConfig(file, waypoint, path.pathType);
|
||||
path.pathWaypoints.push_back(waypoint);
|
||||
}
|
||||
m_Paths.push_back(path);
|
||||
return;
|
||||
}
|
||||
|
||||
BinaryIO::BinaryRead(file, path.pathType);
|
||||
BinaryIO::BinaryRead(file, path.flags);
|
||||
BinaryIO::BinaryRead(file, path.pathBehavior);
|
||||
@@ -435,7 +510,6 @@ void Zone::LoadPath(std::istream& file) {
|
||||
BinaryIO::ReadString<uint8_t>(file, path.camera.nextPath, BinaryIO::ReadType::WideString);
|
||||
if (path.pathVersion >= 14) {
|
||||
BinaryIO::BinaryRead(file, path.camera.rotatePlayer);
|
||||
|
||||
}
|
||||
} else if (path.pathType == PathType::Spawner) {
|
||||
BinaryIO::BinaryRead(file, path.spawner.spawnedLOT);
|
||||
@@ -443,7 +517,9 @@ void Zone::LoadPath(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
|
||||
@@ -457,7 +533,6 @@ void Zone::LoadPath(std::istream& file) {
|
||||
BinaryIO::BinaryRead(file, waypoint.position.y);
|
||||
BinaryIO::BinaryRead(file, waypoint.position.z);
|
||||
|
||||
|
||||
if (path.pathType == PathType::Spawner || path.pathType == PathType::MovingPlatform || path.pathType == PathType::Race || path.pathType == PathType::Camera || path.pathType == PathType::Rail) {
|
||||
BinaryIO::BinaryRead(file, waypoint.rotation.w);
|
||||
BinaryIO::BinaryRead(file, waypoint.rotation.x);
|
||||
@@ -491,37 +566,11 @@ void Zone::LoadPath(std::istream& file) {
|
||||
|
||||
// object LDF configs
|
||||
if (path.pathType == PathType::Movement || path.pathType == PathType::Spawner || path.pathType == PathType::Rail) {
|
||||
uint32_t count;
|
||||
BinaryIO::BinaryRead(file, count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
std::string parameter;
|
||||
BinaryIO::ReadString<uint8_t>(file, parameter, BinaryIO::ReadType::WideString);
|
||||
|
||||
std::string value;
|
||||
BinaryIO::ReadString<uint8_t>(file, value, BinaryIO::ReadType::WideString);
|
||||
|
||||
if (path.pathType == PathType::Movement || path.pathType == PathType::Rail) {
|
||||
// cause NetDevil puts spaces in things that don't need spaces
|
||||
parameter.erase(std::remove_if(parameter.begin(), parameter.end(), ::isspace), parameter.end());
|
||||
auto waypointCommand = WaypointCommandType::StringToWaypointCommandType(parameter);
|
||||
if (waypointCommand == eWaypointCommandType::DELAY) value.erase(std::remove_if(value.begin(), value.end(), ::isspace), value.end());
|
||||
if (waypointCommand != eWaypointCommandType::INVALID) {
|
||||
auto& command = waypoint.commands.emplace_back();
|
||||
command.command = waypointCommand;
|
||||
command.data = value;
|
||||
} else LOG("Tried to load invalid waypoint command '%s'", parameter.c_str());
|
||||
} else {
|
||||
waypoint.config.ParseInsert(parameter + "=" + value);
|
||||
}
|
||||
|
||||
}
|
||||
ReadLdfConfig(file, waypoint, path.pathType);
|
||||
}
|
||||
|
||||
// We verify the waypoint heights against the navmesh because in many movement paths,
|
||||
// the waypoint is located near 0 height,
|
||||
if (path.pathType == PathType::Movement) {
|
||||
if (dpWorld::IsLoaded()) {
|
||||
// 2000 should be large enough for every world.
|
||||
waypoint.position.y = dpWorld::GetNavMesh()->GetHeightAtPoint(waypoint.position, 2000.0f);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user