using System.Collections.Generic; using System.IO; using System.Text; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using RR.Common.Managers; using RR.Common.Prizes; namespace RR.Common.UI { /// /// Страница правил, которая динамически выводит призы за уровни из настроек призовой системы. /// Повесьте компонент на GameObject страницы и назначьте TMP_Text либо оставьте поле пустым, /// чтобы компонент нашёл первый TMP_Text в дочерних объектах. /// [DisallowMultipleComponent] public sealed class RulesPrizeListPage : MonoBehaviour { [Header("Text")] [SerializeField] private TMP_Text targetText; [Header("Content")] [SerializeField] private string title = "Призы за уровни"; [SerializeField] private string emptyPrizeText = "без приза"; [SerializeField] private string noLevelsText = "Уровни не найдены."; [SerializeField] private string unavailableText = "Настройки призов недоступны."; [SerializeField] private bool showTitle = true; [SerializeField] private bool showLevelsWithoutPrize = true; [Header("Levels")] [SerializeField] private bool includeOnlyLevelsFolder = true; [SerializeField] private string levelsFolderName = "Levels"; [SerializeField] private List ignoredSceneNames = new() { "MainMenu", "Level UI" }; private void Awake() { ResolveText(); } private void OnEnable() { Refresh(); } [ContextMenu("Refresh Prize List")] public void Refresh() { ResolveText(); if (targetText == null) { Debug.LogWarning($"[{nameof(RulesPrizeListPage)}] TMP_Text не найден на странице правил.", this); return; } PrizeSystemManager manager = PrizeSystemManager.Instance; PrizeDatabase database = manager != null ? manager.Database : null; if (database == null) { targetText.text = unavailableText; return; } List levels = GetLevelSceneNames(); if (levels.Count == 0) { levels.AddRange(database.GetAll().Keys); levels.Sort(); } if (levels.Count == 0) { targetText.text = noLevelsText; return; } StringBuilder builder = new(); if (showTitle && !string.IsNullOrWhiteSpace(title)) { builder.AppendLine(title); builder.AppendLine(); } for (int i = 0; i < levels.Count; i++) { string levelName = levels[i]; LevelPrizeConfig config = database.GetConfig(levelName); if (!showLevelsWithoutPrize && (config == null || config.type == PrizeType.None)) { continue; } builder.Append(levelName); builder.Append(" — "); builder.Append(BuildPrizeText(manager, config)); if (i < levels.Count - 1) { builder.AppendLine(); } } string result = builder.ToString().TrimEnd(); targetText.text = string.IsNullOrWhiteSpace(result) ? noLevelsText : result; } private void ResolveText() { if (targetText == null) { targetText = GetComponent(); } if (targetText == null) { targetText = GetComponentInChildren(true); } } private List GetLevelSceneNames() { List result = new(); int sceneCount = SceneManager.sceneCountInBuildSettings; for (int i = 0; i < sceneCount; i++) { string scenePath = SceneUtility.GetScenePathByBuildIndex(i); if (string.IsNullOrWhiteSpace(scenePath)) { continue; } string normalizedPath = scenePath.Replace("\\", "/"); if (includeOnlyLevelsFolder) { string folderToken = $"/{levelsFolderName}/"; if (!normalizedPath.Contains(folderToken)) { continue; } } string sceneName = Path.GetFileNameWithoutExtension(scenePath); if (ignoredSceneNames != null && ignoredSceneNames.Contains(sceneName)) { continue; } result.Add(sceneName); } return result; } private string BuildPrizeText(PrizeSystemManager manager, LevelPrizeConfig config) { if (config == null || config.type == PrizeType.None) { return emptyPrizeText; } return config.type switch { PrizeType.QRCode => BuildQrPrizeText(manager, config.qrTier), PrizeType.Hopper => $"хоппер, капсул: {Mathf.Max(1, config.hopperCapsuleCount)}", PrizeType.PrizeStand => BuildPrizeStandText(manager), _ => config.type.ToString() }; } private static string BuildQrPrizeText(PrizeSystemManager manager, QRTier tier) { string tierText = tier switch { QRTier.Bronze => "бронзовый QR-код", QRTier.Silver => "серебряный QR-код", QRTier.Gold => "золотой QR-код", _ => "QR-код" }; string prizeText = manager != null ? manager.GetQRCodeModalPrizeText(tier) : string.Empty; return string.IsNullOrWhiteSpace(prizeText) ? tierText : $"{tierText}: {prizeText.Trim()}"; } private static string BuildPrizeStandText(PrizeSystemManager manager) { PrizeStandSettings settings = manager != null ? manager.GetPrizeStandSettings() : null; int boxCount = settings?.boxes != null ? settings.boxes.Count : 0; return boxCount > 0 ? $"призовая витрина, ячеек: {boxCount}" : "призовая витрина"; } } }