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 ""; } } }