using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Text.RegularExpressions; using Assets.PixelFantasy.Common.Scripts.Utils; using UnityEngine; using Object = UnityEngine.Object; namespace Assets.PixelFantasy.Common.Scripts.CollectionScripts { [Serializable] public class Layer { public string Name; public Object SpriteFolder; public List Textures; private Color32[] _pixels; public Sprite GetIcon(Texture2D texture) { var size = texture.width == 576 ? 32 : 64; var icon = new Texture2D(size, size) { filterMode = FilterMode.Point }; icon.SetPixels(texture.GetPixels(0, texture.height - size, size, size)); icon.Apply(); return Sprite.Create(icon, new Rect(0, 0, size, size), Vector2.one / 2, 100); } public Color32[] GetPixels(string data, Color32[] mask = null) { var match = Regex.Match(data, @"(?[\w\- \[\]]+)(?#\w+)?(?:\/(?[-\d]+):(?[-\d]+):(?[-\d]+))?"); var name = match.Groups["Name"].Value; var index = Textures.FindIndex(i => i.name == name); var paint = Color.white; if (index == -1) return null; if (match.Groups["Paint"].Success) { ColorUtility.TryParseHtmlString(match.Groups["Paint"].Value, out paint); } float h = 0f, s = 0f, v = 0f; if (match.Groups["H"].Success && match.Groups["S"].Success && match.Groups["V"].Success) { h = float.Parse(match.Groups["H"].Value, CultureInfo.InvariantCulture); s = float.Parse(match.Groups["S"].Value, CultureInfo.InvariantCulture); v = float.Parse(match.Groups["V"].Value, CultureInfo.InvariantCulture); } return GetPixels(index, paint, h, s, v, mask); } private string _hash; public Color32[] GetPixels(int index, Color paint, float h, float s, float v, Color32[] mask) { var hash = $"{index}.{paint}.{h}.{s}.{v}.{mask}"; if (hash == _hash) return _pixels; _hash = hash; _pixels = Textures[index].GetPixels32(); if (mask != null) { for (var i = 0; i < _pixels.Length; i++) { if (mask[i].a <= 0) { _pixels[i] = new Color32(); } else if (mask[i] == Color.black) { _pixels[i] = mask[i]; } } } if (paint != Color.white) { if (Name == "Head" || Name == "Body" || Name == "Arms" || Name == "Hair") { _pixels = TextureHelper.Repaint(_pixels, Textures[index].width, Textures[index].height, paint, SpriteCollection.Palette); } else { for (var i = 0; i < _pixels.Length; i++) { if (_pixels[i].a > 0) _pixels[i] *= paint; } } } if (Mathf.Approximately(h, 0) && Mathf.Approximately(s, 0) && Mathf.Approximately(v, 0)) return _pixels; for (var i = 0; i < _pixels.Length; i++) { if (_pixels[i].a > 0 && _pixels[i] != Color.black) { _pixels[i] = TextureHelper.AdjustColor(_pixels[i], h, s, v); } } _pixels = TextureHelper.ApplyPalette(_pixels, SpriteCollection.Palette); return _pixels; } public Color[] GetPixels(int index, Color paint, float h, float s, float v, int x, int y, int blockWidth, int blockHeight) { var source = Textures[index]; var pixels = source.GetPixels(x, y, blockWidth, blockHeight); if (paint != Color.white) { for (var i = 0; i < pixels.Length; i++) { if (pixels[i].a > 0) pixels[i] *= paint; } } if (Mathf.Approximately(h, 0) && Mathf.Approximately(s, 0) && Mathf.Approximately(v, 0)) return pixels; for (var i = 0; i < pixels.Length; i++) { if (pixels[i].a <= 0) continue; pixels[i] = TextureHelper.AdjustColor(pixels[i] * paint, h, s, v); } return pixels; } #if UNITY_EDITOR public void Refresh(List palette) { var root = UnityEditor.AssetDatabase.GetAssetPath(SpriteFolder); var files = Directory.GetFiles(root, "*.png", SearchOption.AllDirectories).ToList(); Textures.Clear(); foreach (var path in files) { var texture = UnityEditor.AssetDatabase.LoadAssetAtPath(path); if (texture.width == 576 && texture.height == 928 || texture.width == 512 && texture.height == 2048) { } else { Debug.LogWarning($"Unexpected texture size: {path}, ignoring"); continue; } Textures.Add(texture); var colors = new ColorDistinctor(texture.GetPixels32()).UniqueColors; if (colors.Any(i => i.a > 0 && i.a < 255)) { Debug.LogError($"Transfluent pixels found in {path}"); } var wrong = colors.Where(i => i.a == 255 && !palette.Any(j => i.FastEquals(j))).ToList(); if (wrong.Any()) { Debug.LogError($"Colors outside of the palette found in {path}: {string.Join(",", wrong)}."); } } } #endif } }