Refactor ColorDescriptionService to improve skin and hair color handling by introducing new methods for determining colors based on gene definitions. Add constants for color keywords to enhance readability and maintainability. Update AIImages.dll to reflect these changes.
All checks were successful
SonarQube Analysis / Build and analyze (push) Successful in 1m51s

This commit is contained in:
Leonid Pershin
2025-11-01 09:18:36 +03:00
parent 30010078b4
commit a9dd7910a0
2 changed files with 217 additions and 124 deletions

View File

@@ -11,6 +11,12 @@ namespace AIImages.Services
/// </summary>
public static class ColorDescriptionService
{
// Константы для повторяющихся строковых литералов
private const string Green = "Green";
private const string Orange = "Orange";
private const string Black = "Black";
private const string White = "White";
/// <summary>
/// Получает текстовое описание цвета волос
/// Сначала проверяет гены цвета волос, затем использует вычисленный RimWorld цвет волос
@@ -94,6 +100,35 @@ namespace AIImages.Services
return GetSkinToneDescription(pawn.story.SkinColor);
}
/// <summary>
/// Получает текстовое описание цвета кожи по RGB цвету (fallback метод)
/// </summary>
public static string GetSkinToneDescription(Color color)
{
// Вычисляем яркость
float brightness = (color.r + color.g + color.b) / 3f;
// Определяем оттенок кожи
if (brightness >= 0.85f)
return "very fair skin";
else if (brightness >= 0.75f)
return "fair skin";
else if (brightness >= 0.65f)
return "light skin";
else if (brightness >= 0.55f)
return "medium skin";
else if (brightness >= 0.45f)
return "olive skin";
else if (brightness >= 0.35f)
return "tan skin";
else if (brightness >= 0.25f)
return "brown skin";
else if (brightness >= 0.15f)
return "dark brown skin";
else
return "very dark skin";
}
/// <summary>
/// Проверяет, является ли ген специальным геном цвета кожи (зелёная, синяя, красная и т.д.)
/// Исключает гены меланина (Melanin1-9), так как они определяют обычный цвет кожи
@@ -110,30 +145,49 @@ namespace AIImages.Services
return false;
// Специальные цвета: зелёная, синяя, красная, жёлтая, фиолетовая, оранжевая, чёрная, белая, серая
return geneDefName.StartsWith("Skin_")
&& (
geneDefName.Contains("Green")
|| geneDefName.Contains("Blue")
|| geneDefName.Contains("Red")
|| geneDefName.Contains("Yellow")
|| geneDefName.Contains("Purple")
|| geneDefName.Contains("Orange")
|| geneDefName.Contains("Black")
|| geneDefName.Contains("White")
|| geneDefName.Contains("Gray")
|| geneDefName.Contains("Grey")
|| geneDefName.Contains("Ink")
|| geneDefName.Contains("Slate")
|| geneDefName.Contains("Sheer")
|| geneDefName.Contains("Pale")
|| geneDefName.Contains("Deep")
);
return geneDefName.StartsWith("Skin_") && HasSpecialSkinColorKeyword(geneDefName);
}
/// <summary>
/// Проверяет наличие ключевых слов специальных цветов кожи
/// </summary>
private static bool HasSpecialSkinColorKeyword(string geneDefName)
{
return geneDefName.Contains(Green)
|| geneDefName.Contains("Blue")
|| geneDefName.Contains("Red")
|| geneDefName.Contains("Yellow")
|| geneDefName.Contains("Purple")
|| geneDefName.Contains(Orange)
|| geneDefName.Contains(Black)
|| geneDefName.Contains(White)
|| geneDefName.Contains("Gray")
|| geneDefName.Contains("Grey")
|| geneDefName.Contains("Ink")
|| geneDefName.Contains("Slate")
|| geneDefName.Contains("Sheer")
|| geneDefName.Contains("Pale")
|| geneDefName.Contains("Deep");
}
/// <summary>
/// Получает описание для специальных генов цвета кожи
/// </summary>
private static string GetSpecialGeneSkinTone(string geneDefName)
{
// Сначала проверяем точные совпадения
string exactMatch = GetExactSkinColorMatch(geneDefName);
if (exactMatch != null)
return exactMatch;
// Затем пытаемся определить по ключевым словам
return GetSkinColorByKeyword(geneDefName);
}
/// <summary>
/// Получает точное совпадение для известных генов цвета кожи
/// </summary>
private static string GetExactSkinColorMatch(string geneDefName)
{
switch (geneDefName)
{
@@ -162,31 +216,39 @@ namespace AIImages.Services
case "Skin_Green":
return "green skin";
default:
// Пытаемся определить по названию (defName всегда на английском)
if (geneDefName.Contains("Green"))
return "green skin";
if (geneDefName.Contains("Blue"))
return "blue skin";
if (geneDefName.Contains("Red"))
return "red skin";
if (geneDefName.Contains("Yellow"))
return "yellow skin";
if (geneDefName.Contains("Purple"))
return "purple skin";
if (geneDefName.Contains("Orange"))
return "orange skin";
if (geneDefName.Contains("Black"))
return "black skin";
if (geneDefName.Contains("White"))
return "white skin";
if (geneDefName.Contains("Gray") || geneDefName.Contains("Grey"))
return "gray skin";
return null;
}
}
/// <summary>
/// /// Проверяет, подавлен ли ген другим активным геном
/// Определяет цвет кожи по ключевым словам в названии гена
/// </summary>
private static string GetSkinColorByKeyword(string geneDefName)
{
// Пытаемся определить по названию (defName всегда на английском)
if (geneDefName.Contains(Green))
return "green skin";
if (geneDefName.Contains("Blue"))
return "blue skin";
if (geneDefName.Contains("Red"))
return "red skin";
if (geneDefName.Contains("Yellow"))
return "yellow skin";
if (geneDefName.Contains("Purple"))
return "purple skin";
if (geneDefName.Contains(Orange))
return "orange skin";
if (geneDefName.Contains(Black))
return "black skin";
if (geneDefName.Contains(White))
return "white skin";
if (geneDefName.Contains("Gray") || geneDefName.Contains("Grey"))
return "gray skin";
return null;
}
/// <summary>
/// Проверяет, подавлен ли ген другим активным геном
/// </summary>
private static bool IsGeneSuppressed(Pawn pawn, Gene gene)
{
@@ -201,31 +263,14 @@ namespace AIImages.Services
// Проверяем все активные гены на предмет подавления данного гена
foreach (var otherGene in pawn.genes.GenesListForReading)
{
if (otherGene.Active && otherGene != gene && otherGene.def != null)
if (
otherGene.Active
&& otherGene != gene
&& otherGene.def != null
&& CheckGeneSuppression(otherGene.def, gene.def)
)
{
// Проверяем через GeneUtility, если доступен
// Или проверяем свойство suppresses через reflection, если оно есть
var suppressesField = otherGene.def.GetType().GetField("suppresses");
if (suppressesField != null)
{
var suppresses = suppressesField.GetValue(otherGene.def);
if (
suppresses
is System.Collections.Generic.List<GeneDef> suppressesList
)
{
if (suppressesList.Contains(gene.def))
return true;
}
else if (
suppresses
is System.Collections.Generic.IEnumerable<GeneDef> suppressesEnum
)
{
if (suppressesEnum.Contains(gene.def))
return true;
}
}
return true;
}
}
}
@@ -239,6 +284,29 @@ namespace AIImages.Services
return false;
}
/// <summary>
/// Проверяет, подавляет ли один ген другой через reflection
/// </summary>
private static bool CheckGeneSuppression(GeneDef suppressor, GeneDef suppressed)
{
var suppressesField = suppressor.GetType().GetField("suppresses");
if (suppressesField == null)
return false;
var suppresses = suppressesField.GetValue(suppressor);
if (suppresses is System.Collections.Generic.List<GeneDef> suppressesList)
{
return suppressesList.Contains(suppressed);
}
if (suppresses is System.Collections.Generic.IEnumerable<GeneDef> suppressesEnum)
{
return suppressesEnum.Contains(suppressed);
}
return false;
}
/// <summary>
/// Проверяет, является ли ген геном цвета волос
/// </summary>
@@ -261,17 +329,17 @@ namespace AIImages.Services
|| geneDefName.Contains("Colour")
|| geneDefName.Contains("Red")
|| geneDefName.Contains("Blue")
|| geneDefName.Contains("Green")
|| geneDefName.Contains(Green)
|| geneDefName.Contains("Blond")
|| geneDefName.Contains("Brown")
|| geneDefName.Contains("Black")
|| geneDefName.Contains("White")
|| geneDefName.Contains(Black)
|| geneDefName.Contains(White)
|| geneDefName.Contains("Light")
|| geneDefName.Contains("Dark")
|| geneDefName.Contains("Ginger")
|| geneDefName.Contains("Auburn")
|| geneDefName.Contains("Copper")
|| geneDefName.Contains("Orange")
|| geneDefName.Contains(Orange)
)
);
}
@@ -286,7 +354,20 @@ namespace AIImages.Services
string geneDefName = geneDef.defName;
// Специфичные описания для известных генов цвета волос
// Сначала проверяем точные совпадения
string exactMatch = GetExactHairColorMatch(geneDefName);
if (exactMatch != null)
return exactMatch;
// Затем пытаемся определить по ключевым словам
return GetHairColorByKeyword(geneDefName);
}
/// <summary>
/// Получает точное совпадение для известных генов цвета волос
/// </summary>
private static string GetExactHairColorMatch(string geneDefName)
{
switch (geneDefName)
{
case "Hair_Blond":
@@ -312,71 +393,83 @@ namespace AIImages.Services
case "Hair_Dark":
return "dark hair";
default:
// Пытаемся определить по названию (defName всегда на английском)
// Добавляем поддержку конкретных генов из RimWorld
if (geneDefName.Contains("Blond"))
return "blond hair";
if (geneDefName.Contains("Brown"))
return "brown hair";
if (geneDefName.Contains("Black"))
return "black hair";
if (geneDefName.Contains("White"))
return "white hair";
if (geneDefName.Contains("Red"))
return "red hair";
if (geneDefName.Contains("Ginger"))
return "ginger hair";
if (geneDefName.Contains("Auburn"))
return "auburn hair";
if (geneDefName.Contains("Copper"))
return "copper-brown hair";
if (geneDefName.Contains("Orange"))
return "orange-red hair";
if (geneDefName.Contains("Light"))
return "light hair";
if (geneDefName.Contains("Dark"))
return "dark hair";
if (geneDefName.Contains("Blue"))
return "blue hair";
if (geneDefName.Contains("Green"))
return "green hair";
if (geneDefName.Contains("Purple"))
return "purple hair";
if (geneDefName.Contains("Pink"))
return "pink hair";
if (geneDefName.Contains("Gray") || geneDefName.Contains("Grey"))
return "gray hair";
return null;
}
}
/// <summary>
/// Получает текстовое описание цвета кожи по RGB цвету (fallback метод)
/// Определяет цвет волос по ключевым словам в названии гена
/// </summary>
public static string GetSkinToneDescription(Color color)
private static string GetHairColorByKeyword(string geneDefName)
{
// Вычисляем яркость
float brightness = (color.r + color.g + color.b) / 3f;
// Проверяем основные цвета волос
string basicColor = GetBasicHairColor(geneDefName);
if (basicColor != null)
return basicColor;
// Определяем оттенок кожи
if (brightness >= 0.85f)
return "very fair skin";
else if (brightness >= 0.75f)
return "fair skin";
else if (brightness >= 0.65f)
return "light skin";
else if (brightness >= 0.55f)
return "medium skin";
else if (brightness >= 0.45f)
return "olive skin";
else if (brightness >= 0.35f)
return "tan skin";
else if (brightness >= 0.25f)
return "brown skin";
else if (brightness >= 0.15f)
return "dark brown skin";
else
return "very dark skin";
// Проверяем специальные цвета
string specialColor = GetSpecialHairColor(geneDefName);
if (specialColor != null)
return specialColor;
// Проверяем оттенки
return GetHairColorShade(geneDefName);
}
/// <summary>
/// Получает основной цвет волос
/// </summary>
private static string GetBasicHairColor(string geneDefName)
{
if (geneDefName.Contains("Blond"))
return "blond hair";
if (geneDefName.Contains("Brown"))
return "brown hair";
if (geneDefName.Contains(Black))
return "black hair";
if (geneDefName.Contains(White))
return "white hair";
if (geneDefName.Contains("Red"))
return "red hair";
if (geneDefName.Contains("Ginger"))
return "ginger hair";
if (geneDefName.Contains("Auburn"))
return "auburn hair";
return null;
}
/// <summary>
/// Получает специальный цвет волос
/// </summary>
private static string GetSpecialHairColor(string geneDefName)
{
if (geneDefName.Contains("Copper"))
return "copper-brown hair";
if (geneDefName.Contains(Orange))
return "orange-red hair";
if (geneDefName.Contains("Blue"))
return "blue hair";
if (geneDefName.Contains(Green))
return "green hair";
if (geneDefName.Contains("Purple"))
return "purple hair";
if (geneDefName.Contains("Pink"))
return "pink hair";
if (geneDefName.Contains("Gray") || geneDefName.Contains("Grey"))
return "gray hair";
return null;
}
/// <summary>
/// Получает оттенок волос
/// </summary>
private static string GetHairColorShade(string geneDefName)
{
if (geneDefName.Contains("Light"))
return "light hair";
if (geneDefName.Contains("Dark"))
return "dark hair";
return null;
}
/// <summary>