diff --git a/Assemblies/AIImages.dll b/Assemblies/AIImages.dll
index d3306cd..26489bc 100644
Binary files a/Assemblies/AIImages.dll and b/Assemblies/AIImages.dll differ
diff --git a/Source/AIImages/Window_AIImage.cs b/Source/AIImages/Window_AIImage.cs
index 0dc845c..293c55c 100644
--- a/Source/AIImages/Window_AIImage.cs
+++ b/Source/AIImages/Window_AIImage.cs
@@ -572,12 +572,25 @@ namespace AIImages
{
float contentY = startY;
float lineHeight = 22f;
+
+ contentY = DrawBasicInfo(parentRect, contentY, lineHeight);
+ contentY = DrawTraits(parentRect, contentY, lineHeight);
+ contentY = DrawGenes(parentRect, contentY, lineHeight);
+ contentY = DrawHediffs(parentRect, contentY, lineHeight);
+ DrawApparel(parentRect, contentY, lineHeight);
+ }
+
+ ///
+ /// Отрисовывает базовую информацию о персонаже
+ ///
+ private float DrawBasicInfo(Rect parentRect, float startY, float lineHeight)
+ {
+ float contentY = startY;
float labelWidth = parentRect.width * 0.45f;
float valueWidth = parentRect.width * 0.50f;
Text.Font = GameFont.Tiny;
- // Базовая информация
var info = new[]
{
("AIImages.Info.Gender".Translate(), appearanceData.Gender.ToString()),
@@ -618,123 +631,161 @@ namespace AIImages
contentY += lineHeight;
}
- // Черты характера
- if (pawn.story?.traits?.allTraits != null && pawn.story.traits.allTraits.Any())
- {
- contentY += 15f;
- Text.Font = GameFont.Small;
- Widgets.Label(
- new Rect(parentRect.x + 5f, contentY, parentRect.width - 10f, lineHeight),
- "AIImages.Info.Traits".Translate() + ":"
- );
- contentY += lineHeight + 2f;
+ return contentY;
+ }
- Text.Font = GameFont.Tiny;
- var traitLabels = pawn.story.traits.allTraits.Select(trait => trait.LabelCap);
- foreach (var traitLabel in traitLabels)
- {
- Widgets.Label(
- new Rect(parentRect.x + 15f, contentY, parentRect.width - 20f, lineHeight),
- "• " + traitLabel
- );
- contentY += lineHeight;
- }
+ ///
+ /// Отрисовывает черты характера персонажа
+ ///
+ private float DrawTraits(Rect parentRect, float startY, float lineHeight)
+ {
+ float contentY = startY;
+
+ if (pawn.story?.traits?.allTraits == null || !pawn.story.traits.allTraits.Any())
+ return contentY;
+
+ contentY += 15f;
+ Text.Font = GameFont.Small;
+ Widgets.Label(
+ new Rect(parentRect.x + 5f, contentY, parentRect.width - 10f, lineHeight),
+ "AIImages.Info.Traits".Translate() + ":"
+ );
+ contentY += lineHeight + 2f;
+
+ Text.Font = GameFont.Tiny;
+ var traitLabels = pawn.story.traits.allTraits.Select(trait => trait.LabelCap);
+ foreach (var traitLabel in traitLabels)
+ {
+ Widgets.Label(
+ new Rect(parentRect.x + 15f, contentY, parentRect.width - 20f, lineHeight),
+ "• " + traitLabel
+ );
+ contentY += lineHeight;
}
- // Гены
- if (pawn.genes?.GenesListForReading != null && pawn.genes.GenesListForReading.Any())
- {
- contentY += 15f;
- Text.Font = GameFont.Small;
- Widgets.Label(
- new Rect(parentRect.x + 5f, contentY, parentRect.width - 10f, lineHeight),
- "AIImages.Info.Genes".Translate() + ":"
- );
- contentY += lineHeight + 2f;
+ return contentY;
+ }
- Text.Font = GameFont.Tiny;
- 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 - 25f, textHeight),
- "• " + geneInfo
- );
- contentY += textHeight;
- }
+ ///
+ /// Отрисовывает гены персонажа
+ ///
+ private float DrawGenes(Rect parentRect, float startY, float lineHeight)
+ {
+ float contentY = startY;
+
+ if (pawn.genes?.GenesListForReading == null || !pawn.genes.GenesListForReading.Any())
+ return contentY;
+
+ contentY += 15f;
+ Text.Font = GameFont.Small;
+ Widgets.Label(
+ new Rect(parentRect.x + 5f, contentY, parentRect.width - 10f, lineHeight),
+ "AIImages.Info.Genes".Translate() + ":"
+ );
+ contentY += lineHeight + 2f;
+
+ Text.Font = GameFont.Tiny;
+ var activeGenes = pawn.genes.GenesListForReading.Where(gene => gene.Active).ToList();
+ foreach (var gene in activeGenes)
+ {
+ string geneInfo = BuildGeneInfo(gene);
+ float textHeight = Text.CalcHeight(geneInfo, parentRect.width - 25f);
+
+ Widgets.Label(
+ new Rect(parentRect.x + 15f, contentY, parentRect.width - 25f, textHeight),
+ "• " + geneInfo
+ );
+ contentY += textHeight;
}
- // Хедифы (состояния)
- if (pawn.health?.hediffSet?.hediffs != null && pawn.health.hediffSet.hediffs.Any())
- {
- contentY += 15f;
- Text.Font = GameFont.Small;
- Widgets.Label(
- new Rect(parentRect.x + 5f, contentY, parentRect.width - 10f, lineHeight),
- "AIImages.Info.Hediffs".Translate() + ":"
- );
- contentY += lineHeight + 2f;
+ return contentY;
+ }
- Text.Font = GameFont.Tiny;
- var hediffLabels = pawn
- .health.hediffSet.hediffs.Where(hediff => hediff.Visible)
- .Select(hediff => hediff.LabelCap);
- foreach (var hediffLabel in hediffLabels)
+ ///
+ /// Строит информационную строку для гена
+ ///
+ private string BuildGeneInfo(Gene gene)
+ {
+ string geneLabel = gene.Label ?? gene.def.LabelCap;
+ string geneInfo = geneLabel;
+
+ if (!string.IsNullOrEmpty(gene.def.description))
+ {
+ string description = gene.def.description;
+ if (description.Length > 200)
{
- Widgets.Label(
- new Rect(parentRect.x + 15f, contentY, parentRect.width - 20f, lineHeight),
- "• " + hediffLabel
- );
- contentY += lineHeight;
+ description = description.Substring(0, 197) + "...";
}
+ geneInfo += " - " + description;
}
- // Одежда
+ return geneInfo;
+ }
+
+ ///
+ /// Отрисовывает хедифы (состояния здоровья) персонажа
+ ///
+ private float DrawHediffs(Rect parentRect, float startY, float lineHeight)
+ {
+ float contentY = startY;
+
+ if (pawn.health?.hediffSet?.hediffs == null || !pawn.health.hediffSet.hediffs.Any())
+ return contentY;
+
+ contentY += 15f;
+ Text.Font = GameFont.Small;
+ Widgets.Label(
+ new Rect(parentRect.x + 5f, contentY, parentRect.width - 10f, lineHeight),
+ "AIImages.Info.Hediffs".Translate() + ":"
+ );
+ contentY += lineHeight + 2f;
+
+ Text.Font = GameFont.Tiny;
+ var hediffLabels = pawn
+ .health.hediffSet.hediffs.Where(hediff => hediff.Visible)
+ .Select(hediff => hediff.LabelCap);
+ foreach (var hediffLabel in hediffLabels)
+ {
+ Widgets.Label(
+ new Rect(parentRect.x + 15f, contentY, parentRect.width - 20f, lineHeight),
+ "• " + hediffLabel
+ );
+ contentY += lineHeight;
+ }
+
+ return contentY;
+ }
+
+ ///
+ /// Отрисовывает одежду персонажа
+ ///
+ private void DrawApparel(Rect parentRect, float startY, float lineHeight)
+ {
+ float contentY = startY;
var apparel = pawn.apparel?.WornApparel;
- if (apparel != null && apparel.Any())
- {
- contentY += 15f;
- Text.Font = GameFont.Small;
- Widgets.Label(
- new Rect(parentRect.x + 5f, contentY, parentRect.width - 10f, lineHeight),
- "AIImages.Info.Apparel".Translate() + ":"
- );
- contentY += lineHeight + 2f;
- Text.Font = GameFont.Tiny;
- foreach (var item in apparel)
- {
- var colorDesc = ColorDescriptionService.GetApparelColorDescription(
- item.DrawColor
- );
- string apparelLabel = $"• {colorDesc} {item.def.label}";
- float apparelHeight = Text.CalcHeight(apparelLabel, parentRect.width - 25f);
- Widgets.Label(
- new Rect(
- parentRect.x + 15f,
- contentY,
- parentRect.width - 25f,
- apparelHeight
- ),
- apparelLabel
- );
- contentY += apparelHeight;
- }
+ if (apparel == null || !apparel.Any())
+ return;
+
+ contentY += 15f;
+ Text.Font = GameFont.Small;
+ Widgets.Label(
+ new Rect(parentRect.x + 5f, contentY, parentRect.width - 10f, lineHeight),
+ "AIImages.Info.Apparel".Translate() + ":"
+ );
+ contentY += lineHeight + 2f;
+
+ Text.Font = GameFont.Tiny;
+ foreach (var item in apparel)
+ {
+ var colorDesc = ColorDescriptionService.GetApparelColorDescription(item.DrawColor);
+ string apparelLabel = $"• {colorDesc} {item.def.label}";
+ float apparelHeight = Text.CalcHeight(apparelLabel, parentRect.width - 25f);
+ Widgets.Label(
+ new Rect(parentRect.x + 15f, contentY, parentRect.width - 25f, apparelHeight),
+ apparelLabel
+ );
+ contentY += apparelHeight;
}
}
@@ -803,79 +854,110 @@ namespace AIImages
private float CalculateContentHeight()
{
- float height = 0f;
+ float height = CalculatePortraitHeight();
+ height += CalculateBasicInfoHeight();
+ height += CalculateTraitsHeight();
+ height += CalculateGenesHeight();
+ height += CalculateHediffsHeight();
+ height += CalculateApparelHeight();
+ height += 50f; // Дополнительный отступ
+ return height;
+ }
- // Портрет персонажа (если есть)
+ ///
+ /// Рассчитывает высоту портрета персонажа
+ ///
+ private float CalculatePortraitHeight()
+ {
if (generatedImage != null)
{
float portraitSize = 250f; // Максимальный размер портрета
- height += portraitSize + 15f;
+ return portraitSize + 15f;
}
+ return 0f;
+ }
- // Заголовок "Информация о персонаже"
- height += 35f;
+ ///
+ /// Рассчитывает высоту базовой информации
+ ///
+ private float CalculateBasicInfoHeight()
+ {
+ float height = 35f; // Заголовок "Информация о персонаже"
+ height += 10f; // Разделитель
+ height += 6 * 22f; // Базовая информация (6 строк по 22px)
+ return height;
+ }
- // Разделитель
- height += 10f;
+ ///
+ /// Рассчитывает высоту секции черт характера
+ ///
+ private float CalculateTraitsHeight()
+ {
+ if (pawn.story?.traits?.allTraits == null || !pawn.story.traits.allTraits.Any())
+ return 0f;
- // Базовая информация (6 строк по 22px)
- height += 6 * 22f;
+ float height = 15f; // Отступ
+ height += 22f; // Заголовок "Черты характера"
+ height += 2f; // Отступ
+ height += pawn.story.traits.allTraits.Count * 22f; // Каждая черта
+ return height;
+ }
- // Черты характера (если есть)
- if (pawn.story?.traits?.allTraits != null && pawn.story.traits.allTraits.Any())
+ ///
+ /// Рассчитывает высоту секции генов
+ ///
+ private float CalculateGenesHeight()
+ {
+ if (pawn.genes?.GenesListForReading == null || !pawn.genes.GenesListForReading.Any())
+ return 0f;
+
+ float height = 15f; // Отступ
+ height += 22f; // Заголовок "Гены"
+ height += 2f; // Отступ
+
+ // Рассчитываем высоту для каждого гена с учетом описания
+ Text.Font = GameFont.Tiny;
+ var activeGenes = pawn.genes.GenesListForReading.Where(gene => gene.Active).ToList();
+ float approximateColumnWidth = 900f * 0.35f; // Примерная ширина левой колонки
+ float labelWidth = approximateColumnWidth - 25f;
+
+ foreach (var gene in activeGenes)
{
- height += 15f; // Отступ
- height += 22f; // Заголовок "Черты характера"
- height += 2f; // Отступ
- height += pawn.story.traits.allTraits.Count * 22f; // Каждая черта
+ string geneInfo = BuildGeneInfo(gene);
+ height += Text.CalcHeight("• " + geneInfo, labelWidth);
}
- // Гены (если есть)
- if (pawn.genes?.GenesListForReading != null && pawn.genes.GenesListForReading.Any())
- {
- height += 15f; // Отступ
- height += 22f; // Заголовок "Гены"
- height += 2f; // Отступ
-
- // Рассчитываем высоту для каждого гена с учетом описания
- 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);
- }
- }
+ return height;
+ }
- // Хедифы (если есть)
- if (pawn.health?.hediffSet?.hediffs != null && pawn.health.hediffSet.hediffs.Any())
- {
- height += 15f; // Отступ
- height += 22f; // Заголовок "Хедифы"
- height += 2f; // Отступ
- height += pawn.health.hediffSet.hediffs.Count(hediff => hediff.Visible) * 22f; // Каждый видимый хедиф
- }
+ ///
+ /// Рассчитывает высоту секции хедифов
+ ///
+ private float CalculateHediffsHeight()
+ {
+ if (pawn.health?.hediffSet?.hediffs == null || !pawn.health.hediffSet.hediffs.Any())
+ return 0f;
- // Одежда (если есть)
+ float height = 15f; // Отступ
+ height += 22f; // Заголовок "Хедифы"
+ height += 2f; // Отступ
+ height += pawn.health.hediffSet.hediffs.Count(hediff => hediff.Visible) * 22f; // Каждый видимый хедиф
+ return height;
+ }
+
+ ///
+ /// Рассчитывает высоту секции одежды
+ ///
+ private float CalculateApparelHeight()
+ {
var apparel = pawn.apparel?.WornApparel;
- if (apparel != null && apparel.Any())
- {
- height += 15f; // Отступ
- height += 22f; // Заголовок "Одежда"
- height += 2f; // Отступ
- // Примерно по 22-30px на предмет одежды
- height += apparel.Count * 26f;
- }
-
- // Дополнительный отступ
- height += 50f;
+ if (apparel == null || !apparel.Any())
+ return 0f;
+ float height = 15f; // Отступ
+ height += 22f; // Заголовок "Одежда"
+ height += 2f; // Отступ
+ height += apparel.Count * 26f; // Примерно по 22-30px на предмет одежды
return height;
}