diff --git a/Assemblies/AIImages.dll b/Assemblies/AIImages.dll index d88de2c..ee3bb26 100644 Binary files a/Assemblies/AIImages.dll and b/Assemblies/AIImages.dll differ diff --git a/Languages/English/Keyed/AIImages.xml b/Languages/English/Keyed/AIImages.xml new file mode 100644 index 0000000..24da3ec --- /dev/null +++ b/Languages/English/Keyed/AIImages.xml @@ -0,0 +1,28 @@ + + + + AI Image + Open AI Image window + + AI Image Window + Character: {0} + + Appearance + Appearance information unavailable + Gender: {0} + Age: {0} years + Body type: {0} + Skin color: RGB({0}, {1}, {2}) + Hairstyle: {0} + Hair color: RGB({0}, {1}, {2}) + Traits: + + Apparel + Apparel information unavailable + Character is not wearing anything + Apparel ({0} items): + Quality: {0} + Material: {0} + Durability: {0}/{1} ({2}%) + Color: RGB({0}, {1}, {2}) + diff --git a/Languages/English/LanguageInfo.xml b/Languages/English/LanguageInfo.xml new file mode 100644 index 0000000..1e247e8 --- /dev/null +++ b/Languages/English/LanguageInfo.xml @@ -0,0 +1,6 @@ + + + English + English + true + diff --git a/Languages/Russian/Keyed/AIImages.xml b/Languages/Russian/Keyed/AIImages.xml new file mode 100644 index 0000000..3a260f5 --- /dev/null +++ b/Languages/Russian/Keyed/AIImages.xml @@ -0,0 +1,28 @@ + + + + AI Изображение + Открыть окно AI изображения + + Окно AI изображения + Персонаж: {0} + + Внешность + Информация о внешности недоступна + Пол: {0} + Возраст: {0} лет + Тип тела: {0} + Цвет кожи: RGB({0}, {1}, {2}) + Прическа: {0} + Цвет волос: RGB({0}, {1}, {2}) + Черты характера: + + Одежда + Информация об одежде недоступна + Персонаж ничего не носит + Одежда ({0} предметов): + Качество: {0} + Материал: {0} + Прочность: {0}/{1} ({2}%) + Цвет: RGB({0}, {1}, {2}) + diff --git a/Languages/Russian/LanguageInfo.xml b/Languages/Russian/LanguageInfo.xml new file mode 100644 index 0000000..ac969e5 --- /dev/null +++ b/Languages/Russian/LanguageInfo.xml @@ -0,0 +1,6 @@ + + + Русский + Russian + true + diff --git a/Source/AIImages/PawnGizmoPatch.cs b/Source/AIImages/PawnGizmoPatch.cs index f4e0850..8c81a97 100644 --- a/Source/AIImages/PawnGizmoPatch.cs +++ b/Source/AIImages/PawnGizmoPatch.cs @@ -43,9 +43,9 @@ namespace AIImages { yield return new Command_Action { - defaultLabel = "AI Image", - defaultDesc = "Open AI Image window", - icon = ContentFinder.Get("UI/Commands/AttackMelee", true), + defaultLabel = "AIImages.Gizmo.Label".Translate(), + defaultDesc = "AIImages.Gizmo.Description".Translate(), + icon = ContentFinder.Get("UI/Commands/AIImage", true), action = delegate() { // Проверяем, открыто ли уже окно AI Image diff --git a/Source/AIImages/Window_AIImage.cs b/Source/AIImages/Window_AIImage.cs index a309eaa..544fd82 100644 --- a/Source/AIImages/Window_AIImage.cs +++ b/Source/AIImages/Window_AIImage.cs @@ -79,20 +79,22 @@ namespace AIImages private string GetAppearanceDescription() { if (pawn?.story == null) - return "Информация о внешности недоступна"; + return "AIImages.Appearance.NoInfo".Translate(); StringBuilder sb = new StringBuilder(); // Пол - sb.AppendLine($"Пол: {pawn.gender.GetLabel()}"); + sb.AppendLine("AIImages.Appearance.Gender".Translate(pawn.gender.GetLabel())); // Возраст - sb.AppendLine($"Возраст: {pawn.ageTracker.AgeBiologicalYears} лет"); + sb.AppendLine("AIImages.Appearance.Age".Translate(pawn.ageTracker.AgeBiologicalYears)); // Тип тела if (pawn.story.bodyType != null) { - sb.AppendLine($"Тип тела: {pawn.story.bodyType.defName}"); + sb.AppendLine( + "AIImages.Appearance.BodyType".Translate(pawn.story.bodyType.defName) + ); } // Цвет кожи @@ -100,18 +102,26 @@ namespace AIImages { Color skinColor = pawn.story.SkinColor; sb.AppendLine( - $"Цвет кожи: RGB({skinColor.r:F2}, {skinColor.g:F2}, {skinColor.b:F2})" + "AIImages.Appearance.SkinColor".Translate( + skinColor.r.ToString("F2"), + skinColor.g.ToString("F2"), + skinColor.b.ToString("F2") + ) ); } // Волосы if (pawn.story.hairDef != null) { - sb.AppendLine($"Прическа: {pawn.story.hairDef.label}"); + sb.AppendLine("AIImages.Appearance.Hairstyle".Translate(pawn.story.hairDef.label)); if (pawn.story.HairColor != null) { sb.AppendLine( - $"Цвет волос: RGB({pawn.story.HairColor.r:F2}, {pawn.story.HairColor.g:F2}, {pawn.story.HairColor.b:F2})" + "AIImages.Appearance.HairColor".Translate( + pawn.story.HairColor.r.ToString("F2"), + pawn.story.HairColor.g.ToString("F2"), + pawn.story.HairColor.b.ToString("F2") + ) ); } } @@ -119,7 +129,7 @@ namespace AIImages // Черты характера if (pawn.story.traits?.allTraits != null && pawn.story.traits.allTraits.Any()) { - sb.AppendLine("\nЧерты характера:"); + sb.AppendLine("\n" + "AIImages.Appearance.Traits".Translate()); foreach (var trait in pawn.story.traits.allTraits) { sb.AppendLine($" • {trait.LabelCap}"); @@ -135,18 +145,18 @@ namespace AIImages private string GetApparelDescription() { if (pawn?.apparel == null) - return "Информация об одежде недоступна"; + return "AIImages.Apparel.NoInfo".Translate(); StringBuilder sb = new StringBuilder(); List wornApparel = pawn.apparel.WornApparel; if (wornApparel == null || !wornApparel.Any()) { - sb.AppendLine("Персонаж ничего не носит"); + sb.AppendLine("AIImages.Apparel.NoClothes".Translate()); } else { - sb.AppendLine($"Одежда ({wornApparel.Count} предметов):\n"); + sb.AppendLine("AIImages.Apparel.ListHeader".Translate(wornApparel.Count) + "\n"); foreach (Apparel apparel in wornApparel) { FormatApparelItem(sb, apparel); @@ -165,26 +175,34 @@ namespace AIImages if (apparel.TryGetQuality(out QualityCategory quality)) { - sb.AppendLine($" Качество: {quality.GetLabel()}"); + sb.AppendLine("AIImages.Apparel.Quality".Translate(quality.GetLabel())); } if (apparel.Stuff != null) { - sb.AppendLine($" Материал: {apparel.Stuff.LabelCap}"); + 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( - $" Прочность: {apparel.HitPoints}/{apparel.MaxHitPoints} ({percentage}%)" + "AIImages.Apparel.Durability".Translate( + apparel.HitPoints, + apparel.MaxHitPoints, + percentage + ) ); } if (apparel.DrawColor != Color.white) { sb.AppendLine( - $" Цвет: RGB({apparel.DrawColor.r:F2}, {apparel.DrawColor.g:F2}, {apparel.DrawColor.b:F2})" + "AIImages.Apparel.Color".Translate( + apparel.DrawColor.r.ToString("F2"), + apparel.DrawColor.g.ToString("F2"), + apparel.DrawColor.b.ToString("F2") + ) ); } @@ -197,14 +215,17 @@ namespace AIImages // Заголовок Text.Font = GameFont.Medium; - Widgets.Label(new Rect(0f, curY, inRect.width, 40f), "AI Image Window"); + Widgets.Label( + new Rect(0f, curY, inRect.width, 40f), + "AIImages.Window.Title".Translate() + ); curY += 45f; // Имя пешки Text.Font = GameFont.Small; Widgets.Label( new Rect(0f, curY, inRect.width, 30f), - "Персонаж: " + pawn.NameShortColored.Resolve() + "AIImages.Window.PawnLabel".Translate(pawn.NameShortColored.Resolve()) ); curY += 40f; @@ -227,7 +248,10 @@ namespace AIImages // Секция "Внешность" Text.Font = GameFont.Medium; - Widgets.Label(new Rect(10f, contentY, scrollViewRect.width - 20f, 30f), "Внешность"); + Widgets.Label( + new Rect(10f, contentY, scrollViewRect.width - 20f, 30f), + "AIImages.Appearance.SectionTitle".Translate() + ); contentY += 35f; Text.Font = GameFont.Small; @@ -245,7 +269,10 @@ namespace AIImages // Секция "Одежда" Text.Font = GameFont.Medium; - Widgets.Label(new Rect(10f, contentY, scrollViewRect.width - 20f, 30f), "Одежда"); + Widgets.Label( + new Rect(10f, contentY, scrollViewRect.width - 20f, 30f), + "AIImages.Apparel.SectionTitle".Translate() + ); contentY += 35f; Text.Font = GameFont.Small; diff --git a/Textures/UI/Commands/AIImage.png b/Textures/UI/Commands/AIImage.png new file mode 100644 index 0000000..334dcd4 Binary files /dev/null and b/Textures/UI/Commands/AIImage.png differ