protected override void OnMsgClientSetTeam(BasePlayer player, GameMsg_ClSetTeam message) { if (!GameController.IsTeamChangeAllowed(player)) { return; } if (player.Team == message.Team) { return; } if (Config["SvSpamprotection"] && player.LastSetTeamTick + Server.TickSpeed * 3 > Server.Tick) { return; } if (message.Team != Team.Spectators && LockTeams || player.TeamChangeTick > Server.Tick) { return; } player.LastSetTeamTick = Server.Tick; if (GameController.CanJoinTeam(player, message.Team) && GameController.CanChangeTeam(player, message.Team)) { player.SetTeam(message.Team); } }
protected virtual void OnMsgSetTeam(BasePlayer player, GameMsg_ClSetTeam msg) { if (msg.Team < Team.SPECTATORS || msg.Team > Team.BLUE) { return; } if (World.IsPaused || player.Team == msg.Team || Config["SvSpamprotection"] && player.LastSetTeam + Server.TickSpeed * 3 > Server.Tick) { return; } if (msg.Team != Team.SPECTATORS && LockTeams) { player.LastSetTeam = Server.Tick; SendBroadcast(player.ClientId, "Teams are locked"); return; } if (player.TeamChangeTick > Server.Tick) { player.LastSetTeam = Server.Tick; var timeLeft = (player.TeamChangeTick - Server.Tick) / Server.TickSpeed; SendBroadcast(player.ClientId, $"Time to wait before changing team: {timeLeft/60}:{timeLeft%60}"); return; } if (GameController.CanJoinTeam(player.ClientId, msg.Team)) { if (!GameController.CanChangeTeam(player, msg.Team)) { return; } player.LastSetTeam = Server.Tick; player.TeamChangeTick = Server.Tick; player.SetTeam(msg.Team); GameController.CheckTeamBalance(); if (player.Team == Team.SPECTATORS || msg.Team == Team.SPECTATORS) { // vote update } } else { SendBroadcast(player.ClientId, $"Only {Players.Length - Config["SvSpectatorSlots"]}active players are allowed"); } }
protected virtual void DoTeamBalance() { if (IsTeamplay() && UnbalancedTick != -1 && Server.Tick > UnbalancedTick + Config["SvTeambalanceTime"] * Server.TickSpeed * 60) { GameContext.Console.Print(OutputLevel.DEBUG, "game", "Balancing teams"); var teamPlayers = new int[] { 0, 0 }; var teamScores = new float[] { 0, 0 }; var playersScores = new float[GameContext.Players.Length]; for (var i = 0; i < GameContext.Players.Length; i++) { if (GameContext.Players[i] == null || GameContext.Players[i].Team == Team.SPECTATORS) { continue; } teamPlayers[(int)GameContext.Players[i].Team]++; playersScores[i] = GetPlayerScore(i) * Server.TickSpeed * 60f / (Server.Tick - ScoresStartTick[i]); teamScores[(int)GameContext.Players[i].Team] += playersScores[i]; } if (Math.Abs(teamPlayers[0] - teamPlayers[1]) >= 2) { var m = teamPlayers[0] > teamPlayers[1] ? Team.RED : Team.BLUE; var numBalance = Math.Abs(teamPlayers[0] - teamPlayers[1]) / 2; do { BasePlayer p = null; var pd = teamScores[(int)m]; for (var i = 0; i < GameContext.Players.Length; i++) { if (GameContext.Players[i] == null || !CanBeMovedOnBalance(i)) { continue; } if (GameContext.Players[i].Team == m && (p == null || Math.Abs( (teamScores[(int)m ^ 1] + playersScores[i]) - (teamScores[(int)m] - playersScores[i]) ) < pd)) { p = GameContext.Players[i]; pd = Math.Abs((teamScores[(int)m ^ 1] + playersScores[i]) - (teamScores[(int)m] - playersScores[i])); } } var tmp = p.LastActionTick; p.SetTeam((Team)((int)m ^ 1)); p.LastActionTick = tmp; p.Respawn(); } while (--numBalance != 0); ForceBalanced = true; } UnbalancedTick = -1; } }