using CharacterSystem; using System; using UnityEngine; using UnityEngine.Serialization; public class TurnManager : MonoBehaviour { [Header("Players")] [SerializeField, FormerlySerializedAs("player1")] private Player _player1; [SerializeField, FormerlySerializedAs("player2")] private Player _player2; [SerializeField, FormerlySerializedAs("bot")] private Bot _bot; [Header("Settings")] [SerializeField, FormerlySerializedAs("gameMode")] private GameMode _gameMode; private IGamePlayer _currentPlayer; private bool _isGameOver; public void StartGame(GameMode mode) { _gameMode = mode; _isGameOver = false; SetupPlayers(); StartTurn(_currentPlayer); } public void CancelPlayerPreparation() { _player1.OnMoveCommitted -= OnPlayerMoveCommitted; _player2.OnMoveCommitted -= OnPlayerTwoMoveCommitted; _player1.OnThinkingStarted -= OnPlayerThinkingStarted; _player2.OnThinkingStarted -= OnPlayerTwoThinkingStarted; _player1.OnChipDropped -= OnTurnCompleted; _player1.ReturnPreparedChipToPool(); } public void HandleTimerEnded(Team player) { if (_isGameOver) return; if (_gameMode == GameMode.pve) { if (player == Team.Player1) HandlePveTimeout(); return; } if (_currentPlayer is Player currentPlayer && currentPlayer.team == player) currentPlayer.ForceDrop(); } private void SetupPlayers() { _player1.ControlSide = _gameMode == GameMode.pve ? JoystickSide.Both : JoystickSide.Left; _player2.ControlSide = JoystickSide.Right; _currentPlayer = _player1; } private void StartTurn(IGamePlayer player) { if (_isGameOver) return; if (player == _player1) { _player1.OnMoveCommitted -= OnPlayerMoveCommitted; _player1.OnMoveCommitted += OnPlayerMoveCommitted; _player1.OnThinkingStarted -= OnPlayerThinkingStarted; _player1.OnThinkingStarted += OnPlayerThinkingStarted; } else if (player == _player2) { _player2.OnMoveCommitted -= OnPlayerTwoMoveCommitted; _player2.OnMoveCommitted += OnPlayerTwoMoveCommitted; _player2.OnThinkingStarted -= OnPlayerTwoThinkingStarted; _player2.OnThinkingStarted += OnPlayerTwoThinkingStarted; } if (_gameMode == GameMode.pve) { GameManager.Instance.turnTracker.EnableTimer(false); } player.OnChipDropped -= OnTurnCompleted; player.OnChipDropped += OnTurnCompleted; player.PrepareChip(); ControlsPerformer.Instance.SetControlable(player); _currentPlayer = player; if (_gameMode == GameMode.pvp && Board.Instance.MovesCount > 0) GameManager.Instance.timerManager.SetActiveTimer(((BasePlayer)player).team); } private void OnTurnCompleted(int column, int row) { IGamePlayer completedPlayer = _currentPlayer; completedPlayer.OnChipDropped -= OnTurnCompleted; if (_gameMode == GameMode.pve && completedPlayer == _player1) EventBus.TriggerEvent(GameEvent.PlayerTurn); if (CheckGameOver(column, row)) { OnGameOver(); return; } NextTurn(); } private void NextTurn() { _currentPlayer.Sleep(); if (_gameMode == GameMode.pve) _currentPlayer = _currentPlayer == _player1 ? (IGamePlayer)_bot : _player1; else _currentPlayer = _currentPlayer == _player1 ? (IGamePlayer)_player2 : _player1; StartTurn(_currentPlayer); if (_gameMode == GameMode.pve && _currentPlayer == _bot) EventBus.TriggerEvent(GameEvent.BotTurn); } private bool CheckGameOver(int column, int row) { if (_currentPlayer is BasePlayer player) { CheckResult checkResult = FieldChecker.Check(player.team, row, column); return checkResult.End; } throw new Exception($"Не удалось привести {_currentPlayer}"); } private void OnGameOver() { _isGameOver = true; _currentPlayer.Sleep(); ControlsPerformer.Instance.SetControlable(null); GameManager.Instance.timerManager.StopAllTimers(); Team lastPlayerTeam = ((BasePlayer)_currentPlayer).team; CheckResult result = FieldChecker.lastResult; GameManager.Instance.endGameHandler.HandleEndGame(lastPlayerTeam, _gameMode, result); } private void OnPlayerMoveCommitted() { _player1.OnMoveCommitted -= OnPlayerMoveCommitted; HandlePlayerMoveCommitted(_player1); } private void OnPlayerTwoMoveCommitted() { _player2.OnMoveCommitted -= OnPlayerTwoMoveCommitted; HandlePlayerMoveCommitted(_player2); } private void HandlePlayerMoveCommitted(Player player) { MachineCountersService.RecordFirstMove(); GameManager.Instance.DisableEarlyMenuExit(); if (_gameMode == GameMode.pve) { GameManager.Instance.turnTracker.EnableTimer(false); GameManager.Instance.turnTracker.IncrementMoves(); } else { GameManager.Instance.timerManager.StopTimer(player.team); } } private void OnPlayerThinkingStarted() { _player1.OnThinkingStarted -= OnPlayerThinkingStarted; GameManager.Instance.EnableEarlyMenuExit(); if (_gameMode == GameMode.pve) GameManager.Instance.turnTracker.EnableTimer(true); } private void OnPlayerTwoThinkingStarted() => _player2.OnThinkingStarted -= OnPlayerTwoThinkingStarted; private void HandlePveTimeout() { _isGameOver = true; _currentPlayer.OnChipDropped -= OnTurnCompleted; _currentPlayer.CancelTurn(); ControlsPerformer.Instance.SetControlable(null); GameManager.Instance.turnTracker.EnableTimer(false); GameManager.Instance.timerManager.StopAllTimers(); GameManager.Instance.endGameHandler.HandlePveTimeout(); } }