void CA_count_alive_players()
{
- total_players = redalive = bluealive = yellowalive = pinkalive = 0;
- FOREACH_CLIENT(IS_PLAYER(it), {
- switch(it.team)
+ total_players = 0;
+ for (int i = 1; i <= NUM_TEAMS; ++i)
+ {
+ Team_SetNumberOfAlivePlayers(Team_GetTeamFromIndex(i), 0);
+ }
+ FOREACH_CLIENT(IS_PLAYER(it) && Entity_HasValidTeam(it),
+ {
+ ++total_players;
+ if (IS_DEAD(it))
{
- case NUM_TEAM_1: ++total_players; if(!IS_DEAD(it)) ++redalive; break;
- case NUM_TEAM_2: ++total_players; if(!IS_DEAD(it)) ++bluealive; break;
- case NUM_TEAM_3: ++total_players; if(!IS_DEAD(it)) ++yellowalive; break;
- case NUM_TEAM_4: ++total_players; if(!IS_DEAD(it)) ++pinkalive; break;
+ continue;
}
+ entity team_ = Entity_GetTeam(it);
+ int num_alive = Team_GetNumberOfAlivePlayers(team_);
+ ++num_alive;
+ Team_SetNumberOfAlivePlayers(team_, num_alive);
});
- FOREACH_CLIENT(IS_REAL_CLIENT(it), {
- it.redalive_stat = redalive;
- it.bluealive_stat = bluealive;
- it.yellowalive_stat = yellowalive;
- it.pinkalive_stat = pinkalive;
+ FOREACH_CLIENT(IS_REAL_CLIENT(it),
+ {
+ STAT(REDALIVE, it) = Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(
+ 1));
+ STAT(BLUEALIVE, it) = Team_GetNumberOfAlivePlayers(
+ Team_GetTeamFromIndex(2));
+ STAT(YELLOWALIVE, it) = Team_GetNumberOfAlivePlayers(
+ Team_GetTeamFromIndex(3));
+ STAT(PINKALIVE, it) = Team_GetNumberOfAlivePlayers(
+ Team_GetTeamFromIndex(4));
});
}
-float CA_GetWinnerTeam()
+int CA_GetWinnerTeam()
{
- float winner_team = 0;
- if(redalive >= 1)
- winner_team = NUM_TEAM_1;
- if(bluealive >= 1)
+ int winner_team = 0;
+ if (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(1)) >= 1)
{
- if(winner_team) return 0;
- winner_team = NUM_TEAM_2;
+ winner_team = NUM_TEAM_1;
}
- if(yellowalive >= 1)
+ for (int i = 2; i <= NUM_TEAMS; ++i)
{
- if(winner_team) return 0;
- winner_team = NUM_TEAM_3;
+ if (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) >= 1)
+ {
+ if (winner_team != 0)
+ {
+ return 0;
+ }
+ winner_team = Team_IndexToTeam(i);
+ }
}
- if(pinkalive >= 1)
+ if (winner_team)
{
- if(winner_team) return 0;
- winner_team = NUM_TEAM_4;
- }
- if(winner_team)
return winner_team;
+ }
return -1; // no player left
}
void nades_Clear(entity player);
-#define CA_ALIVE_TEAMS() ((redalive > 0) + (bluealive > 0) + (yellowalive > 0) + (pinkalive > 0))
-#define CA_ALIVE_TEAMS_OK() (CA_ALIVE_TEAMS() == NumTeams(ca_teams))
+#define CA_ALIVE_TEAMS_OK() (Team_GetNumberOfAliveTeams() == NumTeams(ca_teams))
float CA_CheckWinner()
{
if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
}
CA_count_alive_players();
- if(CA_ALIVE_TEAMS() > 1)
+ if (Team_GetNumberOfAliveTeams() > 1)
+ {
return 0;
+ }
int winner_team = CA_GetWinnerTeam();
if(winner_team > 0)
return false;
}
int missing_teams_mask = 0;
- if(ca_teams & BIT(0))
- missing_teams_mask += (!redalive) * 1;
- if(ca_teams & BIT(1))
- missing_teams_mask += (!bluealive) * 2;
- if(ca_teams & BIT(2))
- missing_teams_mask += (!yellowalive) * 4;
- if(ca_teams & BIT(3))
- missing_teams_mask += (!pinkalive) * 8;
+ for (int i = 1; i <= NUM_TEAMS; ++i)
+ {
+ if ((ca_teams & Team_IndexToBit(i)) &&
+ (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) == 0))
+ {
+ missing_teams_mask |= Team_IndexToBit(i);
+ }
+ }
if(prev_missing_teams_mask != missing_teams_mask)
{
Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
return true;
}
-MUTATOR_HOOKFUNCTION(ca, CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
+MUTATOR_HOOKFUNCTION(ca, TeamBalance_CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
{
M_ARGV(0, float) = ca_teams;
+ return true;
}
entity ca_LastPlayerForTeam(entity this)
ca_LastPlayerForTeam_Notify(frag_target);
if (!allowed_to_spawn)
- frag_target.respawn_flags = RESPAWN_SILENT;
+ {
+ frag_target.respawn_flags = RESPAWN_SILENT;
+ // prevent unwanted sudden rejoin as spectator and movement of spectator camera
+ frag_target.respawn_time = time + 2;
+ }
+ frag_target.respawn_flags |= RESPAWN_FORCE;
if (!warmup_stage)
eliminatedPlayers.SendFlags |= 1;
if(IS_BOT_CLIENT(frag_target))
if (!IS_DEAD(player))
ca_LastPlayerForTeam_Notify(player);
- if (CS(player).killindicator_teamchange == -2) // player wants to spectate
+ if (player.killindicator_teamchange == -2) // player wants to spectate
player.caplayer = 0;
if (player.caplayer)
player.frags = FRAGS_LMS_LOSER;
GameRules_scoring_add_team(frag_attacker, SCORE, (frag_damage - excess) * autocvar_g_ca_damage2score_multiplier);
}
+MUTATOR_HOOKFUNCTION(ca, CalculateRespawnTime)
+{
+ // no respawn calculations needed, player is forced to spectate anyway
+ return true;
+}
+
MUTATOR_HOOKFUNCTION(ca, PlayerRegen)
{
// no regeneration in CA