using System.Collections.Generic; using System.Linq; using System.Text; using AIImages.Models; using RimWorld; using Verse; namespace AIImages.Services { /// /// Сервис для извлечения и описания данных о внешности персонажа /// 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) ); } // Цвет кожи (с умным описанием) if (pawn.story.SkinColor != null) { string skinDescription = ColorDescriptionService.GetSkinToneDescription( pawn.story.SkinColor ); 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 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(); } } }