chip-gameV3/Assets/Scripts/Common/GameManager.cs

601 lines
18 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 CharacterSystem;
using PrizeSystem;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum GameMode { pve, pvp }
public class GameManager : MonoBehaviour
{
public static event Action<GameMode> OnGameStarted;
public static event Action<GameMode> OnGameFinished;
public event Action OnRoundStarted;
public PlayerStatsService StatsService;
public int botsAmount = 5;
[Header("General")]
public static GameManager Instance;
public GameObject AdminPanel, NumberPanel;
public TimerManager timerManager;
public RulesController rulesController;
public ChipPointer chipPointer;
[Header("Menu")]
public GameMode gameMode;
[HideInInspector] public Team currentPlayer = Team.Player2;
[Header("Scores")]
public int player1score = 0, player2score = 0, vsBotScore = 0;
private bool increaseVsBotTimer = false;
public int vsBotMoves;
public float vsBotThinkTime;
[HideInInspector]
public CheckResult lastResult;
[Header("Gameplay")]
public GameObject player1Chip;
public GameObject player2Chip;
public GameObject botChip;
public Chip chipPrefab;
[HideInInspector] public Chip currentChip;
public bool canReturnToMenu = false; //todo: разобраться нафига эта переменная
[Header("Панели ввода")]
public TextInput nameInput;
public Leaderboard leaderboard;
public GameObject CharactersConfigurator;
[Header("Переходы")]
[SerializeField] private MenuGameplayTransit menuGameplayTransit;
[SerializeField] private BackToMenuController _backToMenu;
[SerializeField] TurnManager turnManager;
[SerializeField] private FieldCleaner _fieldCleaner;
public EndGameHandler endGameHandler;
public TurnTracker turnTracker;
public GameObject setPasswordPanel;
//public EnterPasswordPanel enterPasswordPanel;
public VitrinaPanel vitrinaPanel;
public QrPanel qrPanel;
public TakeOrRiskPanel takeOrRiskPanel;
private const int PvpWinningScore = 5;
private const int VictoryNameLength = 10;
private bool _isLeavingGameplay;
private int _paidEntryAmount;
private bool _canRefundEntry;
private bool _returnToMenuAfterPrize;
public void Initialize()
{
if (Instance == null)
{
Instance = this;
}
ComWrapper.PaymentReceived += ProcessDifficultyCounter;
ProcessDifficultyCounter();
SettingsManager.OnSettingsChanged+=ProcessDifficultyCounter;
StatsService = new();
StatsService.Initialize();
timerManager.TimerEnded -= turnManager.HandleTimerEnded;
timerManager.TimerEnded += turnManager.HandleTimerEnded;
StartCoroutine(AddBotRecordEvery2Days());// добавлять каждые 2 дня запись
//stateMachine.ChangeState(new MenuState());
}
public void TryEnterGame(GameMode mode)
{
int entryPrice = PaymentSystem.GetModePrice(mode);
if (!PaymentSystem.TryPayForMode(mode))
return;
_paidEntryAmount = PaymentSystem.Freeplay ? 0 : entryPrice;
_canRefundEntry = true;
SetMode(mode);
_isLeavingGameplay = false;
if (mode == GameMode.pvp)
{
ResetPvpScores();
CharactersController.I.SuspendForPvp();
}
if (mode == GameMode.pve)
CharactersController.I.ApplyFirstCharacterColorsToBoard();
else
Board.Instance.ApplyPvpColors();
menuGameplayTransit.GameplayOpened += OnGameplayOpened;
menuGameplayTransit.GotoGameplay();
ControlsPerformer.Instance.SetControlable(null);
}
void OnGameplayOpened()
{
menuGameplayTransit.GameplayOpened -= OnGameplayOpened;
turnTracker.ResetTracking();
_backToMenu.Show();
OnGameStarted?.Invoke(gameMode);
if (gameMode == GameMode.pve)
{
_fieldCleaner.Clear();
CharactersController.I.StartSession(StartRound);
}
else
{
if (DualAvatarController.Instance != null)
DualAvatarController.Instance.ShowCharacters(StartRound);
else
StartRound();
}
}
private void OnApplicationQuit() => ComNativeWrapper.Serial_CloseAll();
private void Update()
{
if (increaseVsBotTimer)
vsBotThinkTime += Time.deltaTime;
}
private void OnDestroy()
{
if (timerManager != null && turnManager != null)
timerManager.TimerEnded -= turnManager.HandleTimerEnded;
if (nameInput != null)
nameInput.OnComplete -= HandleVictoryNameEntered;
UnsubscribeFromPrizePanels();
}
public void GotoMenu()
{
if (_isLeavingGameplay)
return;
RefundEntryIfAvailable();
_isLeavingGameplay = true;
CancelPrizeFlow();
ControlsPerformer.Instance.SetControlable(null);
timerManager.HideBars();
VideoUtility.CrossFadeToMenu();
turnManager.CancelPlayerPreparation();
_fieldCleaner.Clear();
if (gameMode == GameMode.pve)
{
CharactersController.I.ReturnToMenu();
}
else
{
DualAvatarController.Instance?.HideCharacters();
CharactersController.I.PreloadMenuCharacter();
}
OnGameFinished?.Invoke(gameMode);
menuGameplayTransit.GotoMenu();
}
public void StartVsBotTimer() => increaseVsBotTimer = true;
public void StopVsBotTimer() => increaseVsBotTimer = false;
public void SwitchPlayer()
{
currentPlayer = currentPlayer == Team.Player1 ? Team.Player2 : Team.Player1;
}
public void SetMode(GameMode mode) => gameMode = mode;
public void EnableEarlyMenuExit() => _backToMenu.EnableExit();
public void DisableEarlyMenuExit()
{
_paidEntryAmount = 0;
_canRefundEntry = false;
_backToMenu.Hide();
}
public void PerformRevenge()
=> ContinueAfterPveLoss();
public void PerformDrawRevenge()
=> ContinueAfterPveDraw();
public void ContinueAfterPveWin()
{
if (CharactersController.HasActiveCharacter)
CharactersController.CurrentCharacter.difficultyModule.IncreaseDifficulty();
int nextCharacterIndex = CharactersController.CharacterIndex + 1;
if (nextCharacterIndex >= CharactersController.CharactersAmount)
{
GotoMenu();
return;
}
StartPveRound(nextCharacterIndex);
}
public bool TryStartPvePrizeFlow()
{
if (gameMode != GameMode.pve
|| !SettingsManager.GetBool(SettingKey.PRIZING)
|| !CharactersController.HasActiveCharacter)
return false;
if (!CharactersController.I.TryFetchCurrentPrizes(out List<Prize> configuredPrizes))
return false;
List<Prize> availablePrizes = GetAvailablePrizes(configuredPrizes);
if (availablePrizes.Count == 0)
return false;
bool isLastBot = CharactersController.CharacterIndex >= CharactersController.CharactersAmount - 1;
bool takeOrRiskEnabled = SettingsManager.GetBool(SettingKey.TAKE_OR_RISK);
bool continueAvailable = takeOrRiskEnabled && !isLastBot;
_returnToMenuAfterPrize = continueAvailable;
if (availablePrizes.Count > 1 || continueAvailable)
{
SubscribeToPrizePanels();
takeOrRiskPanel.Open(availablePrizes, continueAvailable, GetNextBotPrize());
}
else
{
StartPrizeIssue(availablePrizes[0]);
}
return true;
}
public void ShowFinalVictoryNameInput()
{
ControlsPerformer.Instance.SetControlable(null);
nameInput.OnComplete -= HandleVictoryNameEntered;
nameInput.OnComplete += HandleVictoryNameEntered;
nameInput.SetDestroyOnComplete(false);
nameInput.gameObject.SetActive(true);
nameInput.Initialize(VictoryNameLength, Alphabets.RUS_AND_DIGITS);
ControlsPerformer.Instance.SetControlable(nameInput);
}
public void ContinueAfterPveLoss()
{
if (CharactersController.HasActiveCharacter)
CharactersController.CurrentCharacter.difficultyModule.DecreaseDifficulty();
int previousCharacterIndex = Mathf.Max(CharactersController.CharacterIndex - 1, 0);
StartPveRound(previousCharacterIndex);
}
public void ContinueAfterPveDraw()
=> StartPveRound(CharactersController.CharacterIndex);
public void ContinueAfterPvpRound()
{
_fieldCleaner.Clear();
StartRound();
}
public void RestartPvpMatch()
{
ResetPvpScores();
ContinueAfterPvpRound();
}
public void IncreaseScore(Team player)
{
if (player == Team.Player1)
player1score += 1;
else
player2score += 1;
timerManager.RefreshPvpScores();
}
public bool HasPvpMatchWinner(Team player)
=> player == Team.Player1 ? player1score >= PvpWinningScore : player2score >= PvpWinningScore;
public void ProcessDifficultyCounter()//вызывается каждый раз, когда приходит COIN с платы или обновились настройки
{
string previous = PlayerPrefs.GetString("PreviousBaseBotDifficulty", "Прохождение");
string difficultyType = SettingsManager.GetString(SettingKey.DIFFICULTY_MODE);
//Инициализация
if (!PlayerPrefs.HasKey("PulsesToResetDifficulty"))
PlayerPrefs.SetInt("PulsesToResetDifficulty", 100);
//если переход с повышенной на обычную - сброс счетчика
if (previous == "Заработок" && difficultyType != previous)
{
PaymentSystem.ResetPulsesCounter();
}
PlayerPrefs.SetString("PreviousBaseBotDifficulty", difficultyType);
if (difficultyType == "Заработок")
{
int pulses = PaymentSystem.PulsesCounter;
int pulsesToResetDifficulty = PlayerPrefs.GetInt("PulsesToResetDifficulty", 10);
//todo: разобраться
//if (pulses >= pulsesToResetDifficulty)
//{
// PaymentSystem.ResetPulsesCounter();
//Setting difficultySetting = SettingsManager.Container.TryGetSetting(SettingKeys.DIFFICULTY_MODE);
// difficultySetting.StringValue = "Прохождение";
// SettingsManager.OnSettingsChanged?.Invoke();
// SettingsManager.SaveContainerToFile();
// AdminPanel.GetComponent<SettingsScreen>().RefreshViews();
// print("Сложность сброшена");
//}
}
}
public void PrepareRound(Team firstPlayer)
{
currentPlayer = firstPlayer;
timerManager.SetupTimers(gameMode);
if (gameMode == GameMode.pve)
{
timerManager.SetActiveTimer(Team.Player1);
}
VitrinaView.Instance.ActivateIfNeed();
DetermineNextTurn(switchPlayer: false);
}
public void DetermineNextTurn(bool switchPlayer = true)
{
if (switchPlayer) SwitchPlayer();
//spawnChip();
if (gameMode == GameMode.pvp)//переключаем таймеры только в pvp
{
timerManager.SetActiveTimer(currentPlayer);
LightSystem.Player(currentPlayer);
}
}
public void ResetGameSession()
{
vsBotThinkTime = 0;
StopVsBotTimer();
vsBotMoves = 0;
//movesAndTimeCounter.SetVisibility(false);
CharactersController.I.ReturnToMenu();
CharactersController.I.SetAllCharactersPrizeAvailable();
DualAvatarController.Instance?.HideCharacters();
player1score = 0;
player2score = 0;
vsBotScore = 0;
VitrinaView.Instance.Deactivate();
canReturnToMenu = true;
}
private void StartPveRound(int characterIndex)
{
_fieldCleaner.Clear();
CharactersController.I.ShowCharacter(characterIndex, StartRound);
}
private void StartRound()
{
turnManager.StartGame(gameMode);
PrepareRound(Team.Player1);
OnRoundStarted?.Invoke();
}
private static List<Prize> GetAvailablePrizes(IEnumerable<Prize> prizes)
{
List<Prize> result = new();
if (prizes == null)
return result;
foreach (Prize prize in prizes)
{
if (prize != null && prize is not EmptyPrize)
result.Add(prize);
}
return result;
}
private Prize GetNextBotPrize()
{
int nextIndex = CharactersController.CharacterIndex + 1;
if (nextIndex >= CharactersController.CharactersAmount)
return null;
List<Prize> nextPrizes = GetAvailablePrizes(CharactersController.I.GetPrizes(nextIndex));
return nextPrizes.Count > 0 ? nextPrizes[0] : null;
}
private void SubscribeToPrizePanels()
{
UnsubscribeFromPrizePanels();
takeOrRiskPanel.PrizeSelected += StartPrizeIssue;
takeOrRiskPanel.ContinueSelected += HandlePrizeSkipped;
qrPanel.OnComplete += HandlePrizeIssueFinished;
vitrinaPanel.OnComplete += HandleVitrinaIssueFinished;
}
private void UnsubscribeFromPrizePanels()
{
if (takeOrRiskPanel != null)
{
takeOrRiskPanel.PrizeSelected -= StartPrizeIssue;
takeOrRiskPanel.ContinueSelected -= HandlePrizeSkipped;
}
if (qrPanel != null)
qrPanel.OnComplete -= HandlePrizeIssueFinished;
if (vitrinaPanel != null)
vitrinaPanel.OnComplete -= HandleVitrinaIssueFinished;
PrizeSystemManager.PrizeIssueFinished -= HandleCountablePrizeIssueFinished;
}
private void StartPrizeIssue(Prize prize)
{
SubscribeToPrizePanels();
if (prize is CountablePrize)
{
PrizeSystemManager.PrizeIssueFinished -= HandleCountablePrizeIssueFinished;
PrizeSystemManager.PrizeIssueFinished += HandleCountablePrizeIssueFinished;
PrizeSystemManager.GivePrize(prize);
}
else if (prize is QrPrize)
{
qrPanel.gameObject.SetActive(true);
qrPanel.Initialize(prize);
}
else if (prize is VitrinaPrize vitrinaPrize)
{
vitrinaPanel.gameObject.SetActive(true);
vitrinaPanel.Initialize(vitrinaPrize.Boxes);
}
else
{
HandlePrizeIssueFinished();
}
}
private void HandlePrizeSkipped()
{
_returnToMenuAfterPrize = false;
UnsubscribeFromPrizePanels();
ContinueAfterPveWin();
}
private void HandleCountablePrizeIssueFinished(bool success)
{
PrizeSystemManager.PrizeIssueFinished -= HandleCountablePrizeIssueFinished;
HandlePrizeIssueFinished();
}
private void HandleVitrinaIssueFinished(bool success)
=> HandlePrizeIssueFinished();
private void HandlePrizeIssueFinished()
{
UnsubscribeFromPrizePanels();
if (_returnToMenuAfterPrize)
{
GotoMenu();
return;
}
bool isLastBot = CharactersController.CharacterIndex >= CharactersController.CharactersAmount - 1;
if (isLastBot)
ShowFinalVictoryNameInput();
else
ContinueAfterPveWin();
}
private void CancelPrizeFlow()
{
UnsubscribeFromPrizePanels();
if (takeOrRiskPanel != null)
takeOrRiskPanel.gameObject.SetActive(false);
if (qrPanel != null)
qrPanel.gameObject.SetActive(false);
if (vitrinaPanel != null)
vitrinaPanel.gameObject.SetActive(false);
}
private void RefundEntryIfAvailable()
{
if (!_canRefundEntry)
return;
PaymentSystem.ReturnCredits(_paidEntryAmount);
_paidEntryAmount = 0;
_canRefundEntry = false;
}
private void ResetPvpScores()
{
player1score = 0;
player2score = 0;
timerManager.RefreshPvpScores();
}
private void HandleVictoryNameEntered(string playerName)
{
nameInput.OnComplete -= HandleVictoryNameEntered;
ControlsPerformer.Instance.SetControlable(null);
StatsService.AddRecord(playerName, TurnTracker.Timer, TurnTracker.Moves);
nameInput.gameObject.SetActive(false);
GotoMenu();
}
public void upgradeFeeshkaDifficulty()
{
string difficultyMode = SettingsManager.GetString(SettingKey.DIFFICULTY_MODE);
//todo: разобраться
//if (difficultyMode == "Прохождение")
//{
// PaymentSystem.ResetPulsesCounter();
// Setting difficultySetting = SettingsManager.Container.TryGetSetting(SettingKeys.DIFFICULTY_MODE);
// difficultySetting.StringValue = "Заработок";
// SettingsManager.OnSettingsChanged?.Invoke();
// SettingsManager.SaveContainerToFile();
// GameManager.instance.AdminPanel.GetComponent<SettingsScreen>().RefreshViews();
// print("Сложность повышена");
//}
}
IEnumerator AddBotRecordEvery2Days()
{
while (true)
{
yield return new WaitForSeconds(3600f); // ✅ Проверка каждый час
double lastRecordTime = PlayerPrefs.GetFloat("LastBotRecord", 0);
double currentTime = (DateTime.UtcNow - new System.DateTime(1970, 1, 1)).TotalSeconds;
if (currentTime - lastRecordTime >= 172800f)
{
StatsService.AddDailyRecord();
PlayerPrefs.SetFloat("LastBotRecord", (float)currentTime);
PlayerPrefs.Save();
}
}
}
}