From 1aeede3cd15882b0db192522ede558c601270bcd Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sun, 21 Jun 2026 01:50:08 -0500 Subject: [PATCH] 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 and 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 --- dCommon/NiColor.h | 4 +- dCommon/dClient/SceneColor.h | 317 +++++++++--------- .../SlashCommands/DEVGMCommands.cpp | 67 ++-- dZoneManager/Raw.cpp | 157 ++++----- dZoneManager/Zone.cpp | 2 +- dZoneManager/dZoneManager.cpp | 20 +- 6 files changed, 264 insertions(+), 303 deletions(-) diff --git a/dCommon/NiColor.h b/dCommon/NiColor.h index e6d01a4f..585f0e5e 100644 --- a/dCommon/NiColor.h +++ b/dCommon/NiColor.h @@ -6,8 +6,8 @@ struct NiColor { float m_Green; float m_Blue; - NiColor(float red, float green, float blue) : m_Red(red), m_Green(green), m_Blue(blue) {} - NiColor() : NiColor(0.0f, 0.0f, 0.0f) {} + constexpr NiColor(float red, float green, float blue) : m_Red(red), m_Green(green), m_Blue(blue) {} + constexpr NiColor() : NiColor(0.0f, 0.0f, 0.0f) {} /* reduce RGB files to grayscale, with or without alpha * using the equation given in Poynton's ColorFAQ at diff --git a/dCommon/dClient/SceneColor.h b/dCommon/dClient/SceneColor.h index f9139957..2ae4e33b 100644 --- a/dCommon/dClient/SceneColor.h +++ b/dCommon/dClient/SceneColor.h @@ -2,170 +2,165 @@ #define SCENE_COLOR_H #include "NiColor.h" +#include #include -#include -class SceneColor { -public: - SceneColor() { - TEMPLATE_COLORS.resize(146); +namespace SceneColor { + // these are not random values, they are the actual template colors used by the game + static constexpr std::array TEMPLATE_COLORS = {{ + { 0.5019608f, 0.5019608f, 0.5019608f }, + { 1.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f }, + { 1.0f, 1.0f, 0.0f }, + { 1.0f, 0.0f, 1.0f }, + { 0.0f, 1.0f, 1.0f }, + { 0.5019608f, 0.0f, 1.0f }, + { 1.0f, 0.5019608f, 0.0f }, + { 1.0f, 0.5019608f, 0.5019608f }, + { 0.5019608f, 0.2509804f, 0.0f }, + { 0.5019608f, 0.0f, 0.2509804f }, + { 0.0f, 0.5019608f, 0.2509804f }, + { 0.2509804f, 0.0f, 0.5019608f }, + { 0.8745098f, 0.0f, 0.2509804f }, + { 0.2509804f, 0.8745098f, 0.5019608f }, + { 1.0f, 0.7490196f, 0.0f }, + { 1.0f, 0.2509804f, 0.0627451f }, + { 0.2509804f, 0.0f, 0.8745098f }, + { 0.7490196f, 0.0627451f, 0.0627451f }, + { 0.0627451f, 0.7490196f, 0.0627451f }, + { 1.0f, 0.5019608f, 1.0f }, + { 0.9372549f, 0.8705882f, 0.8039216f }, + { 0.8039216f, 0.5843138f, 0.4588235f }, + { 0.9921569f, 0.8509804f, 0.7098039f }, + { 0.4705882f, 0.8588235f, 0.8862745f }, + { 0.5294118f, 0.6627451f, 0.4196078f }, + { 1.0f, 0.6431373f, 0.454902f }, + { 0.9803922f, 0.9058824f, 0.7098039f }, + { 0.6235294f, 0.5058824f, 0.4392157f }, + { 0.9921569f, 0.4862745f, 0.4313726f }, + { 0.0f, 0.0f, 0.0f }, + { 0.6745098f, 0.8980392f, 0.9333333f }, + { 0.1215686f, 0.4588235f, 0.9960784f }, + { 0.6352941f, 0.6352941f, 0.8156863f }, + { 0.4f, 0.6f, 0.8f }, + { 0.05098039f, 0.5960785f, 0.7294118f }, + { 0.4509804f, 0.4f, 0.7411765f }, + { 0.8705882f, 0.3647059f, 0.5137255f }, + { 0.7960784f, 0.254902f, 0.3294118f }, + { 0.7058824f, 0.4039216f, 0.3019608f }, + { 1.0f, 0.4980392f, 0.2862745f }, + { 0.9176471f, 0.4941176f, 0.3647059f }, + { 0.6901961f, 0.7176471f, 0.7764706f }, + { 1.0f, 1.0f, 0.6f }, + { 0.1098039f, 0.827451f, 0.6352941f }, + { 1.0f, 0.6666667f, 0.8f }, + { 0.8666667f, 0.2666667f, 0.572549f }, + { 0.1137255f, 0.6745098f, 0.8392157f }, + { 0.7372549f, 0.3647059f, 0.345098f }, + { 0.8666667f, 0.5803922f, 0.4588235f }, + { 0.6039216f, 0.8078431f, 0.9215686f }, + { 1.0f, 0.7372549f, 0.8509804f }, + { 0.9921569f, 0.8588235f, 0.427451f }, + { 0.1686275f, 0.4235294f, 0.7686275f }, + { 0.9372549f, 0.8039216f, 0.7215686f }, + { 0.4313726f, 0.3176471f, 0.3764706f }, + { 0.8078431f, 1.0f, 0.1137255f }, + { 0.427451f, 0.682353f, 0.5058824f }, + { 0.7647059f, 0.3921569f, 0.772549f }, + { 0.8f, 0.4f, 0.4f }, + { 0.9058824f, 0.7764706f, 0.5921569f }, + { 0.9882353f, 0.8509804f, 0.4588235f }, + { 0.6588235f, 0.8941177f, 0.627451f }, + { 0.5843138f, 0.5686275f, 0.5490196f }, + { 0.1098039f, 0.6745098f, 0.4705882f }, + { 0.06666667f, 0.3921569f, 0.7058824f }, + { 0.9411765f, 0.9098039f, 0.5686275f }, + { 1.0f, 0.1137255f, 0.8078431f }, + { 0.6980392f, 0.9254902f, 0.3647059f }, + { 0.3647059f, 0.4627451f, 0.7960784f }, + { 0.7921569f, 0.2156863f, 0.4039216f }, + { 0.2313726f, 0.6901961f, 0.5607843f }, + { 0.9882353f, 0.7058824f, 0.8352941f }, + { 1.0f, 0.9568627f, 0.3098039f }, + { 1.0f, 0.7411765f, 0.5333334f }, + { 0.9647059f, 0.3921569f, 0.6862745f }, + { 0.6666667f, 0.9411765f, 0.8196079f }, + { 0.8039216f, 0.2901961f, 0.2980392f }, + { 0.9294118f, 0.8196079f, 0.6117647f }, + { 0.5921569f, 0.6039216f, 0.6666667f }, + { 0.7843137f, 0.2196078f, 0.3529412f }, + { 0.9372549f, 0.5960785f, 0.6666667f }, + { 0.9921569f, 0.7372549f, 0.7058824f }, + { 0.1019608f, 0.282353f, 0.4627451f }, + { 0.1882353f, 0.7294118f, 0.5607843f }, + { 0.772549f, 0.2941177f, 0.5490196f }, + { 0.09803922f, 0.454902f, 0.8235294f }, + { 0.7294118f, 0.7215686f, 0.4235294f }, + { 1.0f, 0.4588235f, 0.2196078f }, + { 1.0f, 0.1686275f, 0.1686275f }, + { 0.972549f, 0.8352941f, 0.4078431f }, + { 0.9019608f, 0.6588235f, 0.8431373f }, + { 0.254902f, 0.2901961f, 0.2980392f }, + { 1.0f, 0.4313726f, 0.2901961f }, + { 0.1098039f, 0.6627451f, 0.7882353f }, + { 1.0f, 0.8117647f, 0.6705883f }, + { 0.772549f, 0.8156863f, 0.9019608f }, + { 0.9921569f, 0.8666667f, 0.9019608f }, + { 0.08235294f, 0.5019608f, 0.4705882f }, + { 0.9882353f, 0.454902f, 0.9921569f }, + { 0.9686275f, 0.5607843f, 0.654902f }, + { 0.5568628f, 0.2705882f, 0.5215687f }, + { 0.454902f, 0.2588235f, 0.7843137f }, + { 0.6156863f, 0.5058824f, 0.7294118f }, + { 1.0f, 0.2862745f, 0.4235294f }, + { 0.8392157f, 0.5411765f, 0.3490196f }, + { 0.4431373f, 0.2941177f, 0.1372549f }, + { 1.0f, 0.282353f, 0.8156863f }, + { 0.9333333f, 0.1254902f, 0.3019608f }, + { 1.0f, 0.3254902f, 0.2862745f }, + { 0.7529412f, 0.2666667f, 0.5607843f }, + { 0.1215686f, 0.8078431f, 0.7960784f }, + { 0.4705882f, 0.3176471f, 0.6627451f }, + { 1.0f, 0.6078432f, 0.6666667f }, + { 0.9882353f, 0.1568628f, 0.2784314f }, + { 0.4627451f, 1.0f, 0.4784314f }, + { 0.6235294f, 0.8862745f, 0.7490196f }, + { 0.6470588f, 0.4117647f, 0.3098039f }, + { 0.5411765f, 0.4745098f, 0.3647059f }, + { 0.2705882f, 0.8078431f, 0.6352941f }, + { 0.8039216f, 0.772549f, 0.7607843f }, + { 0.5019608f, 0.854902f, 0.9215686f }, + { 0.9254902f, 0.9176471f, 0.7450981f }, + { 1.0f, 0.8117647f, 0.282353f }, + { 0.9921569f, 0.3686275f, 0.3254902f }, + { 0.9803922f, 0.654902f, 0.4235294f }, + { 0.09411765f, 0.654902f, 0.7098039f }, + { 0.9215686f, 0.7803922f, 0.8745098f }, + { 0.9882353f, 0.5372549f, 0.6745098f }, + { 0.8588235f, 0.8431373f, 0.8235294f }, + { 0.8705882f, 0.6666667f, 0.5333334f }, + { 0.4666667f, 0.8666667f, 0.9058824f }, + { 1.0f, 1.0f, 0.4f }, + { 0.572549f, 0.4313726f, 0.682353f }, + { 0.1960784f, 0.2901961f, 0.6980392f }, + { 0.9686275f, 0.3254902f, 0.5803922f }, + { 1.0f, 0.627451f, 0.5372549f }, + { 0.5607843f, 0.3137255f, 0.6156863f }, + { 1.0f, 1.0f, 1.0f }, + { 0.6352941f, 0.6784314f, 0.8156863f }, + { 0.9882353f, 0.4235294f, 0.5215687f }, + { 0.8039216f, 0.6431373f, 0.8705882f }, + { 0.9882353f, 0.9098039f, 0.5137255f }, + { 0.772549f, 0.8901961f, 0.5176471f }, + { 1.0f, 0.682353f, 0.2588235f }, + }}; - // these are not random values, they are the actual template colors used by the game - TEMPLATE_COLORS[0] = NiColor(0.5019608f, 0.5019608f, 0.5019608f); - TEMPLATE_COLORS[1] = NiColor(1.0f, 0.0f, 0.0f); - TEMPLATE_COLORS[2] = NiColor(0.0f, 1.0f, 0.0f); - TEMPLATE_COLORS[3] = NiColor(0.0f, 0.0f, 1.0f); - TEMPLATE_COLORS[4] = NiColor(1.0f, 1.0f, 0.0f); - TEMPLATE_COLORS[5] = NiColor(1.0f, 0.0f, 1.0f); - TEMPLATE_COLORS[6] = NiColor(0.0f, 1.0f, 1.0f); - TEMPLATE_COLORS[7] = NiColor(0.5019608f, 0.0f, 1.0f); - TEMPLATE_COLORS[8] = NiColor(1.0f, 0.5019608f, 0.0f); - TEMPLATE_COLORS[9] = NiColor(1.0f, 0.5019608f, 0.5019608f); - TEMPLATE_COLORS[10] = NiColor(0.5019608f, 0.2509804f, 0.0f); - TEMPLATE_COLORS[11] = NiColor(0.5019608f, 0.0f, 0.2509804f); - TEMPLATE_COLORS[12] = NiColor(0.0f, 0.5019608f, 0.2509804f); - TEMPLATE_COLORS[13] = NiColor(0.2509804f, 0.0f, 0.5019608f); - TEMPLATE_COLORS[14] = NiColor(0.8745098f, 0.0f, 0.2509804f); - TEMPLATE_COLORS[15] = NiColor(0.2509804f, 0.8745098f, 0.5019608f); - TEMPLATE_COLORS[16] = NiColor(1.0f, 0.7490196f, 0.0f); - TEMPLATE_COLORS[17] = NiColor(1.0f, 0.2509804f, 0.0627451f); - TEMPLATE_COLORS[18] = NiColor(0.2509804f, 0.0f, 0.8745098f); - TEMPLATE_COLORS[19] = NiColor(0.7490196f, 0.0627451f, 0.0627451f); - TEMPLATE_COLORS[20] = NiColor(0.0627451f, 0.7490196f, 0.0627451f); - TEMPLATE_COLORS[21] = NiColor(1.0f, 0.5019608f, 1.0f); - TEMPLATE_COLORS[22] = NiColor(0.9372549f, 0.8705882f, 0.8039216f); - TEMPLATE_COLORS[23] = NiColor(0.8039216f, 0.5843138f, 0.4588235f); - TEMPLATE_COLORS[24] = NiColor(0.9921569f, 0.8509804f, 0.7098039f); - TEMPLATE_COLORS[25] = NiColor(0.4705882f, 0.8588235f, 0.8862745f); - TEMPLATE_COLORS[26] = NiColor(0.5294118f, 0.6627451f, 0.4196078f); - TEMPLATE_COLORS[27] = NiColor(1.0f, 0.6431373f, 0.454902f); - TEMPLATE_COLORS[28] = NiColor(0.9803922f, 0.9058824f, 0.7098039f); - TEMPLATE_COLORS[29] = NiColor(0.6235294f, 0.5058824f, 0.4392157f); - TEMPLATE_COLORS[30] = NiColor(0.9921569f, 0.4862745f, 0.4313726f); - TEMPLATE_COLORS[31] = NiColor(0.0f, 0.0f, 0.0f); - TEMPLATE_COLORS[32] = NiColor(0.6745098f, 0.8980392f, 0.9333333f); - TEMPLATE_COLORS[33] = NiColor(0.1215686f, 0.4588235f, 0.9960784f); - TEMPLATE_COLORS[34] = NiColor(0.6352941f, 0.6352941f, 0.8156863f); - TEMPLATE_COLORS[35] = NiColor(0.4f, 0.6f, 0.8f); - TEMPLATE_COLORS[36] = NiColor(0.05098039f, 0.5960785f, 0.7294118f); - TEMPLATE_COLORS[37] = NiColor(0.4509804f, 0.4f, 0.7411765f); - TEMPLATE_COLORS[38] = NiColor(0.8705882f, 0.3647059f, 0.5137255f); - TEMPLATE_COLORS[39] = NiColor(0.7960784f, 0.254902f, 0.3294118f); - TEMPLATE_COLORS[40] = NiColor(0.7058824f, 0.4039216f, 0.3019608f); - TEMPLATE_COLORS[41] = NiColor(1.0f, 0.4980392f, 0.2862745f); - TEMPLATE_COLORS[42] = NiColor(0.9176471f, 0.4941176f, 0.3647059f); - TEMPLATE_COLORS[43] = NiColor(0.6901961f, 0.7176471f, 0.7764706f); - TEMPLATE_COLORS[44] = NiColor(1.0f, 1.0f, 0.6f); - TEMPLATE_COLORS[45] = NiColor(0.1098039f, 0.827451f, 0.6352941f); - TEMPLATE_COLORS[46] = NiColor(1.0f, 0.6666667f, 0.8f); - TEMPLATE_COLORS[47] = NiColor(0.8666667f, 0.2666667f, 0.572549f); - TEMPLATE_COLORS[48] = NiColor(0.1137255f, 0.6745098f, 0.8392157f); - TEMPLATE_COLORS[49] = NiColor(0.7372549f, 0.3647059f, 0.345098f); - TEMPLATE_COLORS[50] = NiColor(0.8666667f, 0.5803922f, 0.4588235f); - TEMPLATE_COLORS[51] = NiColor(0.6039216f, 0.8078431f, 0.9215686f); - TEMPLATE_COLORS[52] = NiColor(1.0f, 0.7372549f, 0.8509804f); - TEMPLATE_COLORS[53] = NiColor(0.9921569f, 0.8588235f, 0.427451f); - TEMPLATE_COLORS[54] = NiColor(0.1686275f, 0.4235294f, 0.7686275f); - TEMPLATE_COLORS[55] = NiColor(0.9372549f, 0.8039216f, 0.7215686f); - TEMPLATE_COLORS[56] = NiColor(0.4313726f, 0.3176471f, 0.3764706f); - TEMPLATE_COLORS[57] = NiColor(0.8078431f, 1.0f, 0.1137255f); - TEMPLATE_COLORS[58] = NiColor(0.427451f, 0.682353f, 0.5058824f); - TEMPLATE_COLORS[59] = NiColor(0.7647059f, 0.3921569f, 0.772549f); - TEMPLATE_COLORS[60] = NiColor(0.8f, 0.4f, 0.4f); - TEMPLATE_COLORS[61] = NiColor(0.9058824f, 0.7764706f, 0.5921569f); - TEMPLATE_COLORS[62] = NiColor(0.9882353f, 0.8509804f, 0.4588235f); - TEMPLATE_COLORS[63] = NiColor(0.6588235f, 0.8941177f, 0.627451f); - TEMPLATE_COLORS[64] = NiColor(0.5843138f, 0.5686275f, 0.5490196f); - TEMPLATE_COLORS[65] = NiColor(0.1098039f, 0.6745098f, 0.4705882f); - TEMPLATE_COLORS[66] = NiColor(0.06666667f, 0.3921569f, 0.7058824f); - TEMPLATE_COLORS[67] = NiColor(0.9411765f, 0.9098039f, 0.5686275f); - TEMPLATE_COLORS[68] = NiColor(1.0f, 0.1137255f, 0.8078431f); - TEMPLATE_COLORS[69] = NiColor(0.6980392f, 0.9254902f, 0.3647059f); - TEMPLATE_COLORS[70] = NiColor(0.3647059f, 0.4627451f, 0.7960784f); - TEMPLATE_COLORS[71] = NiColor(0.7921569f, 0.2156863f, 0.4039216f); - TEMPLATE_COLORS[72] = NiColor(0.2313726f, 0.6901961f, 0.5607843f); - TEMPLATE_COLORS[73] = NiColor(0.9882353f, 0.7058824f, 0.8352941f); - TEMPLATE_COLORS[74] = NiColor(1.0f, 0.9568627f, 0.3098039f); - TEMPLATE_COLORS[75] = NiColor(1.0f, 0.7411765f, 0.5333334f); - TEMPLATE_COLORS[76] = NiColor(0.9647059f, 0.3921569f, 0.6862745f); - TEMPLATE_COLORS[77] = NiColor(0.6666667f, 0.9411765f, 0.8196079f); - TEMPLATE_COLORS[78] = NiColor(0.8039216f, 0.2901961f, 0.2980392f); - TEMPLATE_COLORS[79] = NiColor(0.9294118f, 0.8196079f, 0.6117647f); - TEMPLATE_COLORS[80] = NiColor(0.5921569f, 0.6039216f, 0.6666667f); - TEMPLATE_COLORS[81] = NiColor(0.7843137f, 0.2196078f, 0.3529412f); - TEMPLATE_COLORS[82] = NiColor(0.9372549f, 0.5960785f, 0.6666667f); - TEMPLATE_COLORS[83] = NiColor(0.9921569f, 0.7372549f, 0.7058824f); - TEMPLATE_COLORS[84] = NiColor(0.1019608f, 0.282353f, 0.4627451f); - TEMPLATE_COLORS[85] = NiColor(0.1882353f, 0.7294118f, 0.5607843f); - TEMPLATE_COLORS[86] = NiColor(0.772549f, 0.2941177f, 0.5490196f); - TEMPLATE_COLORS[87] = NiColor(0.09803922f, 0.454902f, 0.8235294f); - TEMPLATE_COLORS[88] = NiColor(0.7294118f, 0.7215686f, 0.4235294f); - TEMPLATE_COLORS[89] = NiColor(1.0f, 0.4588235f, 0.2196078f); - TEMPLATE_COLORS[90] = NiColor(1.0f, 0.1686275f, 0.1686275f); - TEMPLATE_COLORS[91] = NiColor(0.972549f, 0.8352941f, 0.4078431f); - TEMPLATE_COLORS[92] = NiColor(0.9019608f, 0.6588235f, 0.8431373f); - TEMPLATE_COLORS[93] = NiColor(0.254902f, 0.2901961f, 0.2980392f); - TEMPLATE_COLORS[94] = NiColor(1.0f, 0.4313726f, 0.2901961f); - TEMPLATE_COLORS[95] = NiColor(0.1098039f, 0.6627451f, 0.7882353f); - TEMPLATE_COLORS[96] = NiColor(1.0f, 0.8117647f, 0.6705883f); - TEMPLATE_COLORS[97] = NiColor(0.772549f, 0.8156863f, 0.9019608f); - TEMPLATE_COLORS[98] = NiColor(0.9921569f, 0.8666667f, 0.9019608f); - TEMPLATE_COLORS[99] = NiColor(0.08235294f, 0.5019608f, 0.4705882f); - TEMPLATE_COLORS[100] = NiColor(0.9882353f, 0.454902f, 0.9921569f); - TEMPLATE_COLORS[101] = NiColor(0.9686275f, 0.5607843f, 0.654902f); - TEMPLATE_COLORS[102] = NiColor(0.5568628f, 0.2705882f, 0.5215687f); - TEMPLATE_COLORS[103] = NiColor(0.454902f, 0.2588235f, 0.7843137f); - TEMPLATE_COLORS[104] = NiColor(0.6156863f, 0.5058824f, 0.7294118f); - TEMPLATE_COLORS[105] = NiColor(1.0f, 0.2862745f, 0.4235294f); - TEMPLATE_COLORS[106] = NiColor(0.8392157f, 0.5411765f, 0.3490196f); - TEMPLATE_COLORS[107] = NiColor(0.4431373f, 0.2941177f, 0.1372549f); - TEMPLATE_COLORS[108] = NiColor(1.0f, 0.282353f, 0.8156863f); - TEMPLATE_COLORS[109] = NiColor(0.9333333f, 0.1254902f, 0.3019608f); - TEMPLATE_COLORS[110] = NiColor(1.0f, 0.3254902f, 0.2862745f); - TEMPLATE_COLORS[111] = NiColor(0.7529412f, 0.2666667f, 0.5607843f); - TEMPLATE_COLORS[112] = NiColor(0.1215686f, 0.8078431f, 0.7960784f); - TEMPLATE_COLORS[113] = NiColor(0.4705882f, 0.3176471f, 0.6627451f); - TEMPLATE_COLORS[114] = NiColor(1.0f, 0.6078432f, 0.6666667f); - TEMPLATE_COLORS[115] = NiColor(0.9882353f, 0.1568628f, 0.2784314f); - TEMPLATE_COLORS[116] = NiColor(0.4627451f, 1.0f, 0.4784314f); - TEMPLATE_COLORS[117] = NiColor(0.6235294f, 0.8862745f, 0.7490196f); - TEMPLATE_COLORS[118] = NiColor(0.6470588f, 0.4117647f, 0.3098039f); - TEMPLATE_COLORS[119] = NiColor(0.5411765f, 0.4745098f, 0.3647059f); - TEMPLATE_COLORS[120] = NiColor(0.2705882f, 0.8078431f, 0.6352941f); - TEMPLATE_COLORS[121] = NiColor(0.8039216f, 0.772549f, 0.7607843f); - TEMPLATE_COLORS[122] = NiColor(0.5019608f, 0.854902f, 0.9215686f); - TEMPLATE_COLORS[123] = NiColor(0.9254902f, 0.9176471f, 0.7450981f); - TEMPLATE_COLORS[124] = NiColor(1.0f, 0.8117647f, 0.282353f); - TEMPLATE_COLORS[125] = NiColor(0.9921569f, 0.3686275f, 0.3254902f); - TEMPLATE_COLORS[126] = NiColor(0.9803922f, 0.654902f, 0.4235294f); - TEMPLATE_COLORS[127] = NiColor(0.09411765f, 0.654902f, 0.7098039f); - TEMPLATE_COLORS[128] = NiColor(0.9215686f, 0.7803922f, 0.8745098f); - TEMPLATE_COLORS[129] = NiColor(0.9882353f, 0.5372549f, 0.6745098f); - TEMPLATE_COLORS[130] = NiColor(0.8588235f, 0.8431373f, 0.8235294f); - TEMPLATE_COLORS[131] = NiColor(0.8705882f, 0.6666667f, 0.5333334f); - TEMPLATE_COLORS[132] = NiColor(0.4666667f, 0.8666667f, 0.9058824f); - TEMPLATE_COLORS[133] = NiColor(1.0f, 1.0f, 0.4f); - TEMPLATE_COLORS[134] = NiColor(0.572549f, 0.4313726f, 0.682353f); - TEMPLATE_COLORS[135] = NiColor(0.1960784f, 0.2901961f, 0.6980392f); - TEMPLATE_COLORS[136] = NiColor(0.9686275f, 0.3254902f, 0.5803922f); - TEMPLATE_COLORS[137] = NiColor(1.0f, 0.627451f, 0.5372549f); - TEMPLATE_COLORS[138] = NiColor(0.5607843f, 0.3137255f, 0.6156863f); - TEMPLATE_COLORS[139] = NiColor(1.0f, 1.0f, 1.0f); - TEMPLATE_COLORS[140] = NiColor(0.6352941f, 0.6784314f, 0.8156863f); - TEMPLATE_COLORS[141] = NiColor(0.9882353f, 0.4235294f, 0.5215687f); - TEMPLATE_COLORS[142] = NiColor(0.8039216f, 0.6431373f, 0.8705882f); - TEMPLATE_COLORS[143] = NiColor(0.9882353f, 0.9098039f, 0.5137255f); - TEMPLATE_COLORS[144] = NiColor(0.772549f, 0.8901961f, 0.5176471f); - TEMPLATE_COLORS[145] = NiColor(1.0f, 0.682353f, 0.2588235f); + static constexpr NiColor FALLBACK_COLOR{ 1.0f, 1.0f, 1.0f }; + + inline const NiColor& Get(uint8_t index) { + return (index < TEMPLATE_COLORS.size()) ? TEMPLATE_COLORS[index] : FALLBACK_COLOR; } - - const NiColor& Get(uint8_t index) const { - return (index < 146) ? TEMPLATE_COLORS[index] : FALLBACK_COLOR; - } - -private: - const NiColor FALLBACK_COLOR = NiColor(1.0f, 1.0f, 1.0f); - std::vector TEMPLATE_COLORS; -}; +} // namespace SceneColor #endif // SCENE_COLOR_H diff --git a/dGame/dUtilities/SlashCommands/DEVGMCommands.cpp b/dGame/dUtilities/SlashCommands/DEVGMCommands.cpp index 89142ade..e47bb25f 100644 --- a/dGame/dUtilities/SlashCommands/DEVGMCommands.cpp +++ b/dGame/dUtilities/SlashCommands/DEVGMCommands.cpp @@ -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(i) / static_cast(chunk.width - 1)) * static_cast(chunk.colorMapResolution - 1); + const float sceneMapJ = (static_cast(j) / static_cast(chunk.height - 1)) * static_cast(chunk.colorMapResolution - 1); + const uint32_t sceneI = std::min(static_cast(sceneMapI), chunk.colorMapResolution - 1); const uint32_t sceneJ = std::min(static_cast(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(i) + (chunk.offsetX / chunk.scaleFactor)) * chunk.scaleFactor; + const float worldY = y; + const float worldZ = (static_cast(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(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 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(i) / static_cast(chunk.width - 1)) * static_cast(chunk.colorMapResolution - 1); + const float sceneMapJ = (static_cast(j) / static_cast(chunk.height - 1)) * static_cast(chunk.colorMapResolution - 1); + const uint32_t sceneI = std::min(static_cast(sceneMapI), chunk.colorMapResolution - 1); const uint32_t sceneJ = std::min(static_cast(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(i) + (chunk.offsetX / chunk.scaleFactor)) * chunk.scaleFactor; + const float worldY = y; + const float worldZ = (static_cast(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(u"SpawnedFromSlashCommand", true) }; + info.settings.Insert(u"SpawnedFromSlashCommand", true); Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr); if (newEntity != nullptr) { diff --git a/dZoneManager/Raw.cpp b/dZoneManager/Raw.cpp index ce4e2485..2b7e5090 100644 --- a/dZoneManager/Raw.cpp +++ b/dZoneManager/Raw.cpp @@ -58,20 +58,22 @@ namespace Raw { */ static bool ReadChunk(std::istream& stream, Chunk& chunk, uint16_t version) { try { - // Read basic chunk info - BinaryIO::BinaryRead(stream, chunk.id); - if (stream.fail()) { - return false; - } + // Read basic chunk info + BinaryIO::BinaryRead(stream, chunk.id); + if (stream.fail()) { + return false; + } - BinaryIO::BinaryRead(stream, chunk.width); - BinaryIO::BinaryRead(stream, chunk.height); - BinaryIO::BinaryRead(stream, chunk.offsetX); - BinaryIO::BinaryRead(stream, chunk.offsetZ); + BinaryIO::BinaryRead(stream, chunk.width); + BinaryIO::BinaryRead(stream, chunk.height); + BinaryIO::BinaryRead(stream, chunk.offsetX); + BinaryIO::BinaryRead(stream, chunk.offsetZ); - if (stream.fail()) { - return false; - } // For version < 32, shader ID comes before texture IDs + if (stream.fail()) { + return false; + } + + // For version < 32, shader ID comes before texture IDs if (version < 32) { BinaryIO::BinaryRead(stream, chunk.shaderId); } @@ -344,30 +346,28 @@ namespace Raw { } // Calculate terrain bounds from all chunks - if (!outRaw.chunks.empty()) { - outRaw.minBoundsX = std::numeric_limits::max(); - outRaw.minBoundsZ = std::numeric_limits::max(); - outRaw.maxBoundsX = std::numeric_limits::lowest(); - outRaw.maxBoundsZ = std::numeric_limits::lowest(); - - for (const auto& chunk : outRaw.chunks) { - // Calculate chunk bounds - const float chunkMinX = chunk.offsetX; - const float chunkMinZ = chunk.offsetZ; - const float chunkMaxX = chunkMinX + (chunk.width * chunk.scaleFactor); - const float chunkMaxZ = chunkMinZ + (chunk.height * chunk.scaleFactor); - - // Update overall bounds - outRaw.minBoundsX = std::min(outRaw.minBoundsX, chunkMinX); - outRaw.minBoundsZ = std::min(outRaw.minBoundsZ, chunkMinZ); - outRaw.maxBoundsX = std::max(outRaw.maxBoundsX, chunkMaxX); - outRaw.maxBoundsZ = std::max(outRaw.maxBoundsZ, chunkMaxZ); + if (!outRaw.chunks.empty()) { + outRaw.minBoundsX = std::numeric_limits::max(); + outRaw.minBoundsZ = std::numeric_limits::max(); + outRaw.maxBoundsX = std::numeric_limits::lowest(); + outRaw.maxBoundsZ = std::numeric_limits::lowest(); + + for (const auto& chunk : outRaw.chunks) { + const float chunkMinX = chunk.offsetX; + const float chunkMinZ = chunk.offsetZ; + const float chunkMaxX = chunkMinX + (chunk.width * chunk.scaleFactor); + const float chunkMaxZ = chunkMinZ + (chunk.height * chunk.scaleFactor); + + outRaw.minBoundsX = std::min(outRaw.minBoundsX, chunkMinX); + outRaw.minBoundsZ = std::min(outRaw.minBoundsZ, chunkMinZ); + outRaw.maxBoundsX = std::max(outRaw.maxBoundsX, chunkMaxX); + outRaw.maxBoundsZ = std::max(outRaw.maxBoundsZ, chunkMaxZ); + } + LOG("Raw terrain bounds: X[%.2f, %.2f], Z[%.2f, %.2f]", + outRaw.minBoundsX, outRaw.maxBoundsX, outRaw.minBoundsZ, outRaw.maxBoundsZ); + } } - LOG("Raw terrain bounds: X[%.2f, %.2f], Z[%.2f, %.2f]", - outRaw.minBoundsX, outRaw.maxBoundsX, outRaw.minBoundsZ, outRaw.maxBoundsZ); - } - } - return true; + return true; } catch (const std::exception&) { return false; } @@ -407,29 +407,23 @@ namespace Raw { const float y = chunk.heightMap[heightIndex]; - // Calculate world position - 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(i) + (chunk.offsetX / chunk.scaleFactor)) * chunk.scaleFactor; + const float worldY = y; + const float worldZ = (static_cast(j) + (chunk.offsetZ / chunk.scaleFactor)) * chunk.scaleFactor; const NiPoint3 worldPos(worldX, worldY, worldZ); - // Get scene ID at this position - // Map heightmap position to scene map position - // The scene map is colorMapResolution x colorMapResolution - // We need to map from heightmap coordinates (i, j) to scene map coordinates - 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(i) / static_cast(chunk.width - 1)) * static_cast(chunk.colorMapResolution - 1); + const float sceneMapJ = (static_cast(j) / static_cast(chunk.height - 1)) * static_cast(chunk.colorMapResolution - 1); + const uint32_t sceneI = std::min(static_cast(sceneMapI), chunk.colorMapResolution - 1); const uint32_t sceneJ = std::min(static_cast(sceneMapJ), chunk.colorMapResolution - 1); - // Scene map uses the same indexing pattern as heightmap: row * width + col const uint32_t sceneIndex = sceneI * chunk.colorMapResolution + sceneJ; uint8_t sceneID = 0; if (sceneIndex < chunk.sceneMap.size()) { sceneID = chunk.sceneMap[sceneIndex]; - } + } outMesh.vertices.emplace_back(worldPos, sceneID); if (i > 0 && j > 0) { const uint32_t currentVert = vertexOffset + chunk.width * i + j; @@ -450,49 +444,38 @@ namespace Raw { } } - vertexOffset += chunk.width * chunk.height; + vertexOffset += chunk.width * chunk.height; + } } -} -bool WriteTerrainMeshToOBJ(const TerrainMesh& mesh, const std::string& path) { - try { - std::ofstream file(path); - if (!file.is_open()) { - LOG("Failed to open OBJ file for writing: %s", path.c_str()); + bool WriteTerrainMeshToOBJ(const TerrainMesh& mesh, const std::string& path) { + try { + std::ofstream file(path); + if (!file.is_open()) { + LOG("Failed to open OBJ file for writing: %s", path.c_str()); + return false; + } + + for (const auto& v : mesh.vertices) { + const NiColor& color = SceneColor::Get(v.sceneID); + file << "v " << v.position.x << ' ' << v.position.y << ' ' << v.position.z + << ' ' << color.m_Red << ' ' << color.m_Green << ' ' << color.m_Blue << '\n'; + } + + for (size_t i = 0; i < mesh.triangles.size(); i += 3) { + file << "f " << (mesh.triangles[i] + 1) << ' ' + << (mesh.triangles[i + 1] + 1) << ' ' + << (mesh.triangles[i + 2] + 1) << '\n'; + } + + file.close(); + LOG("Successfully wrote terrain mesh to OBJ: %s (%zu vertices, %zu triangles)", + path.c_str(), mesh.vertices.size(), mesh.triangles.size() / 3); + return true; + } catch (const std::exception& e) { + LOG("Exception while writing OBJ file: %s", e.what()); return false; } - - // Create instance of SceneColor for color lookup - SceneColor sceneColor; - - // Write vertices with colors - // OBJ format supports vertex colors as: v x y z r g b - for (const auto& v : mesh.vertices) { - file << "v " << v.position.x << ' ' << v.position.y << ' ' << v.position.z; - - uint8_t sceneID = v.sceneID; - - const NiColor& color = sceneColor.Get(sceneID); - file << ' ' << color.m_Red << ' ' << color.m_Green << ' ' << color.m_Blue; - file << '\n'; - } - - // Write faces (triangles) - for (size_t i = 0; i < mesh.triangles.size(); i += 3) { - // OBJ indices are 1-based - file << "f " << (mesh.triangles[i] + 1) << ' ' - << (mesh.triangles[i + 1] + 1) << ' ' - << (mesh.triangles[i + 2] + 1) << '\n'; - } - - file.close(); - LOG("Successfully wrote terrain mesh to OBJ: %s (%zu vertices, %zu triangles)", - path.c_str(), mesh.vertices.size(), mesh.triangles.size() / 3); - return true; - } catch (const std::exception& e) { - LOG("Exception while writing OBJ file: %s", e.what()); - return false; } -} } // namespace Raw diff --git a/dZoneManager/Zone.cpp b/dZoneManager/Zone.cpp index 07f7f9d0..94e59005 100644 --- a/dZoneManager/Zone.cpp +++ b/dZoneManager/Zone.cpp @@ -110,7 +110,7 @@ void Zone::LoadZoneIntoMemory() { // Generate terrain mesh Raw::GenerateTerrainMesh(m_Raw, m_TerrainMesh); - LOG("Generated terrain mesh with %llu vertices and %llu triangles", m_TerrainMesh.vertices.size(), m_TerrainMesh.triangles.size() / 3); + LOG("Generated terrain mesh with %zu vertices and %zu triangles", m_TerrainMesh.vertices.size(), m_TerrainMesh.triangles.size() / 3); // Write to OBJ std::string objFileName = "terrain_" + std::to_string(m_ZoneID.GetMapID()) + ".obj"; diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index 29bf85f0..6e847470 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -10,10 +10,11 @@ #include "VanityUtilities.h" #include "WorldConfig.h" #include "CDZoneTableTable.h" +#include #include #include +#include #include "eObjectBits.h" -#include "CDZoneTableTable.h" #include "AssetManager.h" #include @@ -331,20 +332,11 @@ LWOSCENEID dZoneManager::GetSceneIDFromPosition(const NiPoint3& position) const if (heightI >= 0.0f && heightI < static_cast(chunk.width) && heightJ >= 0.0f && heightJ < static_cast(chunk.height)) { - // Map heightmap position to scene map position (same as GenerateTerrainMesh) - const float sceneMapI = (chunk.width > 1) - ? (heightI / static_cast(chunk.width - 1)) * static_cast(chunk.colorMapResolution - 1) - : 0.0f; - const float sceneMapJ = (chunk.height > 1) - ? (heightJ / static_cast(chunk.height - 1)) * static_cast(chunk.colorMapResolution - 1) - : 0.0f; + const float sceneMapI = (heightI / static_cast(chunk.width - 1)) * static_cast(chunk.colorMapResolution - 1); + const float sceneMapJ = (heightJ / static_cast(chunk.height - 1)) * static_cast(chunk.colorMapResolution - 1); - const uint32_t sceneI = (chunk.colorMapResolution > 0) - ? std::min(static_cast(sceneMapI), chunk.colorMapResolution - 1) - : 0; - const uint32_t sceneJ = (chunk.colorMapResolution > 0) - ? std::min(static_cast(sceneMapJ), chunk.colorMapResolution - 1) - : 0; + const uint32_t sceneI = std::min(static_cast(sceneMapI), chunk.colorMapResolution - 1); + const uint32_t sceneJ = std::min(static_cast(sceneMapJ), chunk.colorMapResolution - 1); // Scene map uses the same indexing pattern as heightmap: row * width + col const uint32_t sceneIndex = sceneI * chunk.colorMapResolution + sceneJ;