using System.Collections.Generic; using UnityEngine; namespace Vanguard.UI { /// /// Процедурные карточные текстуры без внешних артов: цвет клана, /// градиент, рубашка. Позже заменяется Addressables-артом. /// public static class CardArt { private static readonly Dictionary Cache = new Dictionary(); private static Sprite _back; private static Sprite _zone; public static Color ClanColor(string clan) => clan switch { "RoyalPaladin" => new Color(0.20f, 0.40f, 0.78f), "OracleThinkTank" => new Color(0.72f, 0.58f, 0.22f), "Kagero" => new Color(0.68f, 0.18f, 0.18f), "Nubatama" => new Color(0.38f, 0.22f, 0.62f), "Tachikaze" => new Color(0.22f, 0.56f, 0.34f), "NovaGrappler" => new Color(0.78f, 0.40f, 0.16f), "SpikeBrothers" => new Color(0.52f, 0.34f, 0.20f), "DarkIrregulars" => new Color(0.30f, 0.18f, 0.38f), "Granblue" => new Color(0.16f, 0.46f, 0.54f), "Megacolony" => new Color(0.40f, 0.48f, 0.18f), _ => new Color(0.28f, 0.34f, 0.46f), }; public static Sprite ForClan(string clan) { var key = "clan:" + clan; if (Cache.TryGetValue(key, out var sprite)) return sprite; var color = ClanColor(clan); sprite = Gradient( Color.Lerp(color, Color.black, 0.55f), Color.Lerp(color, Color.white, 0.18f), accent: Color.Lerp(color, Color.white, 0.35f), variant: 0); Cache[key] = sprite; return sprite; } public static Sprite ForCard(string nameId, string clan) { var key = "card:" + nameId; if (Cache.TryGetValue(key, out var sprite)) return sprite; var color = ClanColor(clan); var hash = StableHash(nameId ?? string.Empty); var accent = Color.HSVToRGB( (hash % 360) / 360f, 0.62f, 0.98f); sprite = Gradient( Color.Lerp(color, Color.black, 0.58f), Color.Lerp(color, Color.white, 0.16f), accent, (int)(hash % 5)); Cache[key] = sprite; return sprite; } private static uint StableHash(string value) { var hash = 2166136261u; foreach (var ch in value) { hash ^= ch; hash *= 16777619u; } return hash; } public static Sprite Back { get { if (_back != null) return _back; _back = BackTexture(); return _back; } } public static Sprite Zone { get { if (_zone != null) return _zone; _zone = ZoneTexture(); return _zone; } } private static Sprite ZoneTexture() { const int size = 64; var texture = new Texture2D(size, size, TextureFormat.RGBA32, false) { filterMode = FilterMode.Bilinear, wrapMode = TextureWrapMode.Clamp, }; var pixels = new Color[size * size]; var center = (size - 1) * 0.5f; for (var y = 0; y < size; y++) { for (var x = 0; x < size; x++) { var distance = Mathf.Sqrt((x - center) * (x - center) + (y - center) * (y - center)); if (distance > 30f) { pixels[y * size + x] = Color.clear; } else if (distance > 26f) { pixels[y * size + x] = new Color(0.38f, 0.52f, 0.78f, 0.9f); } else { var glow = Mathf.Clamp01(1f - distance / 26f) * 0.08f; pixels[y * size + x] = new Color( 0.04f + glow, 0.07f + glow, 0.12f + glow, 0.95f); } } } texture.SetPixels(pixels); texture.Apply(); return Sprite.Create( texture, new Rect(0f, 0f, size, size), new Vector2(0.5f, 0.5f), 100f); } private static Sprite Gradient(Color bottom, Color top, Color accent, int variant) { const int width = 32; const int height = 48; var texture = new Texture2D(width, height, TextureFormat.RGBA32, false) { filterMode = FilterMode.Bilinear, wrapMode = TextureWrapMode.Clamp, }; var pixels = new Color[width * height]; for (var y = 0; y < height; y++) { var t = y / (float)(height - 1); var row = Color.Lerp(bottom, top, t); for (var x = 0; x < width; x++) { var stripe = ((x + y + variant * 3) % 11) < 2 ? 0.12f : 0f; var glow = Mathf.Clamp01(1f - Mathf.Abs(x - width * 0.5f) / (width * 0.5f)) * 0.12f; var cx = x - width * 0.5f; var cy = y - height * 0.38f; var radius = 6f + variant; var sigil = Mathf.Abs(cx) + Mathf.Abs(cy) < radius ? 0.22f : 0f; if (variant == 2 && Mathf.Abs(cx) < 2f && Mathf.Abs(cy) < 9f) sigil += 0.18f; pixels[y * width + x] = Color.Lerp(row, accent, Mathf.Clamp01(stripe + glow + sigil)); } } texture.SetPixels(pixels); texture.Apply(); return Sprite.Create( texture, new Rect(0f, 0f, width, height), new Vector2(0.5f, 0.5f), 100f); } private static Sprite BackTexture() { const int width = 32; const int height = 48; var texture = new Texture2D(width, height, TextureFormat.RGBA32, false) { filterMode = FilterMode.Point, wrapMode = TextureWrapMode.Clamp, }; var pixels = new Color[width * height]; for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { var border = x == 0 || y == 0 || x == width - 1 || y == height - 1; var diamond = (x + y) % 8 == 0 || (x - y + 64) % 8 == 0; pixels[y * width + x] = border ? new Color(0.42f, 0.56f, 0.82f) : diamond ? new Color(0.12f, 0.22f, 0.42f) : new Color(0.05f, 0.09f, 0.17f); } } texture.SetPixels(pixels); texture.Apply(); return Sprite.Create( texture, new Rect(0f, 0f, width, height), new Vector2(0.5f, 0.5f), 100f); } } }