Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
- завершен спринт 24 марта - 2 апреля с опережением плана и закрытием задач раньше срока - расширена и стабилизирована система призов: добавлены и доработаны QR-tier конфиги, новые типы и модели данных, сохранение `qrCodes` в `prizes.json`, fallback-логика и синхронизация через `PrizeSystemManager`, `PrizeDatabase` и `LevelPrizeConfig` - переработан flow настройки QR-призов: добавлены `QRCodeSettingsModal` и связанный UI-код, разнесены короткий текст приза и полный текст сообщения, добавлены шаблоны форматирования, корректная подстановка текста в QR и в UI-модалках, а также сохранение конфигурации между запусками - доработан flow суперприза и текстовых настроек: добавлены fallback-правила показа, корректная обработка пустых строк и строк из одних пробелов, обновлены binders и показ текста в меню - реализована и обновлена отдельная настройка витрины: добавлена `PrizeStandSettingsModal`, обновлена навигация строк, логика выбора ячейки и порогов очков, циклический выбор ячеек, ускорение изменения значений и исправления для keyboard/gamepad UX - доработана игровая модалка витрины `PrizeStandModal`: добавлен вывод очков игрока, форматируемый текст счета, улучшено отображение ячеек и связанная логика выбора приза - исправлен подсчет очков и интеграция с prize flow: `ScoreSystem` переведен на событийное обновление текущего счета, добавлены `CurrentScore`, `CurrentScoreChanged` и корректный display score, витрина и связанные UI-элементы теперь получают актуальные очки, а не нулевые или несвоевременные preview-значения - переработаны модальные окна и навигация UI: улучшены `Modal`, `ModalManager`, `UIRowPointer`, `RulesModal`, `QRCodeModal`, `PrizeStandModal`, `LevelPrizeSettingsModal` и др., чтобы фокус, указатель и submit работали консистентно без мыши - обновлен win/prize UI: доработаны `WinBannerController`, `GameEndUIController`, `MainMenu`, `QRCodeUIController`, `TopPanelTextController` и настройки UI, улучшены тексты баннеров, отображение призов и итогового счета - обновлены сцены и ассеты под новый flow: `MainMenu`, `Level UI`, prefab'ы строк настроек и кнопок, глобальные префабы, шрифты TMP, иконки, recovery-данные и ресурсы UI - добавлены вспомогательные UI-компоненты и служебные скрипты: `ButtonTextFocusColor`, `SelectableDescriptionTarget`, `QRTier` и другие изменения, поддерживающие новый конфигурируемый prize UI
80 lines
3.0 KiB
C#
80 lines
3.0 KiB
C#
using System;
|
||
using UnityEngine;
|
||
using RR.Common.UI;
|
||
using RR.Game2D.Behaviour;
|
||
using RR.Game2D.Core.Managers;
|
||
|
||
namespace RR.Common.Prizes
|
||
{
|
||
/// <summary>
|
||
/// Исполнитель приза «QR-код».
|
||
/// Показывает модальное окно с QR-кодами. Сами QR-коды получает через делегат —
|
||
/// не знает откуда они берутся.
|
||
/// </summary>
|
||
public class QRCodePrize : PrizeBase
|
||
{
|
||
public override PrizeType Type => PrizeType.QRCode;
|
||
public override bool IsGiving => _isGiving;
|
||
|
||
private readonly Func<QRCodeModal> _resolveModal;
|
||
private readonly Func<QRTier, Texture2D[]> _getQRCodes;
|
||
private bool _isGiving;
|
||
private QRCodeModal _activeModal;
|
||
|
||
/// <param name="resolveModal">Делегат для поиска модального окна в текущих сценах.</param>
|
||
/// <param name="getQRCodes">Делегат получения QR-текстур.</param>
|
||
public QRCodePrize(Func<QRCodeModal> resolveModal, Func<QRTier, Texture2D[]> getQRCodes)
|
||
{
|
||
_resolveModal = resolveModal;
|
||
_getQRCodes = getQRCodes;
|
||
}
|
||
|
||
public override void Execute(MonoBehaviour host, LevelPrizeConfig config)
|
||
{
|
||
Texture2D[] codes = _getQRCodes?.Invoke(config != null ? config.qrTier : QRTier.None);
|
||
|
||
if (codes == null || codes.Length == 0)
|
||
{
|
||
Debug.LogWarning("[QRCodePrize] Нет QR-кодов для отображения.");
|
||
InvokeResult(false);
|
||
return;
|
||
}
|
||
|
||
QRCodeModal modal = _resolveModal?.Invoke();
|
||
if (modal == null)
|
||
{
|
||
Debug.LogWarning("[QRCodePrize] QRCodeModal не найден на сцене.");
|
||
InvokeResult(false);
|
||
return;
|
||
}
|
||
|
||
_isGiving = true;
|
||
bool showFinalScore = GameManager.Instance != null && GameManager.Instance.IsCurrentLevelFinal();
|
||
float gameTime = GameManager.Instance != null ? GameManager.Instance.GetPendingOrCurrentWinGameTime() : 0f;
|
||
int finalScore = showFinalScore && ScoreSystem.Instance != null
|
||
? ScoreSystem.Instance.CalculatePreviewScore(gameTime, true)
|
||
: 0;
|
||
|
||
// Отписываемся от предыдущего, если было
|
||
if (_activeModal != null)
|
||
_activeModal.OnClosed -= OnModalClosed;
|
||
|
||
_activeModal = modal;
|
||
_activeModal.OnClosed += OnModalClosed;
|
||
_activeModal.ShowQRCodes(codes, config != null ? config.qrTier : QRTier.None, gameTime, finalScore, showFinalScore);
|
||
}
|
||
|
||
private void OnModalClosed()
|
||
{
|
||
if (_activeModal != null)
|
||
{
|
||
_activeModal.OnClosed -= OnModalClosed;
|
||
_activeModal = null;
|
||
}
|
||
|
||
_isGiving = false;
|
||
InvokeResult(true);
|
||
}
|
||
}
|
||
}
|