2 float redalive, bluealive, yellowalive, pinkalive;
3 .float redalive_stat, bluealive_stat, yellowalive_stat, pinkalive_stat;
5 float allowed_to_spawn;
7 void CA_count_alive_players()
10 total_players = redalive = bluealive = yellowalive = pinkalive = 0;
12 if(e.team == COLOR_TEAM1)
15 if (e.health >= 1) ++redalive;
17 else if(e.team == COLOR_TEAM2)
20 if (e.health >= 1) ++bluealive;
22 else if(e.team == COLOR_TEAM3)
25 if (e.health >= 1) ++yellowalive;
27 else if(e.team == COLOR_TEAM4)
30 if (e.health >= 1) ++pinkalive;
33 FOR_EACH_REALCLIENT(e) {
34 e.redalive_stat = redalive;
35 e.bluealive_stat = bluealive;
36 e.yellowalive_stat = yellowalive;
37 e.pinkalive_stat = pinkalive;
41 float CA_GetWinnerTeam()
43 float winner_team = 0;
45 winner_team = COLOR_TEAM1;
48 if(winner_team) return 0;
49 winner_team = COLOR_TEAM2;
53 if(winner_team) return 0;
54 winner_team = COLOR_TEAM3;
58 if(winner_team) return 0;
59 winner_team = COLOR_TEAM4;
63 return -1; // no player left
66 #define CA_ALIVE_TEAMS() ((redalive > 0) + (bluealive > 0) + (yellowalive > 0) + (pinkalive > 0))
67 #define CA_ALIVE_TEAMS_OK() (CA_ALIVE_TEAMS() == ca_teams)
68 float CA_CheckWinner()
71 if(round_handler_GetTimeLeft() <= 0)
73 FOR_EACH_REALCLIENT(e)
74 centerprint(e, "Round over, there's no winner");
75 bprint("Round over, there's no winner.\n");
76 allowed_to_spawn = FALSE;
77 round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit);
81 CA_count_alive_players();
82 if(CA_ALIVE_TEAMS() > 1)
87 winner_team = CA_GetWinnerTeam();
90 teamname = ColoredTeamName(winner_team);
91 FOR_EACH_REALCLIENT(e)
92 centerprint(e, strcat(teamname, " wins the round"));
93 bprint(teamname, " wins the round.\n");
94 TeamScore_AddToTeam(winner_team, ST_SCORE, +1);
96 else if(winner_team == -1)
98 FOR_EACH_REALCLIENT(e)
99 centerprint(e, "Round tied");
100 bprint("Round tied.\n");
103 allowed_to_spawn = FALSE;
104 round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit);
111 allowed_to_spawn = TRUE;
113 allowed_to_spawn = FALSE;
116 float prev_total_players;
117 float CA_CheckTeams()
120 allowed_to_spawn = TRUE;
121 CA_count_alive_players();
122 if(CA_ALIVE_TEAMS_OK())
124 if(prev_total_players != -1)
126 FOR_EACH_REALCLIENT(e)
127 Send_CSQC_Centerprint_Generic_Expire(e, CPID_WAITING_PLAYERS);
129 prev_total_players = -1;
132 if(prev_total_players != total_players)
134 string teams_missing = "";
135 if(!redalive) teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM1), ", ");
136 if(!bluealive) teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM2), ", ");
138 if(!yellowalive) teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM3), ", ");
140 if(!pinkalive) teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM4), ", ");
141 teams_missing = substring(teams_missing, 0, strlen(teams_missing)-2);
143 FOR_EACH_REALCLIENT(e)
144 Send_CSQC_Centerprint_Generic(e, CPID_WAITING_PLAYERS, strcat("Waiting for players to join...\n\nNeed active players for: ", teams_missing), -1, 0);
145 prev_total_players = total_players;
150 MUTATOR_HOOKFUNCTION(ca_PlayerSpawn)
156 MUTATOR_HOOKFUNCTION(ca_PutClientInServer)
158 if(!allowed_to_spawn)
160 self.classname = "observer";
164 if(clienttype(self) == CLIENTTYPE_REAL)
165 sprint(self, "You will join the game in the next round.\n");
171 MUTATOR_HOOKFUNCTION(ca_reset_map_players)
173 FOR_EACH_CLIENT(self)
177 self.classname = "player";
185 MUTATOR_HOOKFUNCTION(ca_ClientConnect)
187 self.classname = "observer";
191 MUTATOR_HOOKFUNCTION(ca_reset_map_global)
193 allowed_to_spawn = TRUE;
197 MUTATOR_HOOKFUNCTION(ca_GetTeamCount)
199 ca_teams = autocvar_g_ca_teams_override;
201 ca_teams = autocvar_g_ca_teams;
202 ca_teams = bound(2, ca_teams, 4);
203 ret_float = ca_teams;
207 MUTATOR_HOOKFUNCTION(ca_PlayerPreThink)
209 if(!allowed_to_spawn)
210 self.stat_respawn_time = 0;
214 MUTATOR_HOOKFUNCTION(ca_ForbidPlayerScore_Clear)
219 MUTATOR_HOOKFUNCTION(ca_MakePlayerObserver)
221 if(self.killindicator_teamchange == -2)
224 self.frags = FRAGS_LMS_LOSER;
228 MUTATOR_HOOKFUNCTION(ca_ForbidThrowCurrentWeapon)
233 MUTATOR_HOOKFUNCTION(ca_GiveFragsForKill)
235 frag_score = 0; // score will be given to the winner team when the round ends
241 allowed_to_spawn = TRUE;
243 round_handler_Spawn(CA_CheckTeams, CA_CheckWinner, CA_RoundStart);
244 round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit);
246 addstat(STAT_REDALIVE, AS_INT, redalive_stat);
247 addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat);
248 addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat);
249 addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat);
252 MUTATOR_DEFINITION(gamemode_ca)
254 MUTATOR_HOOK(PlayerSpawn, ca_PlayerSpawn, CBC_ORDER_ANY);
255 MUTATOR_HOOK(PutClientInServer, ca_PutClientInServer, CBC_ORDER_ANY);
256 MUTATOR_HOOK(MakePlayerObserver, ca_MakePlayerObserver, CBC_ORDER_ANY);
257 MUTATOR_HOOK(ClientConnect, ca_ClientConnect, CBC_ORDER_ANY);
258 MUTATOR_HOOK(reset_map_global, ca_reset_map_global, CBC_ORDER_ANY);
259 MUTATOR_HOOK(reset_map_players, ca_reset_map_players, CBC_ORDER_ANY);
260 MUTATOR_HOOK(GetTeamCount, ca_GetTeamCount, CBC_ORDER_EXCLUSIVE);
261 MUTATOR_HOOK(PlayerPreThink, ca_PlayerPreThink, CBC_ORDER_ANY);
262 MUTATOR_HOOK(ForbidPlayerScore_Clear, ca_ForbidPlayerScore_Clear, CBC_ORDER_ANY);
263 MUTATOR_HOOK(ForbidThrowCurrentWeapon, ca_ForbidThrowCurrentWeapon, CBC_ORDER_ANY);
264 MUTATOR_HOOK(GiveFragsForKill, ca_GiveFragsForKill, CBC_ORDER_FIRST);
268 if(time > 1) // game loads at time 1
269 error("This is a game type and it cannot be added at runtime.");
275 print("This is a game type and it cannot be removed at runtime.");