private bool AssignTeamAndPlayer(int team_request, Player dest_player) { int team_assignment = 0; int player_assignment = 0; if (players.Count >= MAX_PLAYER_COUNT) { HostDebugWriteLine("Max player count hit"); return false; } switch (game_state.game_type) { //Solo Games case CommandCode.COMMAND_CODE_CUSTOM_GAME_MODE_HOST: case CommandCode.COMMAND_CODE_OWN_THE_ZONE_GAME_MODE_HOST: /** * Cycle through all spots until we find an open one */ for (int team_index = 0; team_index < 3; team_index++) { for (int player_number = 0; player_number < 8; player_number++) { bool found = false; foreach (Player p in players) { if (p.team_index == team_index && p.player_number == player_number) { found = true; break; } } if (!found) { dest_player.team_index = team_index; dest_player.team_number = team_index + 1; dest_player.player_number = player_number; return true; } } } return false; //Team Games case CommandCode.COMMAND_CODE_2TMS_GAME_MODE_HOST: case CommandCode.COMMAND_CODE_3TMS_GAME_MODE_HOST: case CommandCode.COMMAND_CODE_HIDE_AND_SEEK_GAME_MODE_HOST: case CommandCode.COMMAND_CODE_HUNT_THE_PREY_GAME_MODE_HOST: case CommandCode.COMMAND_CODE_2_KINGS_GAME_MODE_HOST: case CommandCode.COMMAND_CODE_3_KINGS_GAME_MODE_HOST: case CommandCode.COMMAND_CODE_2TMS_OWN_THE_ZONE_GAME_MODE_HOST: case CommandCode.COMMAND_CODE_3TMS_OWN_THE_ZONE_GAME_MODE_HOST: /** * We first locate the smallest team, then assign an unused player slot */ if (team_request > 0 && team_request <= game_state.number_of_teams) { team_assignment = team_request; } else { //team request is any or invalid int i = 0; int lowest_team_player_count = 0; int max_player_count = 8; for (i = 1; i <= game_state.number_of_teams; i++) { int player_count = 0; foreach (Player p in players) { if (p.team_number == i) player_count++; } if (player_count < max_player_count) { lowest_team_player_count = i; max_player_count = player_count; } } if (lowest_team_player_count != 0) { team_assignment = lowest_team_player_count; } else { HostDebugWriteLine("Unable to assign team"); return false; } } break; default: HostDebugWriteLine("Unable to assign team"); return false; } /*switch (game_state.game_type) { case CommandCode.COMMAND_CODE_CUSTOM_GAME_MODE_HOST: case CommandCode.COMMAND_CODE_2TMS_GAME_MODE_HOST: case CommandCode.COMMAND_CODE_3TMS_GAME_MODE_HOST:*/ { int i = 0; for (i = 0; i < 8; i++) { bool found = false; foreach (Player p in players) { if (team_assignment != p.team_number) continue; if (i == p.player_number) { found = true; break; } } if (!found) { player_assignment = i; break; } } if (i == 8) { HostDebugWriteLine("Failed to assign player number"); return false; } //break; } /*default: return false; }*/ dest_player.team_number = team_assignment; dest_player.team_index = team_assignment - 1; dest_player.player_number = player_assignment; HostDebugWriteLine("Assigned player to team " + team_assignment + " and player " + player_assignment); return true; }
public void RunRankTests() { game_state.game_type = CommandCode.COMMAND_CODE_3TMS_GAME_MODE_HOST; hosting_state = HostingState.HOSTING_STATE_GAME_OVER; Player p1 = new Player(0x01); Player p2 = new Player(0x02); Player p3 = new Player(0x03); players.AddLast(p1); players.AddLast(p2); players.AddLast(p3); p1.team_number = 1; p1.player_number = 0; p1.alive = true; p2.team_number = 2; p2.player_number = 1; p2.alive = true; p3.team_number = 3; p3.player_number = 3; p3.alive = false; p1.hit_by_team_player_count[1,1] = 6; p2.hit_team_player_count[2,0] = 6; p1.hit_team_player_count[0,5] = 6; RankPlayers(); PrintScoreReport(); }
private bool AssignTeamAndPlayer(int requestedTeam, Player newPlayer) { int assignedTeamNumber = 0; var assignedPlayerNumber = 0; if (_players.Count >= TeamPlayerId.MaximumPlayerNumber) { Log.Add(Log.Severity.Information, "Cannot add player. The game is full."); return false; } if (GameDefinition.IsTeamGame) { var isTagMasterGame = ( GameDefinition.GameType == GameType.TagMasterHideAndSeek || GameDefinition.GameType == GameType.TagMasterHuntThePrey || GameDefinition.GameType == GameType.HuntTheTagMasterTwoTeams); // Count the players on each team and find the smallest team var teamPlayerCounts = new int[_gameDefinition.TeamCount]; var smallestTeamNumber = 0; var smallestTeamPlayerCount = 8; for (var teamNumber = 1; teamNumber <= _gameDefinition.TeamCount; teamNumber++) { var teamPlayerCount = 0; foreach (var player in _players) { if (player.TeamPlayerId.TeamNumber == teamNumber) teamPlayerCount++; } // In Tag Master games, team 1 is full once it has a player if (isTagMasterGame && teamNumber == 1 && teamPlayerCount > 0) teamPlayerCount = 8; if (teamPlayerCount < smallestTeamPlayerCount) { smallestTeamNumber = teamNumber; smallestTeamPlayerCount = teamPlayerCount; } teamPlayerCounts[teamNumber - 1] = teamPlayerCount; } if (smallestTeamNumber == 0) { Log.Add(Log.Severity.Information, "All teams are full."); return false; } if (requestedTeam > 0 && requestedTeam <= _gameDefinition.TeamCount && teamPlayerCounts[requestedTeam - 1] < 8) { assignedTeamNumber = requestedTeam; } else { assignedTeamNumber = smallestTeamNumber; } for (var playerNumber = 1; playerNumber <= 8; playerNumber++) { if (_players.Player(new TeamPlayerId(assignedTeamNumber, playerNumber)) == null) { assignedPlayerNumber = playerNumber; break; } } } else { // Assign player to the first open player number for (var playerNumber = 1; playerNumber <= 24; playerNumber++) { var teamPlayerId = new TeamPlayerId(playerNumber); if (_players.Player(teamPlayerId) != null) continue; assignedTeamNumber = teamPlayerId.TeamNumber; assignedPlayerNumber = playerNumber; break; } } if (assignedTeamNumber == 0 || assignedPlayerNumber == 0) { Log.Add(Log.Severity.Warning, "Unable to assign a player number."); return false; } if (_gameDefinition.IsTeamGame) { newPlayer.TeamPlayerId = new TeamPlayerId(assignedTeamNumber, assignedPlayerNumber); } else { newPlayer.TeamPlayerId = new TeamPlayerId(assignedPlayerNumber); } newPlayer.Team = Teams.Team(assignedTeamNumber); Teams.Team(assignedTeamNumber).Players.Add(newPlayer); return true; }
private bool ProcessCommandSequence() { DateTime now = DateTime.Now; switch (hosting_state) { case HostingState.HOSTING_STATE_IDLE: { #if JOIN_PLAYERS_TEST if (!autostart) { IRPacket command_packet = incoming_packet_queue[0]; IRPacket game_id_packet = incoming_packet_queue[1]; if (command_packet.data == (UInt16)CommandCode.COMMAND_CODE_CUSTOM_GAME_MODE_HOST) { System.Threading.Thread.Sleep(100); byte game_id = (byte)game_id_packet.data; if (join_count < 100) { join_count++; if (join_count % 10 == 0) { SendPlayerJoin(game_id); } } } else if (command_packet.data == (UInt16)CommandCode.COMMAND_CODE_ACK_PLAYER_JOIN_RESPONSE) { System.Threading.Thread.Sleep(100); IRPacket player_id_packet = incoming_packet_queue[2]; UInt16[] join = { (UInt16)CommandCode.COMMAND_CODE_CONFIRM_PLAY_JOIN_GAME, game_id_packet.data, player_id_packet.data, }; TransmitPacket2(ref join); } } #endif return true; } case HostingState.HOSTING_STATE_ADDING: { if (incoming_packet_queue.Count != 4) { return false; } IRPacket command_packet = incoming_packet_queue[0]; IRPacket game_id_packet = incoming_packet_queue[1]; IRPacket player_id_packet = incoming_packet_queue[2]; IRPacket player_team_request_packet = incoming_packet_queue[3]; UInt16 player_id = player_id_packet.data; if ((CommandCode)command_packet.data != CommandCode.COMMAND_CODE_PLAYER_JOIN_GAME_REQUEST) { HostDebugWriteLine("Wrong command"); return false; } if (game_id != game_id_packet.data) { HostDebugWriteLine("Wrong game id"); return false; } bool collision = false; foreach (Player collision_check_player in players) { if (collision_check_player.player_id == player_id) { collision = true; break; } } if (collision) { HostDebugWriteLine("Player id collision"); return false; } confirm_join_state.player_id = (byte)player_id; /* * 0 = any * 1-3 = team 1-3 */ UInt16 team_request = (UInt16)(player_team_request_packet.data & 0x03); Player p = new Player((byte)player_id); if (!AssignTeamAndPlayer(team_request, p)) { return false; } players.AddLast(p); UInt16 team_response = (UInt16)((p.team_number << 3) | (p.player_number)); UInt16[] values = new UInt16[]{ (UInt16)CommandCode.COMMAND_CODE_ACK_PLAYER_JOIN_RESPONSE, game_id,//Game ID player_id,//Player ID team_response, //player # // [3 bits - zero - unknown][2 bits - team assignment][3 bits - player assignment] }; if (game_id_packet.data != game_id) { HostDebugWriteLine("Game id does not match current game, discarding"); return false; } string debug = String.Format("Player {0:x} found, joining", new object[] { player_id }); HostDebugWriteLine(debug); TransmitPacket2(ref values); incoming_packet_queue.Clear(); hosting_state = HostGun.HostingState.HOSTING_STATE_CONFIRM_JOIN; state_change_timeout = now.AddSeconds(2); return true; } case HostingState.HOSTING_STATE_CONFIRM_JOIN: { if (incoming_packet_queue.Count != 3) { return false; } IRPacket command_packet = incoming_packet_queue[0]; IRPacket game_id_packet = incoming_packet_queue[1]; IRPacket player_id_packet = incoming_packet_queue[2]; UInt16 confirmed_game_id = game_id_packet.data; UInt16 confirmed_player_id = player_id_packet.data; if ((CommandCode)command_packet.data != CommandCode.COMMAND_CODE_CONFIRM_PLAY_JOIN_GAME) { HostDebugWriteLine("Wrong command"); return false; } if (game_id != confirmed_game_id || confirm_join_state.player_id != confirmed_player_id) { string debug = String.Format("{0:x},{1:x},{2:x},{3:x}", new object[] { game_id, confirmed_game_id, confirm_join_state.player_id, confirmed_player_id}); HostDebugWriteLine("Invalid confirmation: " + debug); ChangeState(now, HostingState.HOSTING_STATE_ADDING); break; } bool found = false; foreach(Player p in players) { if (p.player_id == confirmed_player_id) { p.confirmed = true; found = true; break; } } if (found) { HostDebugWriteLine("Confirmed player"); } else { HostDebugWriteLine("Unable to find player to confirm"); return false; } if (players.Count >= MINIMUM_PLAYER_COUNT_START) { state_change_timeout = now.AddSeconds(WAIT_FOR_ADDITIONAL_PLAYERS_TIMEOUT_SECONDS); } ChangeState(now, HostingState.HOSTING_STATE_ADDING); incoming_packet_queue.Clear(); if (listener != null) { listener.PlayerListChanged(new List<Player>(players)); } return true; } case HostingState.HOSTING_STATE_SUMMARY: { IRPacket command_packet = incoming_packet_queue[0]; switch ((CommandCode)command_packet.data) { case CommandCode.COMMAND_CODE_PLAYER_REPORT_SCORE: return ProcessPlayerReportScore(); case CommandCode.COMMAND_CODE_PLAYER_HIT_BY_TEAM_1_REPORT: case CommandCode.COMMAND_CODE_PLAYER_HIT_BY_TEAM_2_REPORT: case CommandCode.COMMAND_CODE_PLAYER_HIT_BY_TEAM_3_REPORT: return ProcessPlayerHitByTeamReport(); default: break; } return false; } default: break; } return false; }
private bool ProcessRequestJoinGame(UInt16 gameId, UInt16 taggerId, UInt16 requestedTeam) { // TODO: Handle multiple simultaneous games if (gameId != GameDefinition.GameId) { Log.Add(Log.Severity.Warning, "Wrong game ID."); return false; } Player player = null; foreach (var checkPlayer in Players) { if (checkPlayer.TaggerId == taggerId && !checkPlayer.Confirmed) { player = checkPlayer; break; } } if (player == null) { player = new Player(this, (byte)taggerId); if (!AssignTeamAndPlayer(requestedTeam, player)) return false; Players.Add(player); } var joinState = new JoinState { GameId = gameId, Player = player, AssignPlayerSendTime = DateTime.Now }; _joinStates.Remove(taggerId); _joinStates.Add(taggerId, joinState); Log.Add(Log.Severity.Information, "Assigning tagger 0x{0:X2} to player {1} for game 0x{2:X2}.", taggerId, player.TeamPlayerId.ToString(_gameDefinition.IsTeamGame), gameId); SendPlayerAssignment(player.TeamPlayerId); ChangeState(HostingStates.AcknowledgePlayerAssignment); return true; }