2026-01-22 20:50:41 +05:30
using System ;
2026-01-21 20:27:45 +05:30
using System.Collections.Generic ;
using System.Linq ;
2026-01-29 18:13:07 +05:30
using DG.Tweening ;
2026-01-26 19:48:55 +05:30
using TMPro ;
2026-01-21 20:27:45 +05:30
using UnityEngine ;
2026-01-27 20:55:55 +05:30
public enum BotMove
{
FinishingPathMove = 0 ,
SafeMove = 1 ,
AttackMove = 2 ,
NormalMove = 3 ,
NoMoves = 4
}
2026-01-21 20:27:45 +05:30
public class GameplayManager : MonoBehaviour , IBase , IBootLoader , IDataLoader
{
2026-01-30 09:35:31 +05:30
[SerializeField] DiceRollHandler diceRollHandler ;
2026-01-28 20:57:35 +05:30
[SerializeField] private int diceValue = 0 ;
2026-01-26 19:48:55 +05:30
[SerializeField] private TextMeshProUGUI diceText ;
2026-01-21 20:27:45 +05:30
[SerializeField] private Transform pointerDebug ;
[SerializeField] private MeshRenderer pointerMeshRend ;
[SerializeField] private Material turnMat ;
[SerializeField] private Material selectMat ;
[SerializeField] private PlayerGameData [ ] playerGameDatas ;
2026-01-23 15:32:48 +05:30
[SerializeField] private PlayerBaseHandler playerBaseHandler ;
2026-01-21 20:27:45 +05:30
2026-01-26 19:48:55 +05:30
private PlayerType currentPlayerTypeTurn ;
2026-01-30 22:17:18 +05:30
public PlayerType CurrentPlayerTypeTurn = > currentPlayerTypeTurn ;
2026-01-21 20:27:45 +05:30
private int currentPlayerTurnIndex = 0 ;
2026-01-30 21:51:33 +05:30
2026-01-27 20:55:55 +05:30
private List < PlayerType > allPlayerTypes = new List < PlayerType > ( ) ;
private List < PlayerType > botTypesInGame = new List < PlayerType > ( ) ;
2026-01-21 20:27:45 +05:30
2026-01-30 21:51:33 +05:30
private List < PlayerData > playerDatas = new List < PlayerData > ( ) ;
2026-01-21 20:27:45 +05:30
2026-01-30 21:51:33 +05:30
private Dictionary < PlayerType , PlayerGameData > playerGameDatasDict = new Dictionary < PlayerType , PlayerGameData > ( ) ;
2026-01-30 19:04:14 +05:30
private Dictionary < PlayerType , Dictionary < int , BotMove > > botRuntimeMovementData = new Dictionary < PlayerType , Dictionary < int , BotMove > > ( ) ;
2026-01-27 20:55:55 +05:30
2026-01-21 20:27:45 +05:30
private TilesManager tilesManager ;
2026-01-30 22:17:18 +05:30
private UIManager uIManager ;
2026-01-30 21:51:33 +05:30
private GameManager gameManager ;
2026-01-21 20:27:45 +05:30
private int diceRolledValue ;
2026-01-22 20:50:41 +05:30
private bool CanRollDiceAgain = false ; // used for when you get a 6 or when you reach the finish point
2026-01-29 21:15:48 +05:30
private int diceSixRollCounter = 0 ;
2026-01-21 20:27:45 +05:30
2026-01-30 09:35:31 +05:30
private List < PlayerPawn > availPlayers = new List < PlayerPawn > ( ) ;
private bool canSwitchPlayer = false ;
2026-01-30 11:30:40 +05:30
public bool CanRollDiceForUser
2026-01-30 09:35:31 +05:30
{
get ; private set ;
}
2026-01-30 21:51:33 +05:30
public int TotalPlayersInGame
{
get ; private set ;
}
public List < PlayerData > PlayerDatas = > playerDatas ;
2026-01-30 09:35:31 +05:30
public List < PlayerType > PlayerTypesCollection = > allPlayerTypes ;
2026-01-30 19:04:14 +05:30
2026-01-21 20:27:45 +05:30
public void Initialize ( )
{
InterfaceManager . Instance ? . RegisterInterface < GameplayManager > ( this ) ;
2026-01-29 18:13:07 +05:30
DOTween . useSafeMode = false ;
2026-01-21 20:27:45 +05:30
}
public void InitializeData ( )
{
tilesManager = InterfaceManager . Instance . GetInterfaceInstance < TilesManager > ( ) ;
2026-01-30 22:17:18 +05:30
uIManager = InterfaceManager . Instance . GetInterfaceInstance < UIManager > ( ) ;
2026-01-30 21:51:33 +05:30
gameManager = InterfaceManager . Instance . GetInterfaceInstance < GameManager > ( ) ;
2026-01-26 19:48:55 +05:30
}
2026-01-30 21:51:33 +05:30
public void InitPlayerTypesForPVP ( List < PlayerType > types , List < string > names )
2026-01-26 19:48:55 +05:30
{
2026-01-30 11:30:40 +05:30
allPlayerTypes = new List < PlayerType > ( types ) ;
2026-01-30 21:51:33 +05:30
playerDatas . Clear ( ) ;
TotalPlayersInGame = types . Count ;
for ( int i = 0 ; i < types . Count ; i + + )
{
playerDatas . Add ( new PlayerData
{
playerType = types [ i ] ,
playerName = names [ i ] ,
} ) ;
}
2026-01-23 15:32:48 +05:30
2026-01-30 22:06:51 +05:30
tilesManager . InitTilesData ( ) ;
2026-01-27 20:55:55 +05:30
playerBaseHandler . InitPlayerTypes ( allPlayerTypes ) ;
2026-01-23 15:32:48 +05:30
InitCurrentGamePlayerInfo ( ) ;
2026-01-30 12:54:43 +05:30
SetCanRollDiceForUser ( true ) ;
2026-01-21 20:27:45 +05:30
}
2026-01-30 21:51:33 +05:30
public void InitPlayerTypesForBotMatch ( PlayerData selectedPlayerData , int botCount )
2026-01-26 19:48:55 +05:30
{
2026-01-30 22:06:51 +05:30
playerDatas = new List < PlayerData > ( ) ;
botTypesInGame = new List < PlayerType > ( ) ;
allPlayerTypes = new List < PlayerType > ( ) ;
2026-01-27 20:55:55 +05:30
2026-01-30 21:51:33 +05:30
TotalPlayersInGame = botCount + 1 ;
AssignBotTypes ( selectedPlayerData . playerType , botCount ) ;
foreach ( PlayerType playerType in Enum . GetValues ( typeof ( PlayerType ) ) )
{
if ( botTypesInGame . Contains ( playerType ) )
{
allPlayerTypes . Add ( playerType ) ;
playerDatas . Add ( new PlayerData { playerType = selectedPlayerData . playerType , playerName = $"{playerType}" } ) ;
}
else
{
allPlayerTypes . Add ( selectedPlayerData . playerType ) ;
playerDatas . Add ( new PlayerData { playerType = selectedPlayerData . playerType , playerName = $"{selectedPlayerData.playerName}" } ) ;
}
}
2026-01-27 20:55:55 +05:30
2026-01-30 22:06:51 +05:30
tilesManager . InitTilesData ( ) ;
2026-01-27 20:55:55 +05:30
playerBaseHandler . InitPlayerTypes ( allPlayerTypes ) ;
InitCurrentGamePlayerInfo ( ) ;
2026-01-28 16:57:27 +05:30
InitBotRuntimeData ( ) ;
2026-01-30 21:51:33 +05:30
AssignPlayerAndBotStates ( selectedPlayerData . playerType ) ;
2026-01-30 19:04:14 +05:30
2026-01-30 21:51:33 +05:30
SetCanRollDiceForUser ( ! botTypesInGame . Contains ( allPlayerTypes [ 0 ] ) ) ;
if ( botTypesInGame . Contains ( allPlayerTypes [ 0 ] ) )
Invoke ( nameof ( HandleDiceRoll ) , 1f ) ;
2026-01-27 20:55:55 +05:30
}
private void InitBotRuntimeData ( )
{
2026-01-30 22:06:51 +05:30
botRuntimeMovementData = new Dictionary < PlayerType , Dictionary < int , BotMove > > ( ) ;
2026-01-27 20:55:55 +05:30
foreach ( var botType in botTypesInGame )
{
PlayerGameData playerGameData = playerGameDatasDict [ botType ] ;
if ( ! botRuntimeMovementData . ContainsKey ( botType ) )
{
botRuntimeMovementData . Add ( botType , new Dictionary < int , BotMove > ( ) ) ;
}
foreach ( var pawn in playerGameData . playerPawnsDict )
{
2026-01-28 16:57:27 +05:30
botRuntimeMovementData [ botType ] . Add ( pawn . Value . PlayerId , BotMove . NoMoves ) ;
2026-01-27 20:55:55 +05:30
}
}
}
private void AssignPlayerAndBotStates ( PlayerType selectedPlayerType )
{
PlayerBase playerBase = playerBaseHandler . GetPlayerBase ( selectedPlayerType ) ;
playerBase . AssignBotState ( PawnType . User ) ;
foreach ( PlayerType playerType in botTypesInGame )
{
playerBase = playerBaseHandler . GetPlayerBase ( playerType ) ;
playerBase . AssignBotState ( PawnType . Bot ) ;
}
}
private void AssignBotTypes ( PlayerType selectedPlayerType , int botCount )
{
int addedBots = 0 ;
2026-01-26 19:48:55 +05:30
if ( botCount = = 1 )
{
2026-01-27 20:55:55 +05:30
var playerType = ( PlayerType ) ( ( int ) selectedPlayerType + 2 < Enum . GetValues ( typeof ( PlayerType ) ) . Length ?
2026-01-26 19:48:55 +05:30
( int ) selectedPlayerType + 2 : ( int ) selectedPlayerType - 2 ) ;
2026-01-27 20:55:55 +05:30
botTypesInGame . Add ( playerType ) ;
}
else if ( botCount = = 2 )
{
foreach ( PlayerType enumType in Enum . GetValues ( typeof ( PlayerType ) ) )
{
if ( enumType = = selectedPlayerType ) continue ;
botTypesInGame . Add ( enumType ) ;
addedBots + + ;
if ( addedBots = = botCount ) break ;
}
2026-01-26 19:48:55 +05:30
}
else
{
2026-01-27 20:55:55 +05:30
foreach ( PlayerType enumType in Enum . GetValues ( typeof ( PlayerType ) ) )
{
if ( enumType = = selectedPlayerType ) continue ;
botTypesInGame . Add ( enumType ) ;
}
2026-01-26 19:48:55 +05:30
}
}
2026-01-21 20:27:45 +05:30
// TODO :: Call based on 2P/3P/4P
2026-01-23 15:32:48 +05:30
public void InitCurrentGamePlayerInfo ( )
2026-01-21 20:27:45 +05:30
{
2026-01-27 20:55:55 +05:30
currentPlayerTypeTurn = allPlayerTypes [ currentPlayerTurnIndex ] ;
2026-01-21 20:27:45 +05:30
// initialize the board based on the player types
2026-01-30 22:06:51 +05:30
playerGameDatasDict = new Dictionary < PlayerType , PlayerGameData > ( ) ;
2026-01-30 21:51:33 +05:30
2026-01-21 20:27:45 +05:30
foreach ( PlayerGameData playerGameData in playerGameDatas )
{
2026-01-27 20:55:55 +05:30
if ( ! allPlayerTypes . Contains ( playerGameData . playerType ) )
2026-01-23 15:32:48 +05:30
continue ;
2026-01-21 20:27:45 +05:30
2026-01-27 20:55:55 +05:30
Debug . Log ( $"playerGameData.playerType: {playerGameData.playerType}" ) ;
2026-01-30 19:14:08 +05:30
2026-01-23 15:32:48 +05:30
playerGameDatasDict . Add ( playerGameData . playerType , playerGameData ) ;
2026-01-27 20:55:55 +05:30
playerGameDatasDict [ playerGameData . playerType ] . playerPawnsDict = new Dictionary < int , PlayerPawn > ( ) ;
2026-01-23 15:32:48 +05:30
foreach ( Transform playerPawnChild in playerGameData . playersParent )
{
if ( ! playerPawnChild . gameObject . activeInHierarchy ) continue ;
2026-01-30 19:04:14 +05:30
2026-01-27 20:55:55 +05:30
var pawn = playerPawnChild . GetComponent < PlayerPawn > ( ) ;
playerGameDatasDict [ playerGameData . playerType ] . playerPawnsDict . Add ( pawn . PlayerId , pawn ) ;
2026-01-21 20:27:45 +05:30
}
2026-01-28 20:57:35 +05:30
playerGameDatasDict [ playerGameData . playerType ] . totalPawnsInHome = playerGameDatasDict [ playerGameData . playerType ] . playerPawnsDict . Count ;
2026-01-21 20:27:45 +05:30
}
}
public void EnablePlayerSelectionStates ( bool state )
{
2026-01-23 12:46:59 +05:30
foreach ( var playerPawn in playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict )
2026-01-21 20:27:45 +05:30
{
2026-01-27 20:55:55 +05:30
if ( playerPawn . Value . GetPlayerState ( ) = = PlayerState . InFinishingPath ) continue ;
2026-01-21 20:27:45 +05:30
2026-01-27 20:55:55 +05:30
playerPawn . Value . SetPlayerSelectionState ( state ) ;
2026-01-21 20:27:45 +05:30
}
}
2026-01-30 09:35:31 +05:30
public void OnDiceInteracted ( )
2026-01-28 16:57:27 +05:30
{
2026-01-30 11:30:40 +05:30
diceRollHandler . HandleDiceViewForUser ( ) ;
2026-01-30 09:35:31 +05:30
}
2026-01-28 20:57:35 +05:30
2026-01-30 09:35:31 +05:30
public void RollDiceForPlayer ( int rolledVal )
{
2026-01-28 16:57:27 +05:30
OnDiceRolled ( rolledVal ) ;
2026-01-29 21:15:48 +05:30
OnNoMovesLeft ( ) ;
2026-01-28 16:57:27 +05:30
}
2026-01-29 21:15:48 +05:30
// Summary :: Function will be called and effective when a dice is rolled and no selection of pawns is made.
private void OnNoMovesLeft ( )
2026-01-28 16:57:27 +05:30
{
if ( canSwitchPlayer & & ! CanRollDiceAgain )
{
Debug . Log ( $"Switching player" ) ;
SwitchPlayer ( ) ;
}
2026-01-29 21:15:48 +05:30
}
private bool CheckForMaxDiceRollAttempt ( )
{
if ( diceSixRollCounter = = 3 )
{
CanRollDiceAgain = false ;
SwitchPlayer ( ) ;
return true ;
}
return false ;
2026-01-28 16:57:27 +05:30
}
2026-01-30 11:30:40 +05:30
private void RollDiceForBot ( int rolledVal )
2026-01-28 16:57:27 +05:30
{
Debug . Log ( $"CallTest: RollDiceForBot" ) ;
2026-01-28 20:57:35 +05:30
// OnDiceRolled(diceValue == 0 ? UnityEngine.Random.Range(1, Ludo_3D_Constants.Max_Dice_Rolls + 1) : diceValue);
2026-01-30 11:30:40 +05:30
OnDiceRolled ( rolledVal ) ;
2026-01-28 16:57:27 +05:30
SelectPawnFromBotBase ( ) ;
2026-01-29 21:15:48 +05:30
OnNoMovesLeft ( ) ;
2026-01-28 16:57:27 +05:30
}
// TODO :: Call right after the dice is rolled with the animation
// What happens when you get a 6
private void SelectPawnFromBotBase ( )
{
2026-01-30 19:04:14 +05:30
if ( canSwitchPlayer | | availPlayers . Count ( ) < 1 & & ! CanRollDiceAgain | | ! botTypesInGame . Contains ( currentPlayerTypeTurn ) )
2026-01-30 12:54:43 +05:30
{
Debug . Log ( $"returning from SelectPawnFromBotBase" ) ;
return ; // Have a better check here
}
2026-01-28 16:57:27 +05:30
Debug . Log ( $"CallTest: SelectPawnFromBotBase: {currentPlayerTypeTurn}" ) ;
var botPawnsDictForCurrentPlayer = botRuntimeMovementData [ currentPlayerTypeTurn ] ; // set the data inside this dict
2026-01-30 19:04:14 +05:30
2026-01-28 16:57:27 +05:30
// check the data from the playerGameDataDict
// change playerPawnsDict to list
// only select the pawns that are active
// if no pawns have left the home select the first pawn inside the base should be selected
int savedPlayerId = - 1 ;
PlayerPawn pawn = null ;
2026-01-28 17:34:06 +05:30
Debug . Log ( $"SelectPawnFromBotBase: availPlayers.Count(): {availPlayers.Count()}, CanRollDiceAgain: {CanRollDiceAgain}" ) ;
2026-01-28 20:57:35 +05:30
if ( playerGameDatasDict [ currentPlayerTypeTurn ] . totalPawnsInHome = = 0 )
{
InitActivePlayers ( ) ;
}
2026-01-28 16:57:27 +05:30
if ( availPlayers . Count ( ) < 1 & & CanRollDiceAgain ) // got a 6 roll value
{
pawn = playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict . Values . FirstOrDefault ( pawn = > pawn . GetPlayerState ( ) = = PlayerState . InHome ) ;
2026-01-28 20:57:35 +05:30
Debug . Log ( $"SelectedPawn: {pawn.name}" ) ;
2026-01-28 16:57:27 +05:30
OnPawnSelected ( pawn ) ;
return ;
}
2026-01-30 19:04:14 +05:30
2026-01-28 16:57:27 +05:30
// TODO :: Double check
2026-01-29 16:17:19 +05:30
foreach ( var key in botPawnsDictForCurrentPlayer . Keys )
{
Debug . Log ( $"b :: botPawnsDictForCurrentPlayer[key]: {botPawnsDictForCurrentPlayer[key]}" ) ;
// botPawnsDictForCurrentPlayer[key] = BotMove.NoMoves;
Debug . Log ( $"a :: botPawnsDictForCurrentPlayer[key]: {botPawnsDictForCurrentPlayer[key]}" ) ;
}
2026-01-28 16:57:27 +05:30
2026-01-29 16:17:19 +05:30
Debug . Log ( $"Before Iterating" ) ;
2026-01-28 16:57:27 +05:30
foreach ( var playerPawn in availPlayers )
{
2026-01-29 16:17:19 +05:30
Debug . Log ( $"Iterating" ) ;
2026-01-28 16:57:27 +05:30
var possibleLandingIndex = playerPawn . CurrentTileIndex + diceRolledValue ;
int lastIndex = tilesManager . GetGeneralTilesLength ( ) - 1 ;
2026-01-29 15:45:49 +05:30
int index = possibleLandingIndex > lastIndex ? possibleLandingIndex - lastIndex - 1 : possibleLandingIndex ;
2026-01-28 16:57:27 +05:30
Tile possibleTileData = tilesManager . RetrieveTileBasedOnIndex ( index ) ;
2026-01-28 20:57:35 +05:30
Debug . Log ( $"AI playerPawn :: {playerPawn.name} :: state: {playerPawn.GetPlayerState()}, possibleLandingIndex: {possibleLandingIndex > playerGameDatasDict[currentPlayerTypeTurn].endIndex}" ) ;
Debug . Log ( $"AI playerPawn :: {playerPawn.name} :: possibleTileData.IsSafeZone: {possibleTileData.IsSafeZone}" ) ;
2026-01-29 18:13:07 +05:30
Debug . Log ( $"AI playerPawn :: {playerPawn.name} :: possibleTileData.PlayerPawn: {possibleTileData.HasPawnsAvailable}" ) ;
2026-01-28 20:57:35 +05:30
2026-01-28 16:57:27 +05:30
if ( playerPawn . GetPlayerState ( ) = = PlayerState . InFinishingPath | | possibleLandingIndex > playerGameDatasDict [ currentPlayerTypeTurn ] . endIndex )
{
2026-01-29 16:17:19 +05:30
Debug . Log ( $"AI playerPawn :: {playerPawn.name} :: {playerPawn.PlayerId} :: inFinishingPath :: canSelectPlayer: {playerPawn.CanSelectPlayer}" ) ;
2026-01-29 15:45:49 +05:30
if ( playerPawn . CanSelectPlayer )
{
botPawnsDictForCurrentPlayer [ playerPawn . PlayerId ] = BotMove . FinishingPathMove ;
savedPlayerId = playerPawn . PlayerId ;
break ;
}
else
{
botPawnsDictForCurrentPlayer [ playerPawn . PlayerId ] = BotMove . NoMoves ;
}
2026-01-28 16:57:27 +05:30
}
2026-01-29 16:17:19 +05:30
else if ( possibleTileData . IsSafeZone )
2026-01-28 16:57:27 +05:30
{
2026-01-29 16:17:19 +05:30
Debug . Log ( $"AI playerPawn :: {playerPawn.name} :: {playerPawn.PlayerId} :: safeMove" ) ;
2026-01-28 16:57:27 +05:30
botPawnsDictForCurrentPlayer [ playerPawn . PlayerId ] = BotMove . SafeMove ;
}
2026-01-29 18:13:07 +05:30
else if ( possibleTileData . HasPawnsAvailable )
2026-01-28 16:57:27 +05:30
{
2026-01-29 16:17:19 +05:30
Debug . Log ( $"AI playerPawn :: {playerPawn.name} :: {playerPawn.PlayerId} :: attackMove" ) ;
2026-01-28 16:57:27 +05:30
botPawnsDictForCurrentPlayer [ playerPawn . PlayerId ] = BotMove . AttackMove ;
}
else
{
2026-01-29 15:45:49 +05:30
Debug . Log ( $"AI playerPawn :: {playerPawn.name} :: {playerPawn.PlayerId} :: normalMove" ) ;
2026-01-28 16:57:27 +05:30
botPawnsDictForCurrentPlayer [ playerPawn . PlayerId ] = BotMove . NormalMove ;
}
}
List < int > playerIds = new List < int > ( ) ;
2026-01-29 15:45:49 +05:30
if ( savedPlayerId ! = - 1 )
Debug . Log ( $"SavedPlayerId: {savedPlayerId}, CanSelectPlayer: {playerGameDatasDict[currentPlayerTypeTurn].playerPawnsDict[savedPlayerId].CanSelectPlayer}" ) ;
if ( savedPlayerId ! = - 1 & & playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict [ savedPlayerId ] . CanSelectPlayer )
2026-01-28 16:57:27 +05:30
{
pawn = playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict [ savedPlayerId ] ; // chances are when one of the character reaches towards the finishing point
}
else
{
if ( botPawnsDictForCurrentPlayer . ContainsValue ( BotMove . SafeMove ) & & botPawnsDictForCurrentPlayer . ContainsValue ( BotMove . AttackMove ) )
{
InitPlayerIdsBasedOnState ( ( val ) = > val = = BotMove . AttackMove | | val = = BotMove . SafeMove ) ;
savedPlayerId = playerIds [ UnityEngine . Random . Range ( 0 , playerIds . Count ) ] ;
pawn = playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict [ savedPlayerId ] ;
2026-01-28 20:57:35 +05:30
Debug . Log ( $"AI playerPawn :: {pawn.name} :: Getting savedplayer id" ) ;
2026-01-28 16:57:27 +05:30
}
else if ( botPawnsDictForCurrentPlayer . ContainsValue ( BotMove . SafeMove ) )
{
InitPawnBasedOnState ( BotMove . SafeMove ) ;
2026-01-28 20:57:35 +05:30
Debug . Log ( $"AI playerPawn :: {pawn.name} :: Getting savedplayer id" ) ;
2026-01-28 16:57:27 +05:30
}
else if ( botPawnsDictForCurrentPlayer . ContainsValue ( BotMove . AttackMove ) )
{
InitPawnBasedOnState ( BotMove . AttackMove ) ;
2026-01-28 20:57:35 +05:30
Debug . Log ( $"AI playerPawn :: {pawn.name} :: Getting savedplayer id" ) ;
2026-01-28 16:57:27 +05:30
}
else if ( botPawnsDictForCurrentPlayer . ContainsValue ( BotMove . NormalMove ) )
{
InitPawnBasedOnState ( BotMove . NormalMove ) ;
2026-01-28 20:57:35 +05:30
Debug . Log ( $"AI playerPawn :: {pawn.name} :: Getting savedplayer id" ) ;
2026-01-28 16:57:27 +05:30
}
}
2026-01-28 20:57:35 +05:30
Debug . Log ( $"AI playerPawn :: {pawn.name} :: SelectedPawn: {pawn.name}" ) ;
2026-01-28 16:57:27 +05:30
OnPawnSelected ( pawn ) ;
void InitPawnBasedOnState ( BotMove botMove )
{
InitPlayerIdsBasedOnState ( ( val ) = > val = = botMove ) ;
ReturnPlayerWithMaxSteps ( ref savedPlayerId ) ;
pawn = playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict [ savedPlayerId ] ;
}
void InitPlayerIdsBasedOnState ( Predicate < BotMove > state )
{
foreach ( var botPair in botPawnsDictForCurrentPlayer )
if ( state . Invoke ( botPair . Value ) )
playerIds . Add ( botPair . Key ) ;
}
void ReturnPlayerWithMaxSteps ( ref int savedPlayerId )
{
int maxStepsTaken = - 999 ;
foreach ( var id in playerIds )
{
if ( playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict [ id ] . StepsTaken > maxStepsTaken )
{
maxStepsTaken = playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict [ id ] . StepsTaken ;
savedPlayerId = id ;
}
}
}
}
2026-01-21 20:27:45 +05:30
public void OnDiceRolled ( int rolledVal )
{
2026-01-29 22:16:54 +05:30
SetCanRollDiceForUser ( false ) ;
2026-01-21 20:27:45 +05:30
// add core dice logic here
2026-01-22 20:50:41 +05:30
Debug . Log ( $"Tile Index :: LUDO :: rolledVal: {rolledVal} :: {currentPlayerTypeTurn}" ) ;
2026-01-21 20:27:45 +05:30
diceRolledValue = rolledVal ;
2026-01-26 19:48:55 +05:30
diceText . text = $"{diceRolledValue}" ;
2026-01-30 22:06:51 +05:30
availPlayers = new List < PlayerPawn > ( ) ;
2026-01-30 19:04:14 +05:30
2026-01-21 20:27:45 +05:30
if ( rolledVal = = Ludo_3D_Constants . Max_Dice_Rolls )
{
2026-01-28 16:57:27 +05:30
canSwitchPlayer = false ;
2026-01-21 20:27:45 +05:30
// provide option to select a pawn from the list
// also play a simple animation before selecting
2026-01-22 20:50:41 +05:30
CanRollDiceAgain = true ;
2026-01-29 21:15:48 +05:30
diceSixRollCounter + + ;
2026-01-29 15:45:49 +05:30
pointerMeshRend . material = selectMat ;
2026-01-22 20:50:41 +05:30
2026-01-29 15:45:49 +05:30
foreach ( var playerPawn in playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict )
if ( playerPawn . Value . GetPlayerState ( ) = = PlayerState . InFinishingPath )
playerPawn . Value . SetPlayerSelectionState ( false ) ;
Debug . Log ( $"### AreAllPawnsInFinishingPath" ) ;
2026-01-27 20:55:55 +05:30
if ( AreAllPawnsInFinishingPath ( ) )
2026-01-29 15:45:49 +05:30
{
2026-01-30 12:54:43 +05:30
SetCanRollDiceForUser ( ! botTypesInGame . Contains ( currentPlayerTypeTurn ) ) ;
2026-01-21 20:27:45 +05:30
2026-01-29 15:45:49 +05:30
return ;
}
Debug . Log ( $"### EnablePlayerSelectionStates" ) ;
EnablePlayerSelectionStates ( true ) ;
2026-01-21 20:27:45 +05:30
// pointerMeshRend.materials[0] = selectMat;
}
else // if there are any other pawns that are in safe or moving state
{
// for player's logic
2026-01-28 20:57:35 +05:30
InitActivePlayers ( ) ;
2026-01-28 16:57:27 +05:30
2026-01-22 20:50:41 +05:30
int customAvailPlayers = availPlayers . Count ( ) ;
2026-01-28 16:57:27 +05:30
Debug . Log ( $"before CustomAvailablePlayers: {customAvailPlayers}" ) ;
2026-01-29 15:45:49 +05:30
List < int > indexesToRemove = new List < int > ( ) ;
2026-01-22 20:50:41 +05:30
2026-01-29 15:45:49 +05:30
for ( int i = 0 ; i < availPlayers . Count ; i + + )
2026-01-21 20:27:45 +05:30
{
2026-01-29 15:45:49 +05:30
Debug . Log ( $"## playerPawn.GetPlayerState(): {availPlayers[i].GetPlayerState()}" ) ;
if ( availPlayers [ i ] . GetPlayerState ( ) = = PlayerState . InFinishingPath )
2026-01-21 20:27:45 +05:30
{
2026-01-29 15:45:49 +05:30
Debug . Log ( $"diceRolledValue: {diceRolledValue}, FinishingDataLen: {tilesManager.GetFinishingTileDataLength(currentPlayerTypeTurn)}, playerPawn.CurrentTileIndex: {availPlayers[i].CurrentTileIndex}" ) ;
if ( diceRolledValue < = tilesManager . GetFinishingTileDataLength ( currentPlayerTypeTurn ) - ( availPlayers [ i ] . CurrentTileIndex + 1 ) )
2026-01-22 20:50:41 +05:30
{
2026-01-29 15:45:49 +05:30
availPlayers [ i ] . SetPlayerSelectionState ( true ) ;
2026-01-28 20:57:35 +05:30
}
2026-01-22 20:50:41 +05:30
else
{
2026-01-29 15:45:49 +05:30
indexesToRemove . Add ( i ) ;
availPlayers [ i ] . SetPlayerSelectionState ( false ) ;
2026-01-22 20:50:41 +05:30
customAvailPlayers - - ;
}
continue ;
2026-01-21 20:27:45 +05:30
}
2026-01-22 20:50:41 +05:30
2026-01-29 15:45:49 +05:30
availPlayers [ i ] . SetPlayerSelectionState ( true ) ;
2026-01-21 20:27:45 +05:30
}
2026-01-29 15:45:49 +05:30
foreach ( int i in indexesToRemove ) availPlayers . RemoveAt ( i ) ;
2026-01-22 20:50:41 +05:30
// if (availPlayers.Count() < 1)
Debug . Log ( $"CustomAvailablePlayers: {customAvailPlayers}" ) ;
2026-01-28 16:57:27 +05:30
canSwitchPlayer = customAvailPlayers < 1 ;
2026-01-22 20:50:41 +05:30
CanRollDiceAgain = false ;
2026-01-21 20:27:45 +05:30
}
2026-01-28 16:57:27 +05:30
Debug . Log ( $"CanRollDiceAgain: {CanRollDiceAgain}, canSwitchPlayer: {canSwitchPlayer}" ) ;
2026-01-21 20:27:45 +05:30
}
2026-01-28 20:57:35 +05:30
private void InitActivePlayers ( )
{
availPlayers = playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict . Values . Select ( pawn = > pawn )
. Where ( pawn = > pawn . GetPlayerState ( ) = = PlayerState . InSafeZone | |
pawn . GetPlayerState ( ) = = PlayerState . Moving | |
pawn . GetPlayerState ( ) = = PlayerState . InFinishingPath ) . ToList ( ) ;
2026-01-30 19:04:14 +05:30
Debug . Log ( $"#### UpdatePlayerState in InitActivePlayers " ) ;
foreach ( var pawn in playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict . Values )
{
Debug . Log ( $"pawn: {pawn.name}, state: {pawn.GetPlayerState()}" ) ;
}
foreach ( var player in availPlayers ) // TODO :: Move from here
{
DisplayPlayerCountOnTile ( player , true ) ;
}
2026-01-28 20:57:35 +05:30
}
2026-01-27 20:55:55 +05:30
private bool AreAllPawnsInFinishingPath ( )
{
bool areAllPawnsInFinishingPath = false ;
foreach ( var pawn in playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict )
{
2026-01-29 15:45:49 +05:30
if ( pawn . Value . GetPlayerState ( ) = = PlayerState . HasFinished ) continue ;
if ( pawn . Value . GetPlayerState ( ) = = PlayerState . InFinishingPath )
2026-01-27 20:55:55 +05:30
{
areAllPawnsInFinishingPath = true ;
continue ;
}
areAllPawnsInFinishingPath = false ;
break ;
}
return areAllPawnsInFinishingPath ;
}
2026-01-28 16:57:27 +05:30
private void UpdatePlayerState ( PlayerPawn playerPawn , PlayerState playerState )
{
2026-01-30 19:04:14 +05:30
Debug . Log ( $"#### UpdatePlayerState " ) ;
2026-01-28 16:57:27 +05:30
playerGameDatasDict [ playerPawn . PlayerType ] . playerPawnsDict [ playerPawn . PlayerId ] = playerPawn ;
playerGameDatasDict [ playerPawn . PlayerType ] . playerPawnsDict [ playerPawn . PlayerId ] . SetPlayerState ( playerState ) ;
playerPawn . SetPlayerState ( playerState ) ;
}
2026-01-28 17:34:06 +05:30
private void CheckDiceRollForBot ( PlayerPawn playerPawn )
{
if ( CanRollDiceAgain )
2026-01-30 11:30:40 +05:30
{
HandleDiceRoll ( ) ;
}
}
private void HandleDiceRoll ( )
{
2026-01-30 22:06:51 +05:30
// diceRollHandler.HandleDiceViewForBot((rollVal) => RollDiceForBot(rollVal));
diceRollHandler . HandleDiceViewForBot ( ( rollVal ) = > RollDiceForBot ( rollVal ) , diceValue = = 0 ? UnityEngine . Random . Range ( 1 , Ludo_3D_Constants . Max_Dice_Rolls + 1 ) : diceValue ) ;
2026-01-28 17:34:06 +05:30
}
2026-01-21 20:27:45 +05:30
public void OnPawnSelected ( PlayerPawn playerPawn )
{
EnablePlayerSelectionStates ( false ) ;
2026-01-22 20:50:41 +05:30
PlayerGameData playerGameData = playerGameDatasDict [ currentPlayerTypeTurn ] ;
2026-01-26 13:03:50 +05:30
Debug . Log ( $"playerPawn.GetPlayerState(): {playerPawn.GetPlayerState()}" ) ;
2026-01-21 20:27:45 +05:30
2026-01-30 19:04:14 +05:30
2026-01-21 20:27:45 +05:30
if ( playerPawn . GetPlayerState ( ) = = PlayerState . InHome )
{
2026-01-23 12:46:59 +05:30
Tile targetTile = tilesManager . RetrieveTileBasedOnIndex ( playerGameData . startIndex ) ;
2026-01-30 19:04:14 +05:30
DisplayPlayerCountOnTile ( playerPawn , false ) ;
2026-01-21 20:27:45 +05:30
playerPawn . MoveToTile (
2026-01-23 13:33:16 +05:30
GetAndInitPositionInsideSafeZone ( playerPawn , targetTile ) ,
2026-01-21 20:27:45 +05:30
onComplete : ( ) = >
{
2026-01-28 20:57:35 +05:30
playerGameDatasDict [ playerGameData . playerType ] . totalPawnsInHome - - ;
2026-01-28 16:57:27 +05:30
UpdatePlayerState ( playerPawn , PlayerState . InSafeZone ) ;
2026-01-30 19:04:14 +05:30
DisplayPlayerCountOnTile ( playerPawn , true ) ;
2026-01-29 21:15:48 +05:30
if ( CheckForMaxDiceRollAttempt ( ) )
{
return ;
}
2026-01-28 17:34:06 +05:30
if ( playerPawn . IsBotPlayer )
CheckDiceRollForBot ( playerPawn ) ;
2026-01-29 21:15:48 +05:30
else
2026-01-29 22:16:54 +05:30
SetCanRollDiceForUser ( true ) ;
2026-01-28 17:34:06 +05:30
2026-01-21 20:27:45 +05:30
} , playerGameData . startIndex ) ;
return ;
}
2026-01-29 19:48:25 +05:30
else if ( playerPawn . GetPlayerState ( ) = = PlayerState . InFinishingPath )
2026-01-22 20:50:41 +05:30
{
2026-01-29 19:48:25 +05:30
ApplyFinishingPathLogic ( playerPawn ) ;
}
else if ( playerPawn . CurrentTileIndex = = playerGameDatasDict [ currentPlayerTypeTurn ] . endIndex )
{
tilesManager . RetrieveTileBasedOnIndex ( playerPawn . CurrentTileIndex ) . ResetPlayerPawn ( playerPawn ) ;
ApplyFinishingPathLogic ( playerPawn ) ;
2026-01-22 20:50:41 +05:30
}
else if ( playerPawn . GetPlayerState ( ) = = PlayerState . InSafeZone | | playerPawn . GetPlayerState ( ) = = PlayerState . Moving )
2026-01-21 20:27:45 +05:30
{
// move based on the dice value
2026-01-22 20:50:41 +05:30
Debug . Log ( $"Tile Index :: currentTileIndex: {playerPawn.CurrentTileIndex}" ) ;
int nextTileIdx = GetNextGeneralTileIndex ( playerPawn ) ;
int targetIdx = playerPawn . CurrentTileIndex + diceRolledValue ;
2026-01-21 20:27:45 +05:30
2026-01-22 20:50:41 +05:30
if ( nextTileIdx = = 0 )
2026-01-28 22:00:39 +05:30
targetIdx = ( targetIdx - playerPawn . CurrentTileIndex ) - 1 ;
2026-01-30 19:04:14 +05:30
2026-01-22 20:50:41 +05:30
Tile currentSittingTile = tilesManager . RetrieveTileBasedOnIndex ( playerPawn . CurrentTileIndex ) ;
if ( currentSittingTile . IsSafeZone )
{
2026-01-23 13:33:16 +05:30
SafeTile safeTile = ( SafeTile ) currentSittingTile ;
safeTile . UpdateSafeZonePlayerData ( currentPlayerTypeTurn , playerPawn ) ;
2026-01-30 19:04:14 +05:30
// DisplayPlayerCountOnTile(playerPawn, false);
// if (safeTile.PlayerTypesCount > 0)
// {
// var pawns = safeTile.GetPlayerPawns(playerPawn.PlayerType);
// foreach (var pawn in pawns)
// DisplayPlayerCountOnTile(pawn, true);
// }
2026-01-23 13:33:16 +05:30
if ( safeTile . PlayerTypesCount = = 1 )
{
2026-01-26 19:48:55 +05:30
PlayerType playerType = safeTile . GetFirstPlayerType ( ) ;
2026-01-23 15:32:48 +05:30
2026-01-23 13:33:16 +05:30
var playerPawns = safeTile . GetPlayerPawns ( playerType ) ;
foreach ( var pawn in playerPawns )
pawn . MoveToCustomTilePosition ( safeTile . CenterPlacementPosition ) ;
}
2026-01-22 20:50:41 +05:30
}
2026-01-26 13:03:50 +05:30
else
{
2026-01-29 18:13:07 +05:30
currentSittingTile . ResetPlayerPawn ( playerPawn ) ;
2026-01-26 13:03:50 +05:30
}
2026-01-22 20:50:41 +05:30
MoveThroughTiles ( playerPawn , nextTileIdx , targetIndex : targetIdx ) ;
2026-01-21 20:27:45 +05:30
}
}
2026-01-29 19:48:25 +05:30
private void ApplyFinishingPathLogic ( PlayerPawn playerPawn )
{
int finishingPathIndex = GetNextFinishingTileIndex ( playerPawn ) ;
int targetIdx = finishingPathIndex + diceRolledValue > tilesManager . GetFinishingTileDataLength ( currentPlayerTypeTurn ) - 1 ?
tilesManager . GetFinishingTileDataLength ( currentPlayerTypeTurn ) - 1 : finishingPathIndex + diceRolledValue ;
Debug . Log ( $"TargetIdx: {targetIdx}, finishingPathIndex: {finishingPathIndex}" ) ;
MoveThroughFinishingPath ( playerPawn , finishingPathIndex , targetIdx ) ;
}
2026-01-29 15:54:13 +05:30
public int GetNextGeneralTileIndex ( PlayerPawn playerPawn )
2026-01-22 20:50:41 +05:30
{
return playerPawn . CurrentTileIndex = = tilesManager . GetGeneralTilesLength ( ) - 1 ? 0 : playerPawn . CurrentTileIndex + 1 ;
}
private int GetNextFinishingTileIndex ( PlayerPawn playerPawn )
{
return playerPawn . CurrentTileIndex > tilesManager . GetFinishingTileDataLength ( currentPlayerTypeTurn ) - 1 ? 0 : playerPawn . CurrentTileIndex + 1 ;
}
private void SwitchPlayer ( PlayerPawn playerPawn = null )
2026-01-21 20:27:45 +05:30
{
2026-01-28 16:57:27 +05:30
Debug . Log ( $"CallTest: SwitchPlayer" ) ;
2026-01-30 19:04:14 +05:30
if ( playerPawn )
UpdatePlayerState ( playerPawn , tilesManager . RetrieveTileBasedOnIndex ( playerPawn . CurrentTileIndex ) . IsSafeZone ? PlayerState . InSafeZone : PlayerState . Moving ) ;
2026-01-28 16:57:27 +05:30
2026-01-22 20:50:41 +05:30
if ( ! CanRollDiceAgain )
2026-01-21 20:27:45 +05:30
{
2026-01-22 20:50:41 +05:30
Debug . Log ( $"currentPlayerTurn: {currentPlayerTypeTurn}" ) ;
Debug . Log ( $"currentPlayerTurnIndex: {currentPlayerTurnIndex}" ) ;
2026-01-30 19:04:14 +05:30
Debug . Log ( $"before SwitchPlayer availPlayers: {availPlayers.Count}, playerPawn: {playerPawn}" ) ;
if ( availPlayers . Count < 1 )
InitActivePlayers ( ) ;
Debug . Log ( $"after SwitchPlayer availPlayers: {availPlayers.Count}, playerPawn: {playerPawn}" ) ;
foreach ( var pawn in availPlayers )
{
DisplayPlayerCountOnTile ( pawn , false ) ;
}
2026-01-27 20:55:55 +05:30
if ( allPlayerTypes . Count = = 1 )
2026-01-22 20:50:41 +05:30
{
Debug . LogError ( $"GAME IS OVER" ) ;
return ;
}
2026-01-27 20:55:55 +05:30
if ( currentPlayerTypeTurn = = allPlayerTypes [ allPlayerTypes . Count - 1 ] )
2026-01-21 20:27:45 +05:30
{
currentPlayerTurnIndex = 0 ;
2026-01-27 20:55:55 +05:30
currentPlayerTypeTurn = allPlayerTypes [ currentPlayerTurnIndex ] ;
2026-01-21 20:27:45 +05:30
}
else
{
currentPlayerTurnIndex + + ;
2026-01-27 20:55:55 +05:30
currentPlayerTypeTurn = allPlayerTypes [ currentPlayerTurnIndex ] ;
2026-01-21 20:27:45 +05:30
}
2026-01-26 19:48:55 +05:30
2026-01-30 22:17:18 +05:30
uIManager . UpdatePlayerTurnText ( currentPlayerTypeTurn ) ;
2026-01-29 21:15:48 +05:30
diceSixRollCounter = 0 ;
2026-01-26 19:48:55 +05:30
diceText . text = $"{0}" ;
2026-01-30 19:04:14 +05:30
InitActivePlayers ( ) ;
foreach ( var pawn in availPlayers )
{
DisplayPlayerCountOnTile ( pawn , true ) ;
}
2026-01-21 20:27:45 +05:30
}
2026-01-29 22:16:54 +05:30
SetCanRollDiceForUser ( ! botTypesInGame . Contains ( currentPlayerTypeTurn ) ) ;
2026-01-26 13:03:50 +05:30
Debug . Log ( $"CurrentPlayerTurn: {currentPlayerTypeTurn}" ) ;
var tempPos = playerBaseHandler . GetPlayerBase ( currentPlayerTypeTurn ) . transform . position ;
pointerDebug . position = new Vector3 ( tempPos . x , 3f , tempPos . z ) ;
2026-01-21 20:27:45 +05:30
pointerMeshRend . material = turnMat ;
// pointerMeshRend.materials[0] = turnMat;
2026-01-22 20:50:41 +05:30
2026-01-27 20:55:55 +05:30
Debug . Log ( $"botTypesInGame.Contains(currentPlayerTypeTurn): {botTypesInGame.Contains(currentPlayerTypeTurn)}" ) ;
2026-01-28 16:57:27 +05:30
if ( botTypesInGame . Contains ( currentPlayerTypeTurn ) ) // TODO :: Double check calling of the function
2026-01-27 20:55:55 +05:30
{
2026-01-28 16:57:27 +05:30
Debug . Log ( $"Invoking RollDiceForBot" ) ;
2026-01-30 11:30:40 +05:30
Invoke ( nameof ( HandleDiceRoll ) , 1f ) ;
2026-01-27 20:55:55 +05:30
}
}
2026-01-21 20:27:45 +05:30
private void MoveThroughTiles ( PlayerPawn playerPawn , int index , int targetIndex )
{
2026-01-22 20:50:41 +05:30
Tile nextTile = tilesManager . RetrieveTileBasedOnIndex ( index ) ;
2026-01-23 12:46:59 +05:30
Vector3 targetPosition = nextTile . CenterPlacementPosition ;
2026-01-22 20:50:41 +05:30
2026-01-23 12:46:59 +05:30
Debug . Log ( $"Tile Index :: nextIndex: {index}, targetIndex: {targetIndex}, nextTileName: {nextTile.name}" ) ;
if ( index = = targetIndex ) // if the target index is the safe zone only then apply the logic for rearranging pawns
2026-01-22 20:50:41 +05:30
{
Tile targetTile = tilesManager . RetrieveTileBasedOnIndex ( targetIndex ) ;
if ( targetTile . IsSafeZone )
2026-01-21 20:27:45 +05:30
{
2026-01-23 13:33:16 +05:30
targetPosition = GetAndInitPositionInsideSafeZone ( playerPawn , targetTile ) ;
2026-01-22 20:50:41 +05:30
}
}
2026-01-23 12:46:59 +05:30
Debug . Log ( $"tile targetPosition: {targetPosition}" ) ;
2026-01-30 19:04:14 +05:30
DisplayPlayerCountOnTile ( playerPawn , false ) ;
2026-01-23 12:46:59 +05:30
2026-01-22 20:50:41 +05:30
playerPawn . MoveToTile (
targetPosition ,
onComplete : ( ) = >
{
diceRolledValue - - ;
2026-01-23 12:46:59 +05:30
Debug . Log ( $"DiceRolledValue: {diceRolledValue}" ) ;
2026-01-22 20:50:41 +05:30
if ( diceRolledValue > 0 )
{
int nextTileIndex = GetNextGeneralTileIndex ( playerPawn ) ;
2026-01-23 12:46:59 +05:30
Debug . Log ( $"currentTileIndex: {playerPawn.CurrentTileIndex}, nextTileIndex: {nextTileIndex}, targetIndex: {targetIndex}" ) ;
2026-01-22 20:50:41 +05:30
if ( playerPawn . GetPlayerState ( ) = = PlayerState . InFinishingPath | | index = = playerGameDatasDict [ currentPlayerTypeTurn ] . endIndex )
2026-01-21 20:27:45 +05:30
{
2026-01-22 20:50:41 +05:30
// MoveThroughTiles(playerPawn, index, targetIndex);
Debug . Log ( $"TargetIdx: {targetIndex - index}" ) ;
MoveThroughFinishingPath ( playerPawn , 0 , targetIndex - index ) ;
2026-01-21 20:27:45 +05:30
}
2026-01-22 20:50:41 +05:30
else if ( nextTileIndex < = targetIndex )
{
if ( nextTileIndex = = 0 )
2026-01-23 12:46:59 +05:30
targetIndex = ( targetIndex - playerPawn . CurrentTileIndex ) - 1 ;
2026-01-21 20:27:45 +05:30
2026-01-22 20:50:41 +05:30
MoveThroughTiles ( playerPawn , nextTileIndex , targetIndex ) ;
}
}
else
{
2026-01-30 19:04:14 +05:30
// TODO :: Improve this logic, use a collection
2026-01-26 13:03:50 +05:30
Debug . Log ( $"nextTile.IsSafeZone: {nextTile.IsSafeZone}" ) ;
2026-01-30 19:04:14 +05:30
if ( CanRollDiceAgain )
DisplayPlayerCountOnTile ( playerPawn , true ) ;
2026-01-23 12:46:59 +05:30
if ( ! nextTile . IsSafeZone )
{
2026-01-29 18:13:07 +05:30
Debug . Log ( $"nextTile.HasPawnsAvailable: {nextTile.HasPawnsAvailable}" ) ;
if ( nextTile . HasPawnsAvailable & & playerPawn . PlayerType ! = nextTile . CurrentHoldingPlayerType )
2026-01-23 12:46:59 +05:30
{
2026-01-29 18:13:07 +05:30
Debug . Log ( $"nextTile.PlayerPawn: {nextTile.CurrentHoldingPlayerType}, {nextTile.transform.name}" ) ;
Debug . Log ( $"nextTile.TotalPawnsInTile: {nextTile.TotalPawnsInTile}" ) ;
2026-01-26 13:03:50 +05:30
// play animation for moving back to base.
2026-01-23 12:46:59 +05:30
// TODO :: Send existing pawn back to base.
// means there's already a pawn there, move him back to the base.
2026-01-29 19:48:25 +05:30
int counter = nextTile . TotalPawnsInTile ;
2026-01-29 18:13:07 +05:30
for ( int i = counter ; i > 0 ; i - - )
{
var pawn = nextTile . GetPlayerPawn ( ) ;
Debug . Log ( $"pawn: {pawn}" ) ;
Debug . Log ( $"playerBase: {playerBaseHandler}" ) ;
2026-01-30 19:04:14 +05:30
2026-01-29 18:13:07 +05:30
var playerBasePos = playerBaseHandler . GetPlayerBase ( pawn . PlayerType )
. GetBasePlacementDataPosition ( pawn . PlayerId - 1 ) ;
Debug . Log ( $"playerBasePos: {playerBasePos}" ) ;
playerGameDatasDict [ pawn . PlayerType ] . totalPawnsInHome + + ;
pawn . MoveBackToHome ( playerBasePos ) ;
}
2026-01-29 19:48:25 +05:30
2026-01-29 21:15:48 +05:30
if ( CheckForMaxDiceRollAttempt ( ) )
{
nextTile . InitPlayerPawn ( playerPawn , currentPlayerTypeTurn ) ;
return ;
}
2026-01-29 19:48:25 +05:30
CanRollDiceAgain = true ;
if ( playerPawn . IsBotPlayer )
CheckDiceRollForBot ( playerPawn ) ;
else
2026-01-29 22:16:54 +05:30
SetCanRollDiceForUser ( true ) ;
2026-01-23 12:46:59 +05:30
}
nextTile . InitPlayerPawn ( playerPawn , currentPlayerTypeTurn ) ;
2026-01-29 21:15:48 +05:30
if ( CheckForMaxDiceRollAttempt ( ) )
{
return ;
}
}
else
{
if ( CheckForMaxDiceRollAttempt ( ) )
{
return ;
}
2026-01-23 12:46:59 +05:30
}
2026-01-29 19:59:17 +05:30
SwitchPlayer ( playerPawn ) ;
2026-01-21 20:27:45 +05:30
}
2026-01-30 19:04:14 +05:30
} ,
2026-01-21 20:27:45 +05:30
index ) ;
}
2026-01-23 13:33:16 +05:30
private Vector3 GetAndInitPositionInsideSafeZone ( PlayerPawn playerPawn , Tile targetTile )
2026-01-23 12:46:59 +05:30
{
Vector3 targetPosition ;
SafeTile targetSafeTile = ( SafeTile ) targetTile ;
Debug . Log ( $"targetSafeTile.PlayerTypesCount: {targetSafeTile.PlayerTypesCount}" ) ;
if ( targetSafeTile . PlayerTypesCount = = 1 )
{
Debug . Log ( $"targetSafeTile.ContainsPlayerType(currentPlayerTypeTurn): {targetSafeTile.ContainsPlayerType(currentPlayerTypeTurn)}" ) ;
if ( ! targetSafeTile . ContainsPlayerType ( currentPlayerTypeTurn ) ) // means it is a new player type, the second one
{
2026-01-26 19:48:55 +05:30
PlayerType initialPlayerType = targetSafeTile . GetFirstPlayerType ( ) ;
2026-01-23 12:46:59 +05:30
// rearrange already existing player from center position to it's saved transform
var playerPawns = targetSafeTile . GetPlayerPawns ( initialPlayerType ) ;
foreach ( var pawn in playerPawns )
{
var placementPoint = targetSafeTile . GetPlacementPoint ( initialPlayerType ) ;
2026-01-23 13:33:16 +05:30
pawn . MoveToCustomTilePosition ( placementPoint . position ) ;
2026-01-23 12:46:59 +05:30
}
targetSafeTile . InitPlayerPawn ( playerPawn , currentPlayerTypeTurn ) ;
targetPosition = targetSafeTile . GetPlacementPoint ( currentPlayerTypeTurn ) . position ;
}
else
{
targetSafeTile . InitPlayerPawn ( playerPawn , currentPlayerTypeTurn ) ;
targetPosition = targetTile . CenterPlacementPosition ;
}
}
else
{
// TODO :: Check the data if it's consistent
Debug . Log ( $"targetSafeTile.ContainsPlayerType(currentPlayerTypeTurn): {targetSafeTile.ContainsPlayerType(currentPlayerTypeTurn)}" ) ;
if ( ! targetSafeTile . ContainsPlayerType ( currentPlayerTypeTurn ) )
{
2026-01-30 19:04:14 +05:30
Debug . Log ( $"targetSafeTile.PlayerTypesCount: {targetSafeTile.PlayerTypesCount}" ) ;
2026-01-23 12:46:59 +05:30
if ( targetSafeTile . PlayerTypesCount < 1 ) // he is the only player that is being added to the safe zone
{
targetSafeTile . InitPlayerPawn ( playerPawn , currentPlayerTypeTurn ) ;
targetPosition = targetTile . CenterPlacementPosition ;
}
else
{
targetSafeTile . InitPlayerPawn ( playerPawn , currentPlayerTypeTurn ) ;
targetPosition = targetSafeTile . GetPlacementPoint ( currentPlayerTypeTurn ) . position ;
}
}
else
{
targetSafeTile . InitPlayerPawn ( playerPawn , currentPlayerTypeTurn ) ;
targetPosition = targetSafeTile . GetPlacementPoint ( currentPlayerTypeTurn ) . position ;
}
}
return targetPosition ;
}
2026-01-21 20:27:45 +05:30
private void MoveThroughFinishingPath ( PlayerPawn playerPawn , int index , int targetIndex )
{
2026-01-28 16:57:27 +05:30
UpdatePlayerState ( playerPawn , PlayerState . InFinishingPath ) ;
2026-01-30 19:14:08 +05:30
2026-01-21 20:27:45 +05:30
playerPawn . MoveToTile (
2026-01-22 20:50:41 +05:30
tilesManager . RetrievePositionForFinishingTile ( currentPlayerTypeTurn , index ) . position ,
2026-01-21 20:27:45 +05:30
onComplete : ( ) = >
{
2026-01-22 20:50:41 +05:30
diceRolledValue - - ;
Debug . Log ( $"DiceRolledValue: {diceRolledValue}" ) ;
if ( diceRolledValue > 0 )
2026-01-21 20:27:45 +05:30
{
2026-01-22 20:50:41 +05:30
int tileIndex = GetNextFinishingTileIndex ( playerPawn ) ;
Debug . Log ( $"tileIndex: {tileIndex}, targetIndex: {targetIndex}" ) ;
if ( tileIndex < = targetIndex )
{
// MoveThroughTiles(playerPawn, index, targetIndex);
MoveThroughFinishingPath ( playerPawn , tileIndex , targetIndex ) ;
}
2026-01-21 20:27:45 +05:30
}
else
{
2026-01-30 19:14:08 +05:30
2026-01-28 20:57:35 +05:30
Debug . Log ( $"CurrentTileIndex: {playerPawn.CurrentTileIndex} == lastIndex: {tilesManager.GetFinishingTileDataLength(currentPlayerTypeTurn) - 1}" ) ;
2026-01-22 20:50:41 +05:30
if ( playerPawn . CurrentTileIndex = = tilesManager . GetFinishingTileDataLength ( currentPlayerTypeTurn ) - 1 )
{
2026-01-28 16:57:27 +05:30
UpdatePlayerState ( playerPawn , PlayerState . HasFinished ) ;
2026-01-22 20:50:41 +05:30
playerGameDatasDict [ currentPlayerTypeTurn ] . totalPawnsFinished + + ;
2026-01-29 18:44:41 +05:30
Debug . Log ( $"totalPawnsFinished: {playerGameDatasDict[currentPlayerTypeTurn].totalPawnsFinished}, playerPawnsDict.Count: {playerGameDatasDict[currentPlayerTypeTurn].playerPawnsDict.Count}" ) ;
2026-01-23 12:46:59 +05:30
if ( playerGameDatasDict [ currentPlayerTypeTurn ] . totalPawnsFinished = = playerGameDatasDict [ currentPlayerTypeTurn ] . playerPawnsDict . Count )
2026-01-22 20:50:41 +05:30
{
CanRollDiceAgain = false ;
2026-01-29 19:48:25 +05:30
2026-01-27 20:55:55 +05:30
if ( allPlayerTypes . Contains ( currentPlayerTypeTurn ) )
2026-01-30 09:35:31 +05:30
{
2026-01-27 20:55:55 +05:30
allPlayerTypes . Remove ( currentPlayerTypeTurn ) ;
2026-01-30 21:51:33 +05:30
playerDatas [ ( int ) currentPlayerTypeTurn ] . ranking = TotalPlayersInGame - allPlayerTypes . Count ;
2026-01-30 09:35:31 +05:30
}
if ( allPlayerTypes . Count = = 1 )
{
// Game is over
2026-01-30 21:51:33 +05:30
allPlayerTypes . RemoveAt ( 0 ) ;
playerDatas [ ( int ) currentPlayerTypeTurn ] . ranking = TotalPlayersInGame - allPlayerTypes . Count ;
2026-01-30 09:35:31 +05:30
// Show Game Over panel
2026-01-30 21:51:33 +05:30
gameManager . OnGameStateChanged ( GameState . GameOver ) ;
2026-01-30 09:35:31 +05:30
return ;
}
2026-01-29 19:48:25 +05:30
2026-01-29 18:44:41 +05:30
SwitchPlayer ( ) ;
2026-01-22 20:50:41 +05:30
2026-01-27 20:55:55 +05:30
Debug . Log ( $"PlayerTypes: {allPlayerTypes.Count}" ) ;
2026-01-22 20:50:41 +05:30
}
else
{
CanRollDiceAgain = true ;
2026-01-28 20:57:35 +05:30
if ( playerPawn . IsBotPlayer )
2026-01-30 12:54:43 +05:30
CheckDiceRollForBot ( playerPawn ) ;
2026-01-30 19:04:14 +05:30
else
2026-01-30 12:54:43 +05:30
SetCanRollDiceForUser ( true ) ;
2026-01-22 20:50:41 +05:30
}
}
else
{
2026-01-30 19:14:08 +05:30
// activate here
2026-01-29 21:15:48 +05:30
if ( CheckForMaxDiceRollAttempt ( ) )
{
return ;
}
2026-01-22 20:50:41 +05:30
SwitchPlayer ( ) ;
}
2026-01-21 20:27:45 +05:30
}
2026-01-30 19:04:14 +05:30
} ,
2026-01-21 20:27:45 +05:30
index ) ;
}
2026-01-29 19:48:25 +05:30
2026-01-29 22:16:54 +05:30
private void SetCanRollDiceForUser ( bool state )
2026-01-29 19:48:25 +05:30
{
2026-01-30 11:30:40 +05:30
CanRollDiceForUser = state ;
2026-01-30 12:54:43 +05:30
Debug . Log ( $"CAnRollDiceForUser: {CanRollDiceForUser}" ) ;
2026-01-29 19:48:25 +05:30
}
2026-01-30 19:04:14 +05:30
private void DisplayPlayerCountOnTile ( PlayerPawn playerPawn , bool show )
{
Tile tile = tilesManager . RetrieveTileBasedOnIndex ( playerPawn . CurrentTileIndex ) ;
Debug . Log ( $"Displaycount: {playerPawn.name} on tile: {tile.name}, show: {show}" ) ;
playerPawn . ShowPlayerCountCanvas ( show ) ;
if ( ! show ) return ;
int count = 0 ;
if ( tile . IsSafeZone )
{
count = ( tile as SafeTile ) . GetPlayerPawnsCountInTile ( playerPawn . PlayerType ) ;
}
else
{
count = tile . TotalPawnsInTile ;
}
playerPawn . GetComponentInChildren < PlayerCountCanvas > ( ) . SetPlayerCount ( count ) ;
}
2026-01-30 21:51:33 +05:30
public void ResetData ( )
{
playerDatas = null ;
botTypesInGame = null ;
allPlayerTypes = null ;
botRuntimeMovementData = null ;
playerGameDatasDict = null ;
playerDatas = null ;
availPlayers = null ;
}
2026-01-21 20:27:45 +05:30
}