Files
ai-images/Source/AIImages/Services/PawnDescriptionService.cs

185 lines
6.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AIImages.Models;
using RimWorld;
using Verse;
namespace AIImages.Services
{
/// <summary>
/// Сервис для извлечения и описания данных о внешности персонажа
/// </summary>
public class PawnDescriptionService : IPawnDescriptionService
{
public PawnAppearanceData ExtractAppearanceData(Pawn pawn)
{
if (pawn?.story == null)
return null;
var data = new PawnAppearanceData
{
Name = pawn.Name?.ToStringShort ?? "Unknown",
Gender = pawn.gender,
Age = pawn.ageTracker.AgeBiologicalYears,
BodyType = pawn.story.bodyType?.defName,
SkinColor = pawn.story.SkinColor,
HairStyle = pawn.story.hairDef?.label,
HairDefName = pawn.story.hairDef?.defName,
HairColor = pawn.story.HairColor,
};
// Извлекаем черты характера
if (pawn.story.traits?.allTraits != null)
{
data.Traits.AddRange(pawn.story.traits.allTraits);
}
// Извлекаем одежду
if (pawn.apparel?.WornApparel != null)
{
foreach (var apparel in pawn.apparel.WornApparel)
{
var apparelData = new ApparelData
{
Label = apparel.def.label,
DefName = apparel.def.defName,
Material = apparel.Stuff?.label,
MaterialDefName = apparel.Stuff?.defName,
Color = apparel.DrawColor,
LayerType = apparel.def.apparel?.LastLayer.ToString(),
Durability = apparel.HitPoints,
MaxDurability = apparel.MaxHitPoints,
};
if (apparel.TryGetQuality(out QualityCategory quality))
{
apparelData.Quality = quality;
}
data.Apparel.Add(apparelData);
}
}
return data;
}
public string GetAppearanceDescription(Pawn pawn)
{
if (pawn?.story == null)
return "AIImages.Appearance.NoInfo".Translate();
StringBuilder sb = new StringBuilder();
// Пол
sb.AppendLine("AIImages.Appearance.Gender".Translate(pawn.gender.GetLabel()));
// Возраст
sb.AppendLine("AIImages.Appearance.Age".Translate(pawn.ageTracker.AgeBiologicalYears));
// Тип тела
if (pawn.story.bodyType != null)
{
sb.AppendLine(
"AIImages.Appearance.BodyType".Translate(pawn.story.bodyType.defName)
);
}
// Цвет кожи (с умным описанием, сначала проверяем гены)
string skinDescription = ColorDescriptionService.GetSkinToneDescription(pawn);
if (!string.IsNullOrEmpty(skinDescription))
{
sb.AppendLine("AIImages.Appearance.SkinTone".Translate(skinDescription));
}
// Волосы
if (pawn.story.hairDef != null)
{
sb.AppendLine("AIImages.Appearance.Hairstyle".Translate(pawn.story.hairDef.label));
if (pawn.story.HairColor != null)
{
string hairColorDescription = ColorDescriptionService.GetHairColorDescription(
pawn.story.HairColor
);
sb.AppendLine(
"AIImages.Appearance.HairColorDesc".Translate(hairColorDescription)
);
}
}
// Черты характера
if (pawn.story.traits?.allTraits != null && pawn.story.traits.allTraits.Any())
{
sb.AppendLine("\n" + "AIImages.Appearance.Traits".Translate());
foreach (var trait in pawn.story.traits.allTraits)
{
sb.AppendLine($" • {trait.LabelCap}");
}
}
return sb.ToString();
}
public string GetApparelDescription(Pawn pawn)
{
if (pawn?.apparel == null)
return "AIImages.Apparel.NoInfo".Translate();
StringBuilder sb = new StringBuilder();
List<Apparel> wornApparel = pawn.apparel.WornApparel;
if (wornApparel == null || !wornApparel.Any())
{
sb.AppendLine("AIImages.Apparel.NoClothes".Translate());
}
else
{
sb.AppendLine("AIImages.Apparel.ListHeader".Translate(wornApparel.Count) + "\n");
foreach (Apparel apparel in wornApparel)
{
FormatApparelItem(sb, apparel);
}
}
return sb.ToString();
}
private void FormatApparelItem(StringBuilder sb, Apparel apparel)
{
sb.AppendLine($"• {apparel.LabelCap}");
if (apparel.TryGetQuality(out QualityCategory quality))
{
sb.AppendLine("AIImages.Apparel.Quality".Translate(quality.GetLabel()));
}
if (apparel.Stuff != null)
{
sb.AppendLine("AIImages.Apparel.Material".Translate(apparel.Stuff.LabelCap));
}
if (apparel.HitPoints < apparel.MaxHitPoints)
{
int percentage = (int)((float)apparel.HitPoints / apparel.MaxHitPoints * 100);
sb.AppendLine(
"AIImages.Apparel.Durability".Translate(
apparel.HitPoints,
apparel.MaxHitPoints,
percentage
)
);
}
if (apparel.DrawColor != UnityEngine.Color.white)
{
string colorDesc = ColorDescriptionService.GetApparelColorDescription(
apparel.DrawColor
);
sb.AppendLine("AIImages.Apparel.ColorDesc".Translate(colorDesc));
}
sb.AppendLine();
}
}
}