using PrizeSystem; using System.Collections; using System.Text; using TMPro; using UnityEngine; using UnityEngine.UI; public enum GameMode { pve, pvp } public class GameManager : MonoBehaviour { private const int DEFAULT_FRAME_RATE = 60; public int Rows = 7, Cols = 7; public PlayerStatsService StatsService; public int botsAmount = 5; [Header("General")] public GameStateMachine stateMachine; public Board board; public static GameManager instance; public GameObject AdminPanel, NumberPanel; public TimerManager timerManager; public RulesController rulesController; public ChipPointer chipPointer; [Header("Menu")] public GameMode gameMode; public Transform coinPanel, boardTransform, noPrizeLabel; public UiManager menuUi; [Header("Scores")] public int player1score = 0, player2score = 0, vsBotScore = 0; private bool increaseVsBotTimer = false; public int vsBotMoves; public float vsBotThinkTime; public VictoryScale botScale, Player1Scale, Player2Scale; [HideInInspector] public CheckResult lastResult; [Header("Gameplay")] public GameObject player1Chip; public GameObject player2Chip; public GameObject botChip; public Chip chipPrefab; [HideInInspector] public Chip currentChip; public RectTransform EngamePanel; public RectTransform smallPrizesOut; public Image ReplayButton, MenuButton; public DrawVisual DrawVisual; public TextMeshProUGUI RestartButton; public TextMeshProUGUI TimerLabel; //до выхода в меню.. public TextMeshProUGUI ToMenuLabel; //это же public WinPanel winPanel; [HideInInspector] public CellState currentPlayer = CellState.Player2; public bool canReturnToMenu = false; //todo: разобраться нафига эта переменная public Transform[,] chipTransforms; // Кешированные компоненты для избежания GetComponent в DrawAnimation [Header("Панели ввода")] public TextInput nameInput; public TextInput ValutaNameInput; public TextInput NumberTech; public NumberInput pricePveInput; public NumberInput pricePvpInput; public NumberInput pricePveRevengeInput; public NumberInput prizesAvailableInput; public NumberInput pulsesToResetDifficultyInput; public NumberInput valutaPerPulseInput; public Leaderboard leaderboard; public GameObject CharactersConfigurator; public DualAvatarController avatarController; public PvpPointer pvpPointer; public MovesAndTimeCounter movesAndTimeCounter; public GameObject setPasswordPanel; public EnterPasswordPanel enterPasswordPanel; public SoundManager soundManager; public VitrinaPanel vitrinaPanel; public QrPanel qrPanel; public VitrinaCatcher vitrinaCatcher; public TakeOrRiskPanel takeOrRiskPanel; void Awake() { Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; soundManager.Initialize(); if (instance == null) { Application.targetFrameRate = DEFAULT_FRAME_RATE; instance = this; board.Init(Cols, Rows); chipTransforms = new Transform[Rows, Cols]; } ConfigManager.Initialize(); UnityMainThreadDispatcher.Initialize(); InitializePrefs(); SettingsManager.Initialize(); InitializeDevices(); PaymentSystem.Initialize(); ComWrapper.PaymentReceived += ProcessDifficultyCounter; SettingsManager.OnSettingsChanged.AddListener(ProcessDifficultyCounter); GetComponent().Initialize(); vitrinaCatcher.Initialize(); ProcessDifficultyCounter(); GetComponent().Initialize(); GetComponent().Initialize(); GetComponent().Initialize(); StatsService = new(); StatsService.Initialize(); #if !UNITY_EDITOR Defender.Instance.StartCoroutine(Defender.Instance.CheckLicenseCoroutine()); #endif DifficultyManager.Instance.dummyBots = false; StartCoroutine(AddBotRecordEvery2Days());// добавлять каждые 2 дня запись avatarController.GetComponent().Initialize(); avatarController.Initialize(); } private void InitializeDevices() { var sb = new StringBuilder(); //ИНИЦИАЛИЗАЦИЯ УСТРОЙСТВ var devices = ComPortScanner.ScanPorts(); sb.AppendLine($"Найдено устройств: {devices.Count}"); foreach (var device in devices) { sb.Append($"{device.Key} : {device.Value}"); } Debug.Log(sb.ToString()); bool controllerFound = false; string vitrinaPort = null; PrizeStandController.InitializationComplete += PrizeStandController_InitializationComplete; foreach (var device in devices) { //Витрина if (device.Value == ComPortScanner.DeviceType.PrizeShowcase) { vitrinaPort = device.Key; Debug.Log($"нашел витрину на порту, {vitrinaPort}"); } else if (device.Value == ComPortScanner.DeviceType.ControllerV1) { if (!controllerFound) { Debug.Log("Нашел периферийник1 открываю."); ComWrapper.Initialize(device.Key, boardVersion: 1); controllerFound = true; } } else if (device.Value == ComPortScanner.DeviceType.ControllerV2) { if (!controllerFound) { Debug.Log("Нашел периферийник2 открываю."); ComWrapper.Initialize(device.Key, boardVersion: 2); controllerFound = true; } } else { Debug.Log($"неизвестный тип {device.Key}:{device.Value}"); } } if (vitrinaPort != null) { Debug.Log($"Витрину открываем (порт {vitrinaPort}"); int h = ComNativeWrapper.Serial_Open(vitrinaPort, 115200, 8, 0, 1, 4, 10); if (h > 0) Debug.Log("Открыл"); else Debug.Log("Не Открыл"); PrizeStandController.Initialize(h, 5); } } private void OnApplicationQuit() { ComNativeWrapper.Serial_CloseAll(); } private void PrizeStandController_InitializationComplete(bool arg1, string arg2) { Debug.Log($"Инициализация витрины: {arg1} : {arg2}"); } private static void InitializePrefs() { PlayerPrefs.SetString("Serial", ConfigManager.Config.Serial); if (!PlayerPrefs.HasKey("Number")) PlayerPrefs.SetString("Number", "70000000000"); if (!PlayerPrefs.HasKey("NumberTech")) PlayerPrefs.SetString("NumberTech", "<Не указано>"); } private void Start() { stateMachine.ChangeState(new MenuState()); SettingsManager.OnSettingsChanged.AddListener(pullSettings); pullSettings(); Instantiate(new GameObject()).AddComponent(typeof(VfxPrefab)); } void pullSettings() { SetupCoinPanel(); } private void Update() { #if UNITY_EDITOR if (Input.GetKeyDown(KeyCode.G)) { PrizeSystemManager.GivePrize(PrizeUtils.CreatePrize(CountablePrizeType.Hopper, 1)); } if (Input.GetKeyDown(KeyCode.O)) { PlayerPrefs.SetInt("PrizeGivenBuffer", 1); } #endif if (increaseVsBotTimer) vsBotThinkTime += Time.deltaTime; } public void StartVsBotTimer() => increaseVsBotTimer = true; public void StopVsBotTimer() => increaseVsBotTimer = false; public void SetupCoinPanel() { bool shouldShowCoinCounter = !SettingsManager.GetBool("Freeplay", false); coinPanel.gameObject.SetActive(shouldShowCoinCounter); } public void spawnChip() { GameObject chipToSpawn; if (gameMode == GameMode.pvp) chipToSpawn = currentPlayer == CellState.Player1 ? player1Chip : player2Chip; else chipToSpawn = currentPlayer == CellState.Player1 ? player1Chip : botChip; currentChip = Instantiate(chipPrefab, new Vector2(0, 20), Quaternion.identity); currentChip.Team = currentPlayer; if (currentPlayer == CellState.Player2) currentChip.GetComponentInChildren().sprite = CharacterController.CurrentChipImage; } public void setChipTransformToArray(int row, int col, Transform entryTransform) { chipTransforms[row, col] = entryTransform; } public void SwitchPlayer() { currentPlayer = currentPlayer == CellState.Player1 ? CellState.Player2 : CellState.Player1; } public void SetMode(GameMode mode) => gameMode = mode; public void InitVictoryScales() { //Включить и обнулить нужные шкалы player1score = 0; player2score = 0; vsBotScore = 0; switch (gameMode) { case GameMode.pvp: botScale.gameObject.SetActive(false); Player1Scale.gameObject.SetActive(true); Player2Scale.gameObject.SetActive(true); Player1Scale.SetSlotsCount(5); Player2Scale.SetSlotsCount(5); Player1Scale.ResetScale(); Player2Scale.ResetScale(); break; case GameMode.pve: botScale.gameObject.SetActive(true); botScale.SetSlotsCount(botsAmount); Player1Scale.gameObject.SetActive(false); Player2Scale.gameObject.SetActive(false); botScale.ResetScale(); break; } } public void IncreaseScoreAndScaleOfPlayer(CellState player) { if (player == CellState.Player1) { player1score += 1; Player1Scale.SetMedalsCount(player1score); } else { player2score += 1; Player2Scale.SetMedalsCount(player2score); } } public void ProcessDifficultyCounter()//вызывается каждый раз, когда приходит COIN с платы или обновились настройки { string previous = PlayerPrefs.GetString("PreviousBaseBotDifficulty", "Обычная"); string difficultyType = SettingsManager.GetString("BaseBotDifficulty", "?"); //Инициализация 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); if (pulses >= pulsesToResetDifficulty) { PaymentSystem.ResetPulsesCounter(); Setting difficultySetting = SettingsManager.Container.TryGetSetting("BaseBotDifficulty"); difficultySetting.StringValue = "Обычная"; SettingsManager.OnSettingsChanged?.Invoke(); SettingsManager.SaveContainerToFile(); AdminPanel.GetComponent().RefreshViews(); print("Сложность сброшена"); } } } public void PrepareRound(CellState firstPlayer) { currentPlayer = firstPlayer; timerManager.SetupTimers(gameMode); if (gameMode == GameMode.pve) { timerManager.SetActiveTimer(CellState.Player1); int difficultyIndex = DifficultyManager.Instance.currentOpponent; CharacterController.SwitchToCharacter(difficultyIndex); } else if (gameMode == GameMode.pvp) DualAvatarController.Instance.ShowCharacters(); VitrinaView.Instance.ActivateIfNeed(); DetermineNextTurn(switchPlayer: false); } public void DetermineNextTurn(bool switchPlayer = true) { if (switchPlayer) SwitchPlayer(); spawnChip(); if (gameMode == GameMode.pvp)//переключаем таймеры только в pvp { timerManager.SetActiveTimer(currentPlayer); LightUtility.Player(currentPlayer); } if (currentPlayer == CellState.Player1) { stateMachine.ChangeState(new PositioningState()); } else { IState nextState; if (gameMode == GameMode.pvp) nextState = new PositioningState(); else nextState = new BotThinkingState(CharacterController.CurrentCharacter.ThinkTime); stateMachine.ChangeState(nextState); } } public void ResetGameSession() { vsBotThinkTime = 0; StopVsBotTimer(); vsBotMoves = 0; movesAndTimeCounter.SetVisibility(false); CharacterController.HideCharacter(); CharacterController.I.SetAllCharactersPrizeAvailable(true); DualAvatarController.Instance.HideCharacters(); DifficultyManager.Instance.ResetDifficulty(); player1score = 0; player2score = 0; vsBotScore = 0; VitrinaView.Instance.Deactivate(); canReturnToMenu = true; } IEnumerator AddBotRecordEvery2Days() { while (true) { yield return new WaitForSeconds(3600f); // ✅ Проверка каждый час double lastRecordTime = PlayerPrefs.GetFloat("LastBotRecord", 0); double currentTime = Utils.GetUnixTimestamp(); if (currentTime - lastRecordTime >= 172800f) { StatsService.AddDailyRecord(); PlayerPrefs.SetFloat("LastBotRecord", (float)currentTime); PlayerPrefs.Save(); } } } }