Refactor AIImages UI to use localized strings for labels and descriptions, enhancing user experience and accessibility. Update binary AIImages.dll to the latest version.

This commit is contained in:
Leonid Pershin
2025-10-26 17:21:30 +03:00
parent d5746f4c84
commit 710317e147
8 changed files with 117 additions and 22 deletions

Binary file not shown.

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>
<!-- Gizmo (button) -->
<AIImages.Gizmo.Label>AI Image</AIImages.Gizmo.Label>
<AIImages.Gizmo.Description>Open AI Image window</AIImages.Gizmo.Description>
<!-- Window -->
<AIImages.Window.Title>AI Image Window</AIImages.Window.Title>
<AIImages.Window.PawnLabel>Character: {0}</AIImages.Window.PawnLabel>
<!-- Appearance -->
<AIImages.Appearance.SectionTitle>Appearance</AIImages.Appearance.SectionTitle>
<AIImages.Appearance.NoInfo>Appearance information unavailable</AIImages.Appearance.NoInfo>
<AIImages.Appearance.Gender>Gender: {0}</AIImages.Appearance.Gender>
<AIImages.Appearance.Age>Age: {0} years</AIImages.Appearance.Age>
<AIImages.Appearance.BodyType>Body type: {0}</AIImages.Appearance.BodyType>
<AIImages.Appearance.SkinColor>Skin color: RGB({0}, {1}, {2})</AIImages.Appearance.SkinColor>
<AIImages.Appearance.Hairstyle>Hairstyle: {0}</AIImages.Appearance.Hairstyle>
<AIImages.Appearance.HairColor>Hair color: RGB({0}, {1}, {2})</AIImages.Appearance.HairColor>
<AIImages.Appearance.Traits>Traits:</AIImages.Appearance.Traits>
<!-- Apparel -->
<AIImages.Apparel.SectionTitle>Apparel</AIImages.Apparel.SectionTitle>
<AIImages.Apparel.NoInfo>Apparel information unavailable</AIImages.Apparel.NoInfo>
<AIImages.Apparel.NoClothes>Character is not wearing anything</AIImages.Apparel.NoClothes>
<AIImages.Apparel.ListHeader>Apparel ({0} items):</AIImages.Apparel.ListHeader>
<AIImages.Apparel.Quality> Quality: {0}</AIImages.Apparel.Quality>
<AIImages.Apparel.Material> Material: {0}</AIImages.Apparel.Material>
<AIImages.Apparel.Durability> Durability: {0}/{1} ({2}%)</AIImages.Apparel.Durability>
<AIImages.Apparel.Color> Color: RGB({0}, {1}, {2})</AIImages.Apparel.Color>
</LanguageData>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LanguageInfo>
<friendlyNameNative>English</friendlyNameNative>
<friendlyNameEnglish>English</friendlyNameEnglish>
<canBeTiny>true</canBeTiny>
</LanguageInfo>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>
<!-- Gizmo (кнопка) -->
<AIImages.Gizmo.Label>AI Изображение</AIImages.Gizmo.Label>
<AIImages.Gizmo.Description>Открыть окно AI изображения</AIImages.Gizmo.Description>
<!-- Окно -->
<AIImages.Window.Title>Окно AI изображения</AIImages.Window.Title>
<AIImages.Window.PawnLabel>Персонаж: {0}</AIImages.Window.PawnLabel>
<!-- Внешность -->
<AIImages.Appearance.SectionTitle>Внешность</AIImages.Appearance.SectionTitle>
<AIImages.Appearance.NoInfo>Информация о внешности недоступна</AIImages.Appearance.NoInfo>
<AIImages.Appearance.Gender>Пол: {0}</AIImages.Appearance.Gender>
<AIImages.Appearance.Age>Возраст: {0} лет</AIImages.Appearance.Age>
<AIImages.Appearance.BodyType>Тип тела: {0}</AIImages.Appearance.BodyType>
<AIImages.Appearance.SkinColor>Цвет кожи: RGB({0}, {1}, {2})</AIImages.Appearance.SkinColor>
<AIImages.Appearance.Hairstyle>Прическа: {0}</AIImages.Appearance.Hairstyle>
<AIImages.Appearance.HairColor>Цвет волос: RGB({0}, {1}, {2})</AIImages.Appearance.HairColor>
<AIImages.Appearance.Traits>Черты характера:</AIImages.Appearance.Traits>
<!-- Одежда -->
<AIImages.Apparel.SectionTitle>Одежда</AIImages.Apparel.SectionTitle>
<AIImages.Apparel.NoInfo>Информация об одежде недоступна</AIImages.Apparel.NoInfo>
<AIImages.Apparel.NoClothes>Персонаж ничего не носит</AIImages.Apparel.NoClothes>
<AIImages.Apparel.ListHeader>Одежда ({0} предметов):</AIImages.Apparel.ListHeader>
<AIImages.Apparel.Quality> Качество: {0}</AIImages.Apparel.Quality>
<AIImages.Apparel.Material> Материал: {0}</AIImages.Apparel.Material>
<AIImages.Apparel.Durability> Прочность: {0}/{1} ({2}%)</AIImages.Apparel.Durability>
<AIImages.Apparel.Color> Цвет: RGB({0}, {1}, {2})</AIImages.Apparel.Color>
</LanguageData>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LanguageInfo>
<friendlyNameNative>Русский</friendlyNameNative>
<friendlyNameEnglish>Russian</friendlyNameEnglish>
<canBeTiny>true</canBeTiny>
</LanguageInfo>

View File

@@ -43,9 +43,9 @@ namespace AIImages
{ {
yield return new Command_Action yield return new Command_Action
{ {
defaultLabel = "AI Image", defaultLabel = "AIImages.Gizmo.Label".Translate(),
defaultDesc = "Open AI Image window", defaultDesc = "AIImages.Gizmo.Description".Translate(),
icon = ContentFinder<Texture2D>.Get("UI/Commands/AttackMelee", true), icon = ContentFinder<Texture2D>.Get("UI/Commands/AIImage", true),
action = delegate() action = delegate()
{ {
// Проверяем, открыто ли уже окно AI Image // Проверяем, открыто ли уже окно AI Image

View File

@@ -79,20 +79,22 @@ namespace AIImages
private string GetAppearanceDescription() private string GetAppearanceDescription()
{ {
if (pawn?.story == null) if (pawn?.story == null)
return "Информация о внешности недоступна"; return "AIImages.Appearance.NoInfo".Translate();
StringBuilder sb = new StringBuilder(); 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) 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; Color skinColor = pawn.story.SkinColor;
sb.AppendLine( 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) 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) if (pawn.story.HairColor != null)
{ {
sb.AppendLine( 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()) 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) foreach (var trait in pawn.story.traits.allTraits)
{ {
sb.AppendLine($" • {trait.LabelCap}"); sb.AppendLine($" • {trait.LabelCap}");
@@ -135,18 +145,18 @@ namespace AIImages
private string GetApparelDescription() private string GetApparelDescription()
{ {
if (pawn?.apparel == null) if (pawn?.apparel == null)
return "Информация об одежде недоступна"; return "AIImages.Apparel.NoInfo".Translate();
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
List<Apparel> wornApparel = pawn.apparel.WornApparel; List<Apparel> wornApparel = pawn.apparel.WornApparel;
if (wornApparel == null || !wornApparel.Any()) if (wornApparel == null || !wornApparel.Any())
{ {
sb.AppendLine("Персонаж ничего не носит"); sb.AppendLine("AIImages.Apparel.NoClothes".Translate());
} }
else else
{ {
sb.AppendLine($"Одежда ({wornApparel.Count} предметов):\n"); sb.AppendLine("AIImages.Apparel.ListHeader".Translate(wornApparel.Count) + "\n");
foreach (Apparel apparel in wornApparel) foreach (Apparel apparel in wornApparel)
{ {
FormatApparelItem(sb, apparel); FormatApparelItem(sb, apparel);
@@ -165,26 +175,34 @@ namespace AIImages
if (apparel.TryGetQuality(out QualityCategory quality)) if (apparel.TryGetQuality(out QualityCategory quality))
{ {
sb.AppendLine($" Качество: {quality.GetLabel()}"); sb.AppendLine("AIImages.Apparel.Quality".Translate(quality.GetLabel()));
} }
if (apparel.Stuff != null) if (apparel.Stuff != null)
{ {
sb.AppendLine($" Материал: {apparel.Stuff.LabelCap}"); sb.AppendLine("AIImages.Apparel.Material".Translate(apparel.Stuff.LabelCap));
} }
if (apparel.HitPoints < apparel.MaxHitPoints) if (apparel.HitPoints < apparel.MaxHitPoints)
{ {
int percentage = (int)((float)apparel.HitPoints / apparel.MaxHitPoints * 100); int percentage = (int)((float)apparel.HitPoints / apparel.MaxHitPoints * 100);
sb.AppendLine( sb.AppendLine(
$" Прочность: {apparel.HitPoints}/{apparel.MaxHitPoints} ({percentage}%)" "AIImages.Apparel.Durability".Translate(
apparel.HitPoints,
apparel.MaxHitPoints,
percentage
)
); );
} }
if (apparel.DrawColor != Color.white) if (apparel.DrawColor != Color.white)
{ {
sb.AppendLine( 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; 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; curY += 45f;
// Имя пешки // Имя пешки
Text.Font = GameFont.Small; Text.Font = GameFont.Small;
Widgets.Label( Widgets.Label(
new Rect(0f, curY, inRect.width, 30f), new Rect(0f, curY, inRect.width, 30f),
"Персонаж: " + pawn.NameShortColored.Resolve() "AIImages.Window.PawnLabel".Translate(pawn.NameShortColored.Resolve())
); );
curY += 40f; curY += 40f;
@@ -227,7 +248,10 @@ namespace AIImages
// Секция "Внешность" // Секция "Внешность"
Text.Font = GameFont.Medium; 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; contentY += 35f;
Text.Font = GameFont.Small; Text.Font = GameFont.Small;
@@ -245,7 +269,10 @@ namespace AIImages
// Секция "Одежда" // Секция "Одежда"
Text.Font = GameFont.Medium; 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; contentY += 35f;
Text.Font = GameFont.Small; Text.Font = GameFont.Small;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB