Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 9 additions & 17 deletions Server/mods/deathmatch/logic/CVehicle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,28 +304,20 @@ bool CVehicle::ReadSpecialData(const int iLine)
char szTemp[256];
if (GetCustomDataString("color", szTemp, 256, true))
{
uchar ucValues[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
char* sz1 = strtok(szTemp, ", ");
if (sz1)
ucValues[0] = atoi(sz1);
std::vector<SColorRGBA> vecColors;
unsigned char ucCount;

int i;
for (i = 1; i < 12; i++)
if (ColorStringToRGB(szTemp, SColorRGBA(0, 0, 0, 0), vecColors, ucCount))
{
char* szn = strtok(NULL, ", ");
if (!szn)
break;
ucValues[i] = atoi(szn);
}

if (i == 3 || i == 6 || i == 9 || i == 12)
{
m_Color.SetRGBColors(SColorRGBA(ucValues[0], ucValues[1], ucValues[2], 0), SColorRGBA(ucValues[3], ucValues[4], ucValues[5], 0),
SColorRGBA(ucValues[6], ucValues[7], ucValues[8], 0), SColorRGBA(ucValues[9], ucValues[10], ucValues[11], 0));
if (ucCount % 3 == 0)
m_Color.SetRGBColors(vecColors[0], vecColors[1], vecColors[2], vecColors[3]);
else
m_Color.SetPaletteColors(vecColors[0].R, vecColors[0].G, vecColors[0].B, vecColors[1].R);
}
else
{
m_Color.SetPaletteColors(ucValues[0], ucValues[1], ucValues[2], ucValues[3]);
CLogger::ErrorPrintf("Bad 'color' value specified in <vehicle> (line %u)\n", iLine);
return false;
}
}

Expand Down
120 changes: 111 additions & 9 deletions Server/mods/deathmatch/logic/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,18 +535,120 @@ bool XMLColorToInt(const char* szColor, unsigned long& ulColor)

bool XMLColorToInt(const char* szColor, unsigned char& ucRed, unsigned char& ucGreen, unsigned char& ucBlue, unsigned char& ucAlpha)
{
// Convert it to an integer first
unsigned long ulColor;
if (!XMLColorToInt(szColor, ulColor))
{
// If we're empty, let's just stop right away
if (!szColor || strlen(szColor) == 0)
return false;

std::vector<SColorRGBA> vecColors;
unsigned char ucCount;

if (ColorStringToRGBA(szColor, SColorRGBA(ucRed, ucGreen, ucBlue, ucAlpha), vecColors, ucCount))
{
ucRed = vecColors[0].R;
ucGreen = vecColors[0].G;
ucBlue = vecColors[0].B;
ucAlpha = vecColors[0].A;

return true;
}

return false;
}

bool ColorStringToRGBA(const char* szColor, SColorRGBA defaultColor, std::vector<SColorRGBA>& vecColors, unsigned char& ucCount, bool bIgnoreAlpha)
{
std::stringstream ss(szColor);
SColorRGBA color = defaultColor;
bool bPreviousWasHex = false;
unsigned int uiRGBAIndex = 0;
unsigned long ulColor;
unsigned char ucValue;
unsigned char ucLength = bIgnoreAlpha ? 3 : 4;

while (ss.good())
{
// Ambiguous value before a comma
SString strValue;
getline(ss, strValue, ',');

// Remove spaces
ReplaceOccurrencesInString(strValue, " ", "");

// Is the value looking like a hexadecimal?
if (strValue[0] == '#')
{
// Try converting it to an integer
if (XMLColorToInt(strValue.c_str(), ulColor))
{
// If a previous RGBA wasn't finished, let's finish it now
if (!bPreviousWasHex && uiRGBAIndex != 0)
{
vecColors.push_back(color);
ucCount += ucLength - uiRGBAIndex;
color = defaultColor;
}

color.R = static_cast<unsigned char>(ulColor);
color.G = static_cast<unsigned char>(ulColor >> 8);
color.B = static_cast<unsigned char>(ulColor >> 16);

if (!bIgnoreAlpha)
color.A = static_cast<unsigned char>(ulColor >> 24);

bPreviousWasHex = true;
ucCount += ucLength;
}
else
return false;
}
// It looks like we have an empty value, let's skip the value but treat it as RGB
else if (strValue.empty())
{
if (bPreviousWasHex || uiRGBAIndex % ucLength == 0)
{
bPreviousWasHex = false;
uiRGBAIndex = 0;
}

uiRGBAIndex++;
ucCount++;

if (uiRGBAIndex % ucLength != 0 && ss.good())
continue;
}
// It looks like a plain number so let's treat it as a RGBA value
else if (strValue.find_first_not_of("0123456789") == std::string::npos)
{
ucValue = atoi(strValue.c_str());

if (bPreviousWasHex || uiRGBAIndex % ucLength == 0)
{
color.R = ucValue;
bPreviousWasHex = false;
uiRGBAIndex = 0;
}
else if (uiRGBAIndex % ucLength == 1)
color.G = ucValue;
else if (uiRGBAIndex % ucLength == 2)
color.B = ucValue;
else if (uiRGBAIndex % ucLength == 3)
color.A = ucValue;

uiRGBAIndex++;
ucCount++;

if (uiRGBAIndex % ucLength != 0 && ss.good())
continue;
}
else
return false;

// We have a color, so let's push it
vecColors.push_back(color);
color = defaultColor;
uiRGBAIndex = 0;
}

// Convert it to red, green, blue and alpha
ucRed = static_cast<unsigned char>(ulColor);
ucGreen = static_cast<unsigned char>(ulColor >> 8);
ucBlue = static_cast<unsigned char>(ulColor >> 16);
ucAlpha = static_cast<unsigned char>(ulColor >> 24);
return true;
}

Expand Down
5 changes: 5 additions & 0 deletions Server/mods/deathmatch/logic/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ bool IsValidOrganizationPath(const char* szPath);
unsigned int HexToInt(const char* szHex);
bool XMLColorToInt(const char* szColor, unsigned long& ulColor);
bool XMLColorToInt(const char* szColor, unsigned char& ucRed, unsigned char& ucGreen, unsigned char& ucBlue, unsigned char& ucAlpha);
bool ColorStringToRGBA(const char* szColor, SColorRGBA defaultColor, std::vector<SColorRGBA>& vecColors, unsigned char& ucCount, bool bIgnoreAlpha = false);
inline bool ColorStringToRGB(const char* szColor, SColorRGBA defaultColor, std::vector<SColorRGBA>& vecColors, unsigned char& ucCount)
{
return ColorStringToRGBA(szColor, defaultColor, vecColors, ucCount, true);
}

inline float WrapAround(float fValue, float fHigh)
{
Expand Down