using System.Linq;
using RimWorld;
using UnityEngine;
using Verse;
namespace AIImages.Services
{
///
/// Сервис для умного определения цветов (вместо RGB значений)
///
public static class ColorDescriptionService
{
///
/// Получает текстовое описание цвета волос
///
public static string GetHairColorDescription(Color color)
{
float h,
s,
v;
Color.RGBToHSV(color, out h, out s, out v);
// Проверяем на оттенки серого
if (s < 0.15f)
{
return GetGrayscaleDescription(v);
}
// Определяем оттенок
string hueDescription = GetHueDescription(h);
string brightnessModifier = GetBrightnessModifier(v, s);
return $"{brightnessModifier}{hueDescription}".Trim();
}
///
/// Получает текстовое описание цвета кожи, сначала проверяя гены, затем используя цвет как fallback
///
public static string GetSkinToneDescription(Pawn pawn)
{
// Сначала проверяем гены цвета кожи
string geneSkinTone = GetSkinToneFromGenes(pawn);
if (!string.IsNullOrEmpty(geneSkinTone))
{
return geneSkinTone;
}
// Fallback к определению по цвету
return GetSkinToneDescription(pawn.story.SkinColor);
}
///
/// Получает текстовое описание цвета кожи по RGB цвету (fallback метод)
///
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";
}
///
/// Получает текстовое описание цвета кожи по генам
///
public static string GetSkinToneFromGenes(Pawn pawn)
{
if (pawn?.genes?.GenesListForReading == null)
return null;
// Ищем активные гены цвета кожи
var skinColorGenes = pawn
.genes.GenesListForReading.Where(gene =>
gene.Active && IsSkinColorGene(gene.def.defName)
)
.ToList();
if (!skinColorGenes.Any())
return null;
// Берем первый найденный ген (обычно у персонажа один ген цвета кожи)
var skinGene = skinColorGenes[0];
return GetSkinToneDescriptionFromGene(skinGene.def.defName);
}
///
/// Проверяет, является ли ген геном цвета кожи
///
private static bool IsSkinColorGene(string geneDefName)
{
return geneDefName.StartsWith("Skin_")
|| geneDefName.Contains("SkinColor")
|| geneDefName.Contains("SkinTone");
}
///
/// Получает описание цвета кожи по названию гена
///
private static string GetSkinToneDescriptionFromGene(string geneDefName)
{
// Проверяем стандартные гены
string standardGene = GetStandardGeneSkinTone(geneDefName);
if (!string.IsNullOrEmpty(standardGene))
return standardGene;
// Проверяем дополнительные гены
string additionalGene = GetAdditionalGeneSkinTone(geneDefName);
if (!string.IsNullOrEmpty(additionalGene))
return additionalGene;
// Пытаемся извлечь информацию из названия
return ExtractSkinToneFromGeneName(geneDefName);
}
///
/// Получает описание для стандартных генов цвета кожи
///
private static string GetStandardGeneSkinTone(string geneDefName)
{
switch (geneDefName)
{
case "Skin_InkBlack":
return "ink black skin";
case "Skin_SlateGray":
return "slate gray skin";
case "Skin_LightGray":
return "light gray skin";
case "Skin_SheerWhite":
return "sheer white skin";
case "Skin_Blue":
return "blue skin";
case "Skin_Purple":
return "purple skin";
case "Skin_PaleRed":
return "pale red skin";
case "Skin_DeepRed":
return "deep red skin";
case "Skin_PaleYellow":
return "pale yellow skin";
case "Skin_DeepYellow":
return "deep yellow skin";
case "Skin_Orange":
return "orange skin";
case "Skin_Green":
return "green skin";
default:
return null;
}
}
///
/// Получает описание для дополнительных генов цвета кожи
///
private static string GetAdditionalGeneSkinTone(string geneDefName)
{
switch (geneDefName)
{
case "Skin_Dark":
return "dark skin";
case "Skin_Light":
return "light skin";
case "Skin_Medium":
return "medium skin";
case "Skin_Fair":
return "fair skin";
case "Skin_Tan":
return "tan skin";
case "Skin_Olive":
return "olive skin";
case "Skin_Brown":
return "brown skin";
default:
return null;
}
}
///
/// Извлекает описание цвета кожи из названия гена
///
private static string ExtractSkinToneFromGeneName(string geneDefName)
{
if (geneDefName.Contains("Black"))
return "black skin";
if (geneDefName.Contains("White"))
return "white skin";
if (geneDefName.Contains("Gray") || geneDefName.Contains("Grey"))
return "gray skin";
if (geneDefName.Contains("Blue"))
return "blue skin";
if (geneDefName.Contains("Red"))
return "red skin";
if (geneDefName.Contains("Green"))
return "green skin";
if (geneDefName.Contains("Yellow"))
return "yellow skin";
if (geneDefName.Contains("Purple"))
return "purple skin";
if (geneDefName.Contains("Orange"))
return "orange skin";
return null; // Неизвестный ген
}
///
/// Получает описание цвета одежды
///
public static string GetApparelColorDescription(Color color)
{
float h,
s,
v;
Color.RGBToHSV(color, out h, out s, out v);
// Проверяем на оттенки серого
if (s < 0.1f)
{
return GetGrayscaleDescription(v);
}
// Определяем оттенок
string hueDescription = GetHueDescription(h);
// Модификаторы насыщенности и яркости
string saturationModifier = "";
if (s < 0.3f)
saturationModifier = "pale ";
else if (s > 0.8f)
saturationModifier = "vivid ";
string brightnessModifier = "";
if (v < 0.3f)
brightnessModifier = "dark ";
else if (v > 0.8f)
brightnessModifier = "bright ";
return $"{brightnessModifier}{saturationModifier}{hueDescription}".Trim();
}
private static string GetGrayscaleDescription(float value)
{
if (value >= 0.95f)
return "white";
else if (value >= 0.8f)
return "light gray";
else if (value >= 0.6f)
return "gray";
else if (value >= 0.4f)
return "dark gray";
else if (value >= 0.2f)
return "charcoal";
else
return "black";
}
private static string GetHueDescription(float hue)
{
// Hue from 0 to 1
if (hue < 0.05f || hue >= 0.95f)
return "red";
if (hue < 0.083f)
return "orange-red";
if (hue < 0.15f)
return "orange";
if (hue < 0.19f)
return "golden";
if (hue < 0.22f)
return "yellow";
if (hue < 0.35f)
return "yellow-green";
if (hue < 0.45f)
return "green";
if (hue < 0.52f)
return "cyan";
if (hue < 0.58f)
return "light blue";
if (hue < 0.65f)
return "blue";
if (hue < 0.72f)
return "deep blue";
if (hue < 0.78f)
return "purple";
if (hue < 0.85f)
return "violet";
if (hue < 0.92f)
return "magenta";
return "pink";
}
private static string GetBrightnessModifier(float value, float saturation)
{
// Для волос используем специальные термины
if (value < 0.2f)
return "jet black ";
else if (value < 0.3f)
return "black ";
else if (value < 0.45f)
return "dark ";
else if (value > 0.85f && saturation < 0.3f)
return "platinum ";
else if (value > 0.75f)
return "light ";
else
return "";
}
}
}