134 lines
5.0 KiB
C#
134 lines
5.0 KiB
C#
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
namespace Vanguard.UI
|
||
{
|
||
/// <summary>
|
||
/// Загрузка настоящих артов по imageKey. Соглашение: спрайт лежит в
|
||
/// Assets/Vanguard/Resources/CardArt/{imageKey}.png. Пока файла нет —
|
||
/// используется процедурный CardArt. Позже этот же вход можно
|
||
/// перевести на Addressables без изменения экранов.
|
||
/// </summary>
|
||
public static class CardImageService
|
||
{
|
||
private const string ResourceFolder = "CardArt/";
|
||
private static readonly Dictionary<string, Sprite> Cache =
|
||
new Dictionary<string, Sprite>();
|
||
private static readonly Dictionary<string, Sprite> IllustrationCache =
|
||
new Dictionary<string, Sprite>();
|
||
|
||
/// <summary>Доля высоты карты, занятая иллюстрацией (до полосы флейвора).</summary>
|
||
public const float IllustrationHeight = 0.59f;
|
||
|
||
public static void Apply(Image target, string imageKey, Sprite fallback)
|
||
{
|
||
if (target == null)
|
||
return;
|
||
|
||
var sprite = Resolve(imageKey, fallback);
|
||
target.sprite = sprite;
|
||
target.color = Color.white;
|
||
target.preserveAspect = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Превью только иллюстрации: верхняя часть карты без рамки, имени и
|
||
/// текста способности. Пропорции сохраняются.
|
||
/// </summary>
|
||
public static void ApplyIllustration(Image target, string imageKey, Sprite fallback)
|
||
{
|
||
if (target == null)
|
||
return;
|
||
|
||
var sprite = ResolveIllustration(imageKey, fallback);
|
||
target.sprite = sprite;
|
||
target.color = Color.white;
|
||
target.preserveAspect = true;
|
||
}
|
||
|
||
/// <summary>Спрайт иллюстрации (обрезанная верхняя часть карты).</summary>
|
||
public static Sprite ResolveIllustration(string imageKey, Sprite fallback)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(imageKey))
|
||
return fallback;
|
||
|
||
if (IllustrationCache.TryGetValue(imageKey, out var cached))
|
||
return cached != null ? cached : fallback;
|
||
|
||
var texture = Resources.Load<Texture2D>(ResourceFolder + imageKey);
|
||
if (texture == null)
|
||
{
|
||
IllustrationCache[imageKey] = null;
|
||
return fallback;
|
||
}
|
||
|
||
var height = Mathf.Max(1, Mathf.RoundToInt(texture.height * IllustrationHeight));
|
||
var sprite = Sprite.Create(
|
||
texture,
|
||
new Rect(0f, texture.height - height, texture.width, height),
|
||
new Vector2(0.5f, 0.5f),
|
||
100f);
|
||
sprite.name = imageKey + "_illustration";
|
||
IllustrationCache[imageKey] = sprite;
|
||
return sprite;
|
||
}
|
||
|
||
/// <summary>Спрайт реального арта или процедурный fallback.</summary>
|
||
public static Sprite Resolve(string imageKey, Sprite fallback)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(imageKey))
|
||
return fallback;
|
||
|
||
if (Cache.TryGetValue(imageKey, out var cached))
|
||
return cached != null ? cached : fallback;
|
||
|
||
var texture = Resources.Load<Texture2D>(ResourceFolder + imageKey);
|
||
if (texture == null)
|
||
{
|
||
Cache[imageKey] = null;
|
||
return fallback;
|
||
}
|
||
|
||
var sprite = Sprite.Create(
|
||
texture,
|
||
new Rect(0f, 0f, texture.width, texture.height),
|
||
new Vector2(0.5f, 0.5f),
|
||
100f);
|
||
Cache[imageKey] = sprite;
|
||
return sprite;
|
||
}
|
||
|
||
/// <summary>
|
||
/// "BT01/042EN" → "bt01_042". Нужно, когда каталог ещё не загрузился,
|
||
/// а арт уже лежит в Resources/CardArt.
|
||
/// </summary>
|
||
public static string ImageKeyForPrinting(string printingId)
|
||
{
|
||
if (string.IsNullOrEmpty(printingId))
|
||
return null;
|
||
|
||
var slash = printingId.IndexOf('/');
|
||
if (slash <= 0 || slash >= printingId.Length - 1)
|
||
return null;
|
||
|
||
var set = printingId.Substring(0, slash).ToLowerInvariant();
|
||
var tail = printingId.Substring(slash + 1);
|
||
var number = string.Empty;
|
||
for (var i = 0; i < tail.Length; i++)
|
||
{
|
||
var c = tail[i];
|
||
if (char.IsDigit(c) || (i == 0 && (c == 'S' || c == 's')))
|
||
{
|
||
number += char.ToLowerInvariant(c);
|
||
continue;
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
return number.Length > 0 ? set + "_" + number : null;
|
||
}
|
||
}
|
||
}
|