fix: address PR review feedback for raw terrain parsing

- Fix integer division bug in scene map lookups (was truncating to 0)
- Fix indentation throughout Raw.cpp, DEVGMCommands.cpp
- Add missing <algorithm> and <set> includes in dZoneManager.cpp
- Add missing width/height/scaleFactor guards in SpawnAllScenePoints
- Fix %llu -> %zu for size_t format specifiers
- Simplify no-op worldY calculation (y / scale * scale -> y)
- Remove redundant ternary guards in GetSceneIDFromPosition
- Fix misleading "Spawned LOT" feedback message
- Update info.settings to use LwoNameValue::Insert API (post-merge fix)
- Refactor SceneColor to static constexpr std::array (no heap alloc)
- Make NiColor constructors constexpr
- Remove duplicate CDZoneTableTable.h include

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-06-21 01:50:08 -05:00
parent 83e2ea4278
commit 1aeede3cd1
6 changed files with 264 additions and 303 deletions

View File

@@ -2014,19 +2014,16 @@ namespace DEVGMCommands {
if (chunk.sceneMap.empty() || chunk.colorMapResolution == 0 || chunk.heightMap.empty()
|| chunk.width <= 1 || chunk.height <= 1 || chunk.scaleFactor <= 0.0f) continue;
// Iterate through the heightmap (same as GenerateTerrainMesh)
for (uint32_t i = 0; i < chunk.width; ++i) {
for (uint32_t j = 0; j < chunk.height; ++j) {
// Get height at this position
const uint32_t heightIndex = chunk.width * i + j;
if (heightIndex >= chunk.heightMap.size()) continue;
const float y = chunk.heightMap[heightIndex];
// Map heightmap position to scene map position (same as GenerateTerrainMesh)
const float sceneMapI = ((i) / (chunk.width - 1)) * (chunk.colorMapResolution - 1);
const float sceneMapJ = ((j) / (chunk.height - 1)) * (chunk.colorMapResolution - 1);
const float sceneMapI = (static_cast<float>(i) / static_cast<float>(chunk.width - 1)) * static_cast<float>(chunk.colorMapResolution - 1);
const float sceneMapJ = (static_cast<float>(j) / static_cast<float>(chunk.height - 1)) * static_cast<float>(chunk.colorMapResolution - 1);
const uint32_t sceneI = std::min(static_cast<uint32_t>(sceneMapI), chunk.colorMapResolution - 1);
const uint32_t sceneJ = std::min(static_cast<uint32_t>(sceneMapJ), chunk.colorMapResolution - 1);
const uint32_t sceneIndex = sceneI * chunk.colorMapResolution + sceneJ;
@@ -2035,23 +2032,21 @@ namespace DEVGMCommands {
if (sceneIndex < chunk.sceneMap.size()) {
sceneID = chunk.sceneMap[sceneIndex];
}
// Check if this point belongs to the current scene
if (sceneID == currentSceneID.GetSceneID()) {
// Calculate world position (same as GenerateTerrainMesh)
const float worldX = ((i) + (chunk.offsetX / chunk.scaleFactor)) * chunk.scaleFactor;
const float worldY = (y / chunk.scaleFactor) * chunk.scaleFactor;
const float worldZ = ((j) + (chunk.offsetZ / chunk.scaleFactor)) * chunk.scaleFactor;
NiPoint3 spawnPos(worldX, worldY, worldZ);
EntityInfo info;
info.lot = lot + currentSceneID.GetSceneID(); // to differentiate scenes
if (sceneID == currentSceneID.GetSceneID()) {
const float worldX = (static_cast<float>(i) + (chunk.offsetX / chunk.scaleFactor)) * chunk.scaleFactor;
const float worldY = y;
const float worldZ = (static_cast<float>(j) + (chunk.offsetZ / chunk.scaleFactor)) * chunk.scaleFactor;
NiPoint3 spawnPos(worldX, worldY, worldZ);
EntityInfo info;
info.lot = lot + currentSceneID.GetSceneID();
info.pos = spawnPos;
info.rot = QuatUtils::IDENTITY;
info.spawner = nullptr;
info.spawnerID = entity->GetObjectID();
info.spawnerNodeID = 0;
info.settings = { new LDFData<bool>(u"SpawnedFromSlashCommand", true) };
info.settings.Insert(u"SpawnedFromSlashCommand", true);
Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr);
if (newEntity != nullptr) {
@@ -2074,7 +2069,7 @@ namespace DEVGMCommands {
const auto* sceneRef = zone->GetScene(currentSceneID);
const std::string sceneName = sceneRef ? sceneRef->name : "Unknown";
std::ostringstream feedback;
feedback << "Spawned LOT " << lot + currentSceneID.GetSceneID() << " at " << spawnedCount << " points in scene "
feedback << "Spawned " << spawnedCount << " points (LOT " << lot + currentSceneID.GetSceneID() << ") in scene "
<< currentSceneID.GetSceneID() << " (" << sceneName << ").";
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(feedback.str()));
}
@@ -2102,21 +2097,19 @@ namespace DEVGMCommands {
std::map<uint8_t, uint32_t> sceneSpawnCounts; // Track spawns per scene
for (const auto& chunk : raw.chunks) {
if (chunk.sceneMap.empty() || chunk.colorMapResolution == 0 || chunk.heightMap.empty()) continue;
if (chunk.sceneMap.empty() || chunk.colorMapResolution == 0 || chunk.heightMap.empty()
|| chunk.width <= 1 || chunk.height <= 1 || chunk.scaleFactor <= 0.0f) continue;
// Iterate through the heightmap (same as GenerateTerrainMesh)
for (uint32_t i = 0; i < chunk.width; ++i) {
for (uint32_t j = 0; j < chunk.height; ++j) {
// Get height at this position
const uint32_t heightIndex = chunk.width * i + j;
if (heightIndex >= chunk.heightMap.size()) continue;
const float y = chunk.heightMap[heightIndex];
// Map heightmap position to scene map position (same as GenerateTerrainMesh)
const float sceneMapI = ((i) / (chunk.width - 1)) * (chunk.colorMapResolution - 1);
const float sceneMapJ = ((j) / (chunk.height - 1)) * (chunk.colorMapResolution - 1);
const float sceneMapI = (static_cast<float>(i) / static_cast<float>(chunk.width - 1)) * static_cast<float>(chunk.colorMapResolution - 1);
const float sceneMapJ = (static_cast<float>(j) / static_cast<float>(chunk.height - 1)) * static_cast<float>(chunk.colorMapResolution - 1);
const uint32_t sceneI = std::min(static_cast<uint32_t>(sceneMapI), chunk.colorMapResolution - 1);
const uint32_t sceneJ = std::min(static_cast<uint32_t>(sceneMapJ), chunk.colorMapResolution - 1);
const uint32_t sceneIndex = sceneI * chunk.colorMapResolution + sceneJ;
@@ -2125,24 +2118,22 @@ namespace DEVGMCommands {
if (sceneIndex < chunk.sceneMap.size()) {
sceneID = chunk.sceneMap[sceneIndex];
}
// Skip invalid scenes (scene ID 0 typically means no scene)
if (sceneID == 0) continue;
// Calculate world position (same as GenerateTerrainMesh)
const float worldX = ((i) + (chunk.offsetX / chunk.scaleFactor)) * chunk.scaleFactor;
const float worldY = (y / chunk.scaleFactor) * chunk.scaleFactor;
const float worldZ = ((j) + (chunk.offsetZ / chunk.scaleFactor)) * chunk.scaleFactor;
const float worldX = (static_cast<float>(i) + (chunk.offsetX / chunk.scaleFactor)) * chunk.scaleFactor;
const float worldY = y;
const float worldZ = (static_cast<float>(j) + (chunk.offsetZ / chunk.scaleFactor)) * chunk.scaleFactor;
NiPoint3 spawnPos(worldX, worldY, worldZ);
EntityInfo info;
info.lot = lot + sceneID; // to show different scenes
info.lot = lot + sceneID;
info.pos = spawnPos;
info.rot = QuatUtils::IDENTITY;
info.spawner = nullptr;
info.spawnerID = entity->GetObjectID();
info.spawnerNodeID = 0;
info.settings = { new LDFData<bool>(u"SpawnedFromSlashCommand", true) };
info.settings.Insert(u"SpawnedFromSlashCommand", true);
Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr);
if (newEntity != nullptr) {