using System; using System.Collections.Generic; using System.IO; using System.Numerics; using AibisDream.Utility; using UnityEditor.Rendering; using UnityEngine; using Yarn.Unity; namespace AibisDream { public static class BlockPuzzleKit { /// /// 保存单个 BlockShapeData 到文件,确保 Key 唯一(如果 Key 已存在则更新,不存在则添加) /// /// 要保存的数据 /// 数据的键(用于字典存储) /// 保存路径,如果为空则使用默认路径 public static void SaveBlockShapeData(BlockShapeData data, string key, string path = null) { if (string.IsNullOrEmpty(path)) { path = ConstRef.BlockShapeDataPath; } // 确保目录存在 string directory = Path.GetDirectoryName(path); if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) { Directory.CreateDirectory(directory); } // 读取现有字典(如果文件存在) Dictionary dataDict; if (File.Exists(path)) { try { dataDict = JsonUtil.ReadBeanDict(path) ?? new Dictionary(); } catch (Exception e) { Debug.LogWarning($"读取现有 BlockShapeData 文件失败,将创建新文件: {e.Message}"); dataDict = new Dictionary(); } } else { dataDict = new Dictionary(); } // 更新或添加数据(确保 Key 唯一) dataDict[key] = data; // 保存整个字典 JsonUtil.SaveBean(dataDict, path); } /// /// 从文件加载单个 BlockShapeData /// /// 数据的键 /// 文件路径,如果为空则使用默认路径 /// 加载的数据 /// 是否加载成功 public static bool TryLoadBlockShapeData(string key, out BlockShapeData data, string path = null) { if (string.IsNullOrEmpty(path)) { path = ConstRef.BlockShapeDataPath; } try { if (!File.Exists(path)) { data = default; return false; } var dict = JsonUtil.ReadBeanDict(path); if (dict != null && dict.ContainsKey(key)) { data = dict[key]; return true; } data = default; return false; } catch (Exception e) { Debug.LogError($"加载 BlockShapeData 失败: {e.Message}"); data = default; return false; } } /// /// 从文件加载单个 BlockPuzzleData /// /// 数据的键 /// 加载的数据 /// 是否加载成功 public static bool TryLoadBlockPuzzleData(string key, out BlockPuzzleData data) { var path = ConstRef.BlockPuzzleDataPath; // 加载配置 try { if (!File.Exists(path)) { data = default; return false; } var dict = JsonUtil.ReadBeanDict(path); if (dict != null && dict.ContainsKey(key)) { data = dict[key]; return true; } data = default; return false; } catch (Exception e) { Debug.LogError($"加载 BlockPuzzleData 失败: {e.Message}"); data = default; return false; } } /// /// 保存单个 BlockPuzzleData 到文件,确保 Key 唯一(如果 Key 已存在则更新,不存在则添加) /// /// 要保存的数据 /// 数据的键(用于字典存储) /// 保存路径,如果为空则使用默认路径 public static void SaveBlockPuzzleData(BlockPuzzleData data, string key, string path = null) { if (string.IsNullOrEmpty(path)) { path = ConstRef.BlockPuzzleDataPath; } // 确保目录存在 string directory = Path.GetDirectoryName(path); if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) { Directory.CreateDirectory(directory); } // 读取现有字典(如果文件存在) Dictionary dataDict; if (File.Exists(path)) { try { dataDict = JsonUtil.ReadBeanDict(path) ?? new Dictionary(); } catch (Exception e) { Debug.LogWarning($"读取现有 BlockPuzzleData 文件失败,将创建新文件: {e.Message}"); dataDict = new Dictionary(); } } else { dataDict = new Dictionary(); } // 更新或添加数据(确保 Key 唯一) dataDict[key] = data; // 保存整个字典 JsonUtil.SaveBean(dataDict, path); } } public static class BlockPuzzleYarnCommand { [YarnCommand("init_block_puzzle")] public static void InitBlockPuzzle(string puzzleName) { if (BlockPuzzleKit.TryLoadBlockPuzzleData(puzzleName, out var blockPuzzleData)) { BlockPuzzleSystem.Instance.Initialize(blockPuzzleData); } else { Debug.LogError($"加载 BlockPuzzleData 失败: {puzzleName}"); } } [YarnCommand("clear_block_puzzle")] public static void ClearBlockPuzzle() { BlockPuzzleSystem.Instance.ClearGame(); } [YarnCommand("reset_block_puzzle")] public static void ResetBlockPuzzle() { BlockPuzzleSystem.Instance.ResetGame(); } } [Serializable] public struct BlockPuzzleData { public string puzzleName; public int gridWidth; public int gridHeight; public float cellSize; // 网格内Shape public GridShapeData[] gridShapeDataInfos; // 图形货架内Shape public RackDataInfo[] shapeRackDataInfos; // 验证器 public string validatorName; } [Serializable] public struct GridShapeData { public string shapeKey; public Vector2Int rootCell; public RotationAngle rotationAngle; public bool isDraggable; } [Serializable] public struct BlockShapeData { public int shapeId; public string shapeName; public int width; public int height; public float cellSize; public string originalPatternStr; public string spritePath; [Header("额外限制")] public bool extraLimits; public Vector2Int rootLimit; public RotationAngle rotationAngleLimit; } [Serializable] public struct RackDataInfo { public string key; public int count; } }