private void Start() { //CurrentRoom.SetRoomDirections((Room.RoomDirections)UnityEngine.Random.Range((int)1, (int)15)); //Setup players in current room. for (int i = 0; i < ClientBehaviour.Instance.Clients.Count; i++) { GameObject player = Instantiate(playerPrefab, RoomGameObject.spawnPositions[i].transform.position, RoomGameObject.spawnPositions[i].transform.rotation); player.name = ClientBehaviour.Instance.Clients[i].ClientName; player.GetComponent <Player>().Health = ClientBehaviour.Instance.Clients[i].StartHealth; player.GetComponent <Player>().Client = ClientBehaviour.Instance.Clients[i]; Players.Add(player.GetComponent <Player>()); player.SetActive(false); } if (ClientBehaviour.Instance.IsHost) //Send game info on start of game. { //Generate Grid if host. Grid = GetComponent <GridGeneration>(); Grid.GenerateGrid(); for (int i = 0; i < Players.Count; i++) { Grid.RoomGrid[0, 0].PlayersInRoom.Add(Players[i]); Players[i].CurrentRoom = Grid.RoomGrid[0, 0]; } //Set player turn PlayerCurrentTurn = Players[0]; #region RoomInfoMessage //Send Room Info var roomInfo = new RoomInfo() { MoveDirections = (byte)Grid.RoomGrid[0, 0].possibleDirections, TreasureInRoom = Grid.RoomGrid[0, 0].TreasureAmount, ContainsMonster = Grid.RoomGrid[0, 0].ContainsMonster, ContainsExit = Grid.RoomGrid[0, 0].ContainsExit, NumberOfOtherPlayers = (byte)ServerBehaviour.Instance.Clients.Count }; int[] playerIDs = new int[roomInfo.NumberOfOtherPlayers]; for (int f = 0; f < roomInfo.NumberOfOtherPlayers; f++) { playerIDs[f] = ServerBehaviour.Instance.Clients[f].ClientID; //Debug.Log(playerIDs[f]); } #endregion #region NextPlayerMessage //Send which player's turn it is. var playerTurn = new PlayerTurn { PlayerID = PlayerCurrentTurn.Client.ClientID }; #endregion #region SendMessages //Send Messages. for (int i = 0; i < ServerBehaviour.Instance.Clients.Count; i++) { var writer = ServerBehaviour.Instance.m_Driver.BeginSend(ServerBehaviour.Instance.m_Connections[i]); roomInfo.SerializeObject(ref writer, playerIDs); ServerBehaviour.Instance.m_Driver.EndSend(writer); var writer1 = ServerBehaviour.Instance.m_Driver.BeginSend(ServerBehaviour.Instance.m_Connections[i]); playerTurn.SerializeObject(ref writer1); ServerBehaviour.Instance.m_Driver.EndSend(writer1); } #endregion } }
public override void HandleMessages(Message.MessageType messageType, DataStreamReader reader, int ConnectionID) { if (IsClient) { //Clientside Handling switch (messageType) { case Message.MessageType.PlayerTurn: //This part handles the client side of a player turn. var playerTurn = new PlayerTurn(); playerTurn.DeserializeObject(ref reader); GameManager.Instance.PlayerTurnUI.text = "Current Turn: " + ClientBehaviour.Instance.Clients[playerTurn.PlayerID].ClientName; GameManager.Instance.PlayerCurrentTurn = GameManager.Instance.Players[playerTurn.PlayerID]; break; case Message.MessageType.RoomInfo: var roomInfo = new RoomInfo(); roomInfo.DeserializeObject(ref reader); GameManager.Instance.RoomGameObject.SetRoomProperties( (Room.RoomDirections)roomInfo.MoveDirections, roomInfo.TreasureInRoom, roomInfo.ContainsMonster, roomInfo.ContainsExit); #region SetNewPlayers //Disable all players first. for (int i = 0; i < GameManager.Instance.Players.Count; i++) { GameManager.Instance.Players[i].gameObject.SetActive(false); } //Then enable all players that are currently in this room. for (int f = 0; f < roomInfo.NumberOfOtherPlayers; f++) { if (!GameManager.Instance.Players[roomInfo.OtherPlayerIDs[f]].noTurn) { GameManager.Instance.Players[roomInfo.OtherPlayerIDs[f]].gameObject.SetActive(true); } } #endregion break; case Message.MessageType.PlayerEnterRoom: var playerEnter = new PlayerEnterRoom(); playerEnter.DeserializeObject(ref reader); GameManager.Instance.Players[playerEnter.PlayerID].gameObject.SetActive(true); if (playerEnter.PlayerID != ConnectionID) { string enterMessage = GameManager.Instance.Players[playerEnter.PlayerID].Client.ClientName + " joined the room"; ClientBehaviour.Instance.ClientUI.ShowMessage(enterMessage); } break; case Message.MessageType.PlayerLeaveRoom: var playerLeave = new PlayerLeaveRoom(); playerLeave.DeserializeObject(ref reader); GameManager.Instance.Players[playerLeave.PlayerID].gameObject.SetActive(false); if (playerLeave.PlayerID != ConnectionID) { string leftMessage = GameManager.Instance.Players[playerLeave.PlayerID].Client.ClientName + " left the room"; ClientBehaviour.Instance.ClientUI.ShowMessage(leftMessage); } break; case Message.MessageType.ObtainTreasure: var obtainedTreasure = new ObtainTreasure(); obtainedTreasure.DeserializeObject(ref reader); GameManager.Instance.RoomGameObject.ChestObject.SetActive(false); #region SetTreasureAmount if (ClientBehaviour.Instance.IsHost) { for (int f = 0; f < GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom.Count; f++) { GameManager.Instance.Players[GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom[f].Client.ClientID].PlayerTreasureAmount += obtainedTreasure.TreasureAmount; } } else { GameManager.Instance.Players[ClientBehaviour.Instance.PlayerID].PlayerTreasureAmount += obtainedTreasure.TreasureAmount; } #endregion string obtainMessage = GameManager.Instance.PlayerCurrentTurn.name + " took a treasure and shared it with everyone in the room. You gained " + obtainedTreasure.TreasureAmount + "$."; ClientBehaviour.Instance.ClientUI.ShowMessage(obtainMessage); break; case Message.MessageType.HitMonster: var hitMessage = new HitMonster(); hitMessage.DeserializeObject(ref reader); string hitString = GameManager.Instance.Players[hitMessage.PlayerAttackingID].Client.ClientName + " killed the monster."; ClientBehaviour.Instance.ClientUI.ShowMessage(hitString); GameManager.Instance.RoomGameObject.MonsterObject.SetActive(false); break; case Message.MessageType.HitByMonster: var playerHit = new HitByMonster(); playerHit.DeserializeObject(ref reader); GameManager.Instance.Players[playerHit.PlayerHitID].Health -= playerHit.DamageDealt; if (playerHit.PlayerHitID == ClientBehaviour.Instance.PlayerID) { ClientBehaviour.Instance.ClientUI.HealthInfo.text = GameManager.Instance.Players[playerHit.PlayerHitID].Health + "/" + ClientBehaviour.Instance.Clients[playerHit.PlayerHitID].StartHealth + " HP"; } string playerHitMessage = GameManager.Instance.Players[playerHit.PlayerHitID].Client.ClientName + " took " + playerHit.DamageDealt + " damage."; ClientBehaviour.Instance.ClientUI.ShowMessage(playerHitMessage); break; case Message.MessageType.PlayerDefends: var playerDefend = new PlayerDefend(); playerDefend.DeserializeObject(ref reader); if (playerDefend.PlayerDefendingID == ClientBehaviour.Instance.PlayerID) { ClientBehaviour.Instance.ClientUI.HealthInfo.text = GameManager.Instance.Players[playerDefend.PlayerDefendingID].Health + "/" + ClientBehaviour.Instance.Clients[playerDefend.PlayerDefendingID].StartHealth + " HP"; } string playerDefendMessage = GameManager.Instance.Players[playerDefend.PlayerDefendingID].Client.ClientName + " defended hismelf from the monster, and healed for 1 HP."; ClientBehaviour.Instance.ClientUI.ShowMessage(playerDefendMessage); break; case Message.MessageType.PlayerLeftDungeon: var playerLeft = new PlayerLeftDungeon(); playerLeft.DeserializeObject(ref reader); string leaveMessage = GameManager.Instance.Players[playerLeft.PlayerLeftID].Client.ClientName + " has left the dungeon."; ClientBehaviour.Instance.ClientUI.ShowMessage(leaveMessage); GameManager.Instance.Players[playerLeft.PlayerLeftID].gameObject.SetActive(false); GameManager.Instance.Players[playerLeft.PlayerLeftID].noTurn = true; if (!GameManager.Instance.LeftPlayers.Contains(GameManager.Instance.Players[playerLeft.PlayerLeftID])) { GameManager.Instance.LeftPlayers.Add(GameManager.Instance.Players[playerLeft.PlayerLeftID]); } break; case Message.MessageType.PlayerDies: var playerDies = new PlayerDies(); playerDies.DeserializeObject(ref reader); string deathMessage = GameManager.Instance.Players[playerDies.PlayerDeathID].Client.ClientName + " has died."; ClientBehaviour.Instance.ClientUI.ShowMessage(deathMessage); if (playerDies.PlayerDeathID == ClientBehaviour.Instance.PlayerID) { ClientBehaviour.Instance.ClientUI.HealthInfo.text = "0/" + ClientBehaviour.Instance.Clients[playerDies.PlayerDeathID].StartHealth + " HP"; } GameManager.Instance.Players[playerDies.PlayerDeathID].gameObject.SetActive(false); GameManager.Instance.Players[playerDies.PlayerDeathID].noTurn = true; GameManager.Instance.DeadPlayers.Add(GameManager.Instance.Players[playerDies.PlayerDeathID]); break; case Message.MessageType.EndGame: ClientBehaviour.Instance.ClientUI.ShowMessage("Game Over"); UnityEngine.SceneManagement.SceneManager.LoadScene("EndGame"); break; case Message.MessageType.MoveRequest: break; case Message.MessageType.AttackRequest: break; case Message.MessageType.DefendRequest: break; case Message.MessageType.ClaimTreasureRequest: break; case Message.MessageType.LeaveDungeonRequest: break; } } else { //Serverside Handling switch (messageType) { case Message.MessageType.PlayerTurn: break; case Message.MessageType.RoomInfo: break; case Message.MessageType.PlayerEnterRoom: break; case Message.MessageType.PlayerLeaveRoom: break; case Message.MessageType.ObtainTreasure: break; case Message.MessageType.HitMonster: break; case Message.MessageType.HitByMonster: break; case Message.MessageType.PlayerDefends: break; case Message.MessageType.PlayerLeftDungeon: break; case Message.MessageType.PlayerDies: break; case Message.MessageType.EndGame: break; case Message.MessageType.MoveRequest: //Handle Player Leaving the room. var moveRequest = new MoveRequest(); moveRequest.DeserializeObject(ref reader); //Remove Player form room. GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom.Remove(GameManager.Instance.Players[ConnectionID]); #region RoomLeaveInfo //Send to other clients in room that player left. var playerLeave = new PlayerLeaveRoom() { PlayerID = ConnectionID }; for (int j = 0; j < GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom.Count; j++) { var writer = ServerBehaviour.Instance.m_Driver.BeginSend( ServerBehaviour.Instance.m_Connections[ GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom[j].Client.ClientID ]); playerLeave.SerializeObject(ref writer); ServerBehaviour.Instance.m_Driver.EndSend(writer); } #endregion #region SetPlayerPosition //Set new room position. Vector2 currentGridPosition = GameManager.Instance.Players[ConnectionID].CurrentRoom.GridPosition; Vector2 positionTranslation = GameManager.Instance.Players[ConnectionID].CurrentRoom.MoveToNeighbour(moveRequest.MoveDirection); Vector2Int newPosition = new Vector2Int((int)currentGridPosition.x + (int)positionTranslation.x, (int)currentGridPosition.y + (int)positionTranslation.y); #endregion //Set new room variable. GameManager.Instance.Players[ConnectionID].CurrentRoom = GameManager.Instance.Grid.RoomGrid[newPosition.x, newPosition.y]; GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom.Add(GameManager.Instance.Players[ConnectionID]); #region RoomEnterInfo //Send to other clients in room that player entered. var playerJoin = new PlayerEnterRoom() { PlayerID = ConnectionID }; //Send to other clients. for (int e = 0; e < GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom.Count; e++) { var writer = ServerBehaviour.Instance.m_Driver.BeginSend( ServerBehaviour.Instance.m_Connections[ GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom[e].Client.ClientID ]); playerJoin.SerializeObject(ref writer); ServerBehaviour.Instance.m_Driver.EndSend(writer); } #endregion #region RoomInfo //Make new room info. var roomInfo = new RoomInfo() { MoveDirections = (byte)GameManager.Instance.Players[ConnectionID].CurrentRoom.possibleDirections, TreasureInRoom = GameManager.Instance.Players[ConnectionID].CurrentRoom.TreasureAmount, ContainsMonster = GameManager.Instance.Players[ConnectionID].CurrentRoom.ContainsMonster, ContainsExit = GameManager.Instance.Players[ConnectionID].CurrentRoom.ContainsExit, NumberOfOtherPlayers = (byte)GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom.Count }; //Search for ID's of players already in room. int[] newRoomIDs = new int[GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom.Count]; for (int i = 0; i < GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom.Count; i++) { newRoomIDs[i] = GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom[i].Client.ClientID; } #endregion //Send Room info to client that is moving room. var writer1 = ServerBehaviour.Instance.m_Driver.BeginSend(ServerBehaviour.Instance.m_Connections[ConnectionID]); roomInfo.SerializeObject(ref writer1, newRoomIDs); ServerBehaviour.Instance.m_Driver.EndSend(writer1); //Set next player's turn. GameManager.Instance.NextTurn(); break; case Message.MessageType.AttackRequest: GameManager.Instance.Players[ConnectionID].CurrentRoom.ContainsMonster = 0; var attackFeedback = new HitMonster() { PlayerAttackingID = ConnectionID, DamageDealt = 1 }; //Experiment: use foreach instead of for loop. conclusion: works pretty good and i'm an idiot for not using it everywhere else. foreach (Player player in GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom) { var writer = ServerBehaviour.Instance.m_Driver.BeginSend(ServerBehaviour.Instance.m_Connections[player.Client.ClientID]); attackFeedback.SerializeObject(ref writer); ServerBehaviour.Instance.m_Driver.EndSend(writer); //If the player's health is smaller than 2. the player dies of an attack by the monster. Else it'll take 2 damage. if (GameManager.Instance.Players[ConnectionID].Health > 2) { //the player that attacks also gets hit by the enemy. var attackPlayer = new HitByMonster() { PlayerHitID = ConnectionID, DamageDealt = 2 }; var writer2 = ServerBehaviour.Instance.m_Driver.BeginSend(ServerBehaviour.Instance.m_Connections[player.Client.ClientID]); attackPlayer.SerializeObject(ref writer2); ServerBehaviour.Instance.m_Driver.EndSend(writer2); } else { var playerDeath = new PlayerDies() { PlayerDeathID = ConnectionID }; var writer2 = ServerBehaviour.Instance.m_Driver.BeginSend(ServerBehaviour.Instance.m_Connections[player.Client.ClientID]); playerDeath.SerializeObject(ref writer2); ServerBehaviour.Instance.m_Driver.EndSend(writer2); if (GameManager.Instance.Players.Count == (GameManager.Instance.DeadPlayers.Count + 1)) { GameManager.Instance.EndGame(); } } } GameManager.Instance.NextTurn(); break; case Message.MessageType.DefendRequest: var defendRequest = new DefendRequest(); ushort newPlayerHP = GameManager.Instance.Players[ConnectionID].Health++; var defendFeedback = new PlayerDefend() { PlayerDefendingID = ConnectionID, NewHP = newPlayerHP }; foreach (Player player in GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom) { var writer = ServerBehaviour.Instance.m_Driver.BeginSend(ServerBehaviour.Instance.m_Connections[player.Client.ClientID]); defendFeedback.SerializeObject(ref writer); ServerBehaviour.Instance.m_Driver.EndSend(writer); } GameManager.Instance.NextTurn(); break; case Message.MessageType.ClaimTreasureRequest: int dividedAmount = GameManager.Instance.Players[ConnectionID].CurrentRoom.TreasureAmount / System.Convert.ToUInt16(GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom.Count); #region SendTreasureAmount //Send treasure amount to all players in room. var treasureObtain = new ObtainTreasure() { TreasureAmount = (ushort)dividedAmount }; //Send to other clients. for (int e = 0; e < GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom.Count; e++) { var writer = ServerBehaviour.Instance.m_Driver.BeginSend( ServerBehaviour.Instance.m_Connections[ GameManager.Instance.Players[ConnectionID].CurrentRoom.PlayersInRoom[e].Client.ClientID ]); treasureObtain.SerializeObject(ref writer); ServerBehaviour.Instance.m_Driver.EndSend(writer); } #endregion GameManager.Instance.Players[ConnectionID].CurrentRoom.TreasureAmount = 0; GameManager.Instance.NextTurn(); break; case Message.MessageType.LeaveDungeonRequest: var dungeonLeftMessage = new PlayerLeftDungeon { PlayerLeftID = ConnectionID }; for (int i = 0; i < ServerBehaviour.Instance.Clients.Count; i++) { var writer = ServerBehaviour.Instance.m_Driver.BeginSend(ServerBehaviour.Instance.m_Connections[i]); dungeonLeftMessage.SerializeObject(ref writer); ServerBehaviour.Instance.m_Driver.EndSend(writer); } if (GameManager.Instance.Players.Count == (GameManager.Instance.LeftPlayers.Count + 1)) { GameManager.Instance.LeftPlayers.Add(GameManager.Instance.Players[ConnectionID]); GameManager.Instance.EndGame(); } else { //Set next player's turn. GameManager.Instance.NextTurn(); } break; } } }