Join(): when a client queued for red, then a blue player left the team,
then a client (re)joined blue, the client queued for red was joined too
(stacking red team). Fixed by only joining queued players in Join() when
teams are currently balanced (the unbalanced cases are handled by
TeamBalance_QueuedPlayersTagIn()).
ClientKill_Now_TeamChange(): when all queued client(s) chose specific
team(s) and the last client (which skips the queue and triggers the
joins) chose autoselect from the team selection UI, it was possible they
were assigned the same team as one of the queued clients. Fixed by
deferring the autoselect to Join() when needed/possible.
TRANSMUTE(Player, this);
- if(queued_join)
+ if(queued_join
+ && TeamBalance_AreEqual(this, true)) // if a player couldn't tag in for balance, don't join them here as it would cause a stack
{
// First we must put queued player(s) in their team(s) (they chose first).
FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != this && it.wants_join,
{
if (this.killindicator_teamchange == -1)
{
- TeamBalance_JoinBestTeam(this);
+ if (this.team > 0)
+ // ensure team is valid immediately so ClientKill_Now() -> Damage() can update score without error
+ TeamBalance_JoinBestTeam(this);
+ else
+ {
+ // defer autoselect to Join(), after any queued players were joined to avoid 2 players on same team
+ // when the first player(s) chose specific teams and the last player chose autoselect (they skip the queue)
+ this.team = -1;
+ this.team_selected = -1; // don't stop at ShowTeamSelection()
+ }
}
else if (this.killindicator_teamchange == -2)
{