diff --git a/Assemblies/AIImages.dll b/Assemblies/AIImages.dll index 31c2c5c..d3306cd 100644 Binary files a/Assemblies/AIImages.dll and b/Assemblies/AIImages.dll differ diff --git a/Source/AIImages/Services/AdvancedPromptGenerator.cs b/Source/AIImages/Services/AdvancedPromptGenerator.cs index 6c44372..d519026 100644 --- a/Source/AIImages/Services/AdvancedPromptGenerator.cs +++ b/Source/AIImages/Services/AdvancedPromptGenerator.cs @@ -79,12 +79,13 @@ namespace AIImages.Services prompt.Append(", "); } - // 7. Цвет кожи - string skinTone = ColorDescriptionService.GetSkinToneDescription( - appearanceData.SkinColor - ); - prompt.Append(skinTone); - prompt.Append(", "); + // 7. Цвет кожи (сначала проверяем гены, затем используем цвет как fallback) + string skinTone = GetSkinToneDescription(appearanceData); + if (!string.IsNullOrEmpty(skinTone)) + { + prompt.Append(skinTone); + prompt.Append(", "); + } // 8. Волосы string hairDescription = GetHairDescription(appearanceData); @@ -200,6 +201,14 @@ namespace AIImages.Services }; } + private string GetSkinToneDescription(PawnAppearanceData data) + { + // Этот метод будет использоваться в контексте генерации промптов + // где у нас есть только данные внешности, но не сам Pawn + // Поэтому используем fallback к определению по цвету + return ColorDescriptionService.GetSkinToneDescription(data.SkinColor); + } + private string GetHairDescription(PawnAppearanceData data) { if (string.IsNullOrEmpty(data.HairDefName)) diff --git a/Source/AIImages/Services/ColorDescriptionService.cs b/Source/AIImages/Services/ColorDescriptionService.cs index 5e1c5c7..9cb6b90 100644 --- a/Source/AIImages/Services/ColorDescriptionService.cs +++ b/Source/AIImages/Services/ColorDescriptionService.cs @@ -1,4 +1,7 @@ +using System.Linq; +using RimWorld; using UnityEngine; +using Verse; namespace AIImages.Services { @@ -31,7 +34,23 @@ namespace AIImages.Services } /// - /// Получает текстовое описание цвета кожи + /// Получает текстовое описание цвета кожи, сначала проверяя гены, затем используя цвет как 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) { @@ -59,6 +78,147 @@ namespace AIImages.Services 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; // Неизвестный ген + } + /// /// Получает описание цвета одежды /// diff --git a/Source/AIImages/Services/PawnDescriptionService.cs b/Source/AIImages/Services/PawnDescriptionService.cs index 18492d8..0062420 100644 --- a/Source/AIImages/Services/PawnDescriptionService.cs +++ b/Source/AIImages/Services/PawnDescriptionService.cs @@ -85,12 +85,10 @@ namespace AIImages.Services ); } - // Цвет кожи (с умным описанием) - if (pawn.story.SkinColor != null) + // Цвет кожи (с умным описанием, сначала проверяем гены) + string skinDescription = ColorDescriptionService.GetSkinToneDescription(pawn); + if (!string.IsNullOrEmpty(skinDescription)) { - string skinDescription = ColorDescriptionService.GetSkinToneDescription( - pawn.story.SkinColor - ); sb.AppendLine("AIImages.Appearance.SkinTone".Translate(skinDescription)); } diff --git a/Source/AIImages/Window_AIImage.cs b/Source/AIImages/Window_AIImage.cs index 269542c..0dc845c 100644 --- a/Source/AIImages/Window_AIImage.cs +++ b/Source/AIImages/Window_AIImage.cs @@ -585,7 +585,7 @@ namespace AIImages ("AIImages.Info.BodyType".Translate(), appearanceData.BodyType), ( "AIImages.Info.SkinTone".Translate(), - ColorDescriptionService.GetSkinToneDescription(appearanceData.SkinColor) + ColorDescriptionService.GetSkinToneDescription(pawn) ), ("AIImages.Info.Hair".Translate(), appearanceData.HairStyle), ( @@ -653,16 +653,29 @@ namespace AIImages contentY += lineHeight + 2f; Text.Font = GameFont.Tiny; - var geneLabels = pawn - .genes.GenesListForReading.Where(gene => gene.Active) - .Select(gene => gene.def.LabelCap); - foreach (var geneLabel in geneLabels) + var activeGenes = pawn.genes.GenesListForReading.Where(gene => gene.Active).ToList(); + foreach (var gene in activeGenes) { + // Получаем лейбл гена (предпочитаем Label, если доступен, иначе LabelCap) + string geneLabel = gene.Label ?? gene.def.LabelCap; + + // Собираем дополнительную информацию + string geneInfo = geneLabel; + + // Добавляем описание, если оно есть и не слишком длинное + if (!string.IsNullOrEmpty(gene.def.description) && gene.def.description.Length < 100) + { + geneInfo += " - " + gene.def.description; + } + + // Рассчитываем высоту текста + float textHeight = Text.CalcHeight(geneInfo, parentRect.width - 25f); + Widgets.Label( - new Rect(parentRect.x + 15f, contentY, parentRect.width - 20f, lineHeight), - "• " + geneLabel + new Rect(parentRect.x + 15f, contentY, parentRect.width - 25f, textHeight), + "• " + geneInfo ); - contentY += lineHeight; + contentY += textHeight; } } @@ -823,7 +836,21 @@ namespace AIImages height += 15f; // Отступ height += 22f; // Заголовок "Гены" height += 2f; // Отступ - height += pawn.genes.GenesListForReading.Count(gene => gene.Active) * 22f; // Каждый активный ген + + // Рассчитываем высоту для каждого гена с учетом описания + Text.Font = GameFont.Tiny; + var activeGenes = pawn.genes.GenesListForReading.Where(gene => gene.Active).ToList(); + float labelWidth = parentRect.width - 25f; + foreach (var gene in activeGenes) + { + string geneLabel = gene.Label ?? gene.def.LabelCap; + string geneInfo = geneLabel; + if (!string.IsNullOrEmpty(gene.def.description) && gene.def.description.Length < 100) + { + geneInfo += " - " + gene.def.description; + } + height += Text.CalcHeight("• " + geneInfo, labelWidth); + } } // Хедифы (если есть)