using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
///
/// Система управления выдачей призов и ведения статистики игры.
/// Отвечает за процесс выдачи призов, подсчет запусков и наград.
///
public class PrizeSystem : MonoBehaviour
{
[SerializeField] AudioClip prizeErrorSound;
[SerializeField] bool SoundNotification = true;
[SerializeField] List PrizeNotificationSounds;
[SerializeField] Notification prizeNotification;
public static string key_cash = "STARTS";
public static string key_cashNul = "STARTSNUL";
public static string key_prizesgiven = "PRIZESGIVEN";
public static string key_prizesgivenNul = "PRIZESGIVENNUL";
public static string HopperPrizeCounter = "HopperCounter";
public static string MarblesPrizeCounter = "MarblesCounter";
public static string TicketPrizeCounter = "TicketCounter";
public static string SpecialPrizeCounter = "SpecialCounter";
private static PrizeSystem instance;
private static bool prizing = false;
//===========================start: PUBLIC API===========================//
public void Initialize()
{
instance = this;
InitCounters();
}
public static void GivePrize(Prize prize)
{
bool settingEnabled = SettingsManager.GetBool("Prizing", false);
if (!settingEnabled) { Debug.Log("Выдача приза отключена в настройках"); return; }
if (prizing) { Debug.LogError("Уже идет выдача приза. Не спамь кнопку."); return; }
Debug.Log($"Поступил заказ приз: {prize}");
PrizeType prizeType = prize.PrizeType;
if (prizeType == PrizeType.None)
{
Debug.Log("Пустой приз. Возврат.");
return;
}
else if (prizeType == PrizeType.Special)
{
PlayerPrefs.SetInt("NeedSpecialPrize", 1);
}
else
{
instance.StartCoroutine(instance.PrizingProcess(prize.Amount, prizeType));
}
}
//===========================end: PUBLIC API===========================//
#region Приватные методы
private IEnumerator PrizingProcess(int amount, PrizeType Type)
{
Debug.Log($"Выдача приза {Type}. Количество: {amount}");
prizing = true;
bool atLeastOnePrize = false;
for (int i = 0; i < amount; i++)
{
bool noPrizWhenError = SettingsManager.GetBool("PrizingWhenError", true);
bool errorRegistred = PlayerPrefs.GetInt(KeyVault.PRIZING_ERROR_REGISTRED, 0) == 1;
if (errorRegistred && noPrizWhenError) yield break;
float timeout = 10;
string enableMotorComand = ComWrapper.BoardVersion switch
{
1 => "303",
2 => "301",
_ => "303"
};
Debug.Log($"Включаю мотор хоппера: {enableMotorComand}");
ComWrapper.Send(enableMotorComand);//включаем мотор
float startTime = Time.time;
bool success = false;
PlayerPrefs.SetInt("PrizeGivenBuffer", 0);//подготовка буфера
while (Time.time - startTime < timeout)
{
if (PlayerPrefs.GetInt("PrizeGivenBuffer", 0) == 1)
{
Debug.Log("Считан приз");
success = true;
break;
}
yield return null;
}
//Выключаем мотор
string disableMotorComand = ComWrapper.BoardVersion switch
{
1 => "302",
2 => "300",
_ => "302"
};
Debug.Log($"Выключаю мотор: {disableMotorComand}");
ComWrapper.Send(disableMotorComand);
Debug.Log("Закончил. Успех: " + success);
prizing = false;
if (success)
{
//контроль остатков
int prizesCount = PlayerPrefs.GetInt(KeyVault.PRIZES_AVAILABLE);
prizesCount = Mathf.Clamp(prizesCount - 1, 0, 9999);
PlayerPrefs.SetInt(KeyVault.PRIZES_AVAILABLE, prizesCount);
//Счетчики
IncreasePrizeCounters(Type);
//хотя бы что то успешно выпало
atLeastOnePrize = true;
}
else
{
PlayerPrefs.SetInt(KeyVault.PRIZING_ERROR_REGISTRED, 1);
SoundManager.instance.playClip(prizeErrorSound);
}
}
if (atLeastOnePrize)
{
NotificationSystem.instance.Notificate(prizeNotification);
SoundNotificationIfNeeds();
}
}
void IncreasePrizeCounters(PrizeType Type)
{
string prizeCounterKey = Type switch
{
PrizeType.Special => SpecialPrizeCounter,
PrizeType.Marbles => MarblesPrizeCounter,
PrizeType.Hopper => HopperPrizeCounter,
PrizeType.Hopper2 => HopperPrizeCounter,
PrizeType.Ticket => TicketPrizeCounter,
_ => "none"};
string prizeCounterKeyNullable = prizeCounterKey + "Nullable";
PlayerPrefs.SetInt(prizeCounterKey, PlayerPrefs.GetInt(prizeCounterKey, 0) + 1);
PlayerPrefs.SetInt(prizeCounterKeyNullable, PlayerPrefs.GetInt(prizeCounterKeyNullable, 0) + 1);
}
public static void ResetPrizeCounters()
{
PlayerPrefs.SetInt(HopperPrizeCounter + "Nullable", 0);
PlayerPrefs.SetInt(MarblesPrizeCounter + "Nullable", 0);
PlayerPrefs.SetInt(TicketPrizeCounter + "Nullable", 0);
PlayerPrefs.SetInt(SpecialPrizeCounter + "Nullable", 0);
}
public static string GetPrizesCounterNullableString()
{
StringBuilder sb = new();
sb.Append($"Х: {PlayerPrefs.GetInt(HopperPrizeCounter + "Nullable", 0)}. ");
sb.Append($"Т: {PlayerPrefs.GetInt(TicketPrizeCounter + "Nullable", 0)}. ");
sb.Append($"М: {PlayerPrefs.GetInt(MarblesPrizeCounter + "Nullable", 0)}. ");
sb.Append($"С: {PlayerPrefs.GetInt(SpecialPrizeCounter + "Nullable", 0)}. ");
return sb.ToString();
}
public static string GetPrizesCounterString()
{
StringBuilder sb = new();
sb.Append($"Х: {PlayerPrefs.GetInt(HopperPrizeCounter, 0)}. ");
sb.Append($"Т: {PlayerPrefs.GetInt(TicketPrizeCounter, 0)}. ");
sb.Append($"М: {PlayerPrefs.GetInt(MarblesPrizeCounter, 0)}. ");
sb.Append($"С: {PlayerPrefs.GetInt(SpecialPrizeCounter, 0)}. ");
return sb.ToString();
}
void InitCounters()
{
if (!PlayerPrefs.HasKey(key_cash)) PlayerPrefs.SetInt(key_cash, 0);
if (!PlayerPrefs.HasKey(key_cashNul)) PlayerPrefs.SetInt(key_cashNul, 0);
}
private void SoundNotificationIfNeeds()
{
if(!SoundNotification) return;
if (PrizeNotificationSounds == null || PrizeNotificationSounds.Count == 0) return;
int random = Random.Range(0, PrizeNotificationSounds.Count);
AudioClip notification = PrizeNotificationSounds[random];
SoundManager.instance.playClip(notification);
}
#endregion
}