chip-gameV3/Assets/Scripts/Common/PrizeSystem/PrizeSystemManager.cs

216 lines
7.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using PrizeSystem;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static PrizeView;
namespace PrizeSystem
{
public class PrizeSystemManager : MonoBehaviour
{
public static event Action<PrizeContainer> OnPrizesChanged;
public static event Action<bool> OnErrorStateChanged;
[Header("Звук")]
[SerializeField] private AudioClip prizeErrorSound;
[SerializeField] private List<AudioClip> PrizeNotificationSounds;
[SerializeField] private Notification prizeNotification;
private static PrizeSystemManager I;
private static bool prizingInProcess = false;
public static PrizeContainer PrizeContainer { get; private set; }
private static Queue<QrPrize> qrPrizes;
private static Queue<VitrinaPrize> vitrinaPrizes;
public static bool HasQrPrizeToGive => qrPrizes.Count > 0;
public static bool HasVitrinaPrizeToGive => vitrinaPrizes.Count > 0;
private string StartHopperCommand => "303";
private string StopHopperCommand => "302";
public static bool ErrorState => PlayerPrefs.GetInt(PrefsKeyVault.PRIZING_ERROR_REGISTRED, 0) == 1;
private PrizeContainer _defaultPrizes = new PrizeContainer
{
Sets = new List<PrizeSet>()
{
new PrizeSet() { Prizes = new List<Prize> { new EmptyPrize() } },
new PrizeSet() { Prizes = new List<Prize> { new EmptyPrize() } },
new PrizeSet() { Prizes = new List<Prize> { new EmptyPrize() } },
new PrizeSet() { Prizes = new List<Prize> { new EmptyPrize() } },
new PrizeSet() { Prizes = new List<Prize> { new QrPrize("5000 руб") } }
}
};
[SerializeField] private List<PrizeImageMap> iconsMap;
[SerializeField] private Sprite defaultIcon;
public void Initialize()
{
I = this;
PrizeSerializer.Initialize(_defaultPrizes);
PrizeContainer = PrizeSerializer.LoadFromFile();
qrPrizes = new();
vitrinaPrizes = new();
}
public static QrPrize DequeueQrPrize() => HasQrPrizeToGive ? qrPrizes.Dequeue() : null;
public static VitrinaPrize DequeueVitrinaPrize() => HasVitrinaPrizeToGive ? vitrinaPrizes.Dequeue() : null;
public static void SavePrizes()
{
OnPrizesChanged?.Invoke(PrizeContainer);
}
public static void GivePrize(Prize prize)
{
bool prizingEnabled = SettingsManager.GetBool(SettingKey.PRIZING);
if (prizingEnabled == false) return;
if (prize == null)
{
Debug.Log("Приз Null"); return;
}
if (prize is EmptyPrize)
{
Debug.Log("Пустой приз. Возврат.");
return;
}
else if (prize is CountablePrize countablePrize)
{
I.StartCoroutine(I.GiveCountablePrizeCoroutine(countablePrize.Amount, countablePrize.Type));
}
else if (prize is VitrinaPrize vitrinaPrize)
{
vitrinaPrizes.Enqueue(vitrinaPrize);
}
else if (prize is QrPrize qrPrize)
{
qrPrizes.Enqueue(qrPrize);
}
}
private IEnumerator GiveCountablePrizeCoroutine(int amount, CountablePrizeType Type)
{
if (prizingInProcess)
{
Debug.LogError("Уже идет выдача приза. Повторная выдача отключена");
yield break;
}
prizingInProcess = true;
Debug.Log($"Выдача приза {Type}. Количество: {amount}");
bool atLeastOnePrize = false;
for (int i = 0; i < amount; i++)
{
bool noPrizWhenError = SettingsManager.GetBool(SettingKey.PRIZING_WHEN_ERROR);
bool errorRegistred = PlayerPrefs.GetInt(PrefsKeyVault.PRIZING_ERROR_REGISTRED, 0) == 1;
if (errorRegistred && noPrizWhenError) yield break;
PlayerPrefs.SetInt(PrefsKeyVault.PRIZE_GIVEN_BUFFER, 0);
ComWrapper.Send(StartHopperCommand);
float startTime = Time.time;
bool success = false;
float timeout = 10;
while (Time.time - startTime < timeout)
{
if (PlayerPrefs.GetInt(PrefsKeyVault.PRIZE_GIVEN_BUFFER, 0) == 1)
{
success = true;
break;
}
yield return null;
}
ComWrapper.Send(StopHopperCommand);
if (success)
{
//контроль остатков
int prizesCount = PlayerPrefs.GetInt(PrefsKeyVault.PRIZES_AVAILABLE);
prizesCount = Mathf.Clamp(prizesCount - 1, 0, 9999);
PlayerPrefs.SetInt(PrefsKeyVault.PRIZES_AVAILABLE, prizesCount);
//Счетчики
IncreasePrizeCounters(Type);
//хотя бы что то успешно выпало
atLeastOnePrize = true;
}
else
{
SetPrizingError(true);
SoundManager.instance.playClip(prizeErrorSound);
}
}
if (atLeastOnePrize)
{
NotificationSystem.instance.Notificate(prizeNotification);
SoundNotificationIfNeeds();
}
prizingInProcess = false;
}
public static void SetPrizingError(bool error)
{
PlayerPrefs.SetInt(PrefsKeyVault.PRIZING_ERROR_REGISTRED, error ? 1 : 0);
OnErrorStateChanged?.Invoke(error);
}
private void IncreasePrizeCounters(CountablePrizeType Type)
{
string prizeCounterKey = Type switch
{
CountablePrizeType.Marbles => PrefsKeyVault.MARBLES_GIVEN_COUNTER,
CountablePrizeType.Hopper => PrefsKeyVault.HOPPER_GIVEN_COUNTER,
CountablePrizeType.Hopper2 => PrefsKeyVault.HOPPER_GIVEN_COUNTER,
CountablePrizeType.Ticket => PrefsKeyVault.TICKET_GIVEN_COUNTER,
_ => "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(PrefsKeyVault.HOPPER_GIVEN_COUNTER + "Nullable", 0);
PlayerPrefs.SetInt(PrefsKeyVault.MARBLES_GIVEN_COUNTER + "Nullable", 0);
PlayerPrefs.SetInt(PrefsKeyVault.TICKET_GIVEN_COUNTER + "Nullable", 0);
PlayerPrefs.SetInt(PrefsKeyVault.SPECIAL_GIVEN_COUNTER + "Nullable", 0);
}
private void SoundNotificationIfNeeds()
{
if (PrizeNotificationSounds == null || PrizeNotificationSounds.Count == 0) return;
int random = UnityEngine.Random.Range(0, PrizeNotificationSounds.Count);
AudioClip notification = PrizeNotificationSounds[random];
SoundManager.instance.playClip(notification);
}
public static Sprite GetPrizeIcon(PrizeType prizeType)
{
foreach (var mapItem in I.iconsMap)
if (mapItem.prizeType == prizeType) return mapItem.sprite;
return I.defaultIcon;
}
}
}
[Serializable]
public struct PrizeImageMap
{
public PrizeType prizeType;
public Sprite sprite;
}