using System; using System.Collections.Generic; using UnityEngine; namespace DanroJump.Prizes { /// /// Сериализуемая таблица призов, привязанная к набранным очкам. /// [Serializable] public sealed class PrizeLevelTable { [SerializeField] private List levels = new(); public IReadOnlyList Levels => levels; public int Count => levels.Count; public static PrizeLevelTable FromJson(string json) { if (string.IsNullOrWhiteSpace(json)) { return new PrizeLevelTable(); } try { var table = JsonUtility.FromJson(json); table ??= new PrizeLevelTable(); table.Normalize(); return table; } catch (ArgumentException) { return new PrizeLevelTable(); } } public string ToJson() { Normalize(); return JsonUtility.ToJson(this); } public PrizeRewardKind ResolveRewardKind(int score) { Normalize(); var sanitizedScore = Mathf.Max(0, score); var rewardKind = PrizeRewardKind.None; foreach (var level in levels) { if (level.Score > sanitizedScore) { break; } rewardKind = level.RewardKind; } return rewardKind; } public void Upsert(int score, PrizeRewardKind rewardKind) { var sanitizedScore = Mathf.Max(0, score); for (var index = 0; index < levels.Count; index++) { if (levels[index].Score == sanitizedScore) { levels[index] = new PrizeLevelEntry(sanitizedScore, rewardKind); Normalize(); return; } } levels.Add(new PrizeLevelEntry(sanitizedScore, rewardKind)); Normalize(); } public bool RemoveAt(int index) { Normalize(); if (index < 0 || index >= levels.Count) { return false; } levels.RemoveAt(index); return true; } private void Normalize() { levels ??= new List(); for (var index = 0; index < levels.Count; index++) { var level = levels[index]; levels[index] = new PrizeLevelEntry(level.Score, SanitizeKind(level.RewardKind)); } levels.Sort(static (left, right) => left.Score.CompareTo(right.Score)); for (var index = levels.Count - 2; index >= 0; index--) { if (levels[index].Score == levels[index + 1].Score) { levels.RemoveAt(index); } } } private static PrizeRewardKind SanitizeKind(PrizeRewardKind rewardKind) { return Enum.IsDefined(typeof(PrizeRewardKind), rewardKind) ? rewardKind : PrizeRewardKind.None; } } }