]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Full support for 3 and 4 teams in CA and Freezetag
authorterencehill <piuntn@gmail.com>
Sat, 22 Dec 2012 08:51:02 +0000 (09:51 +0100)
committerterencehill <piuntn@gmail.com>
Sat, 22 Dec 2012 08:51:02 +0000 (09:51 +0100)
18 files changed:
_hud_descriptions.cfg
gamemodes.cfg
gfx/hud/default/player_pink.tga [new file with mode: 0644]
gfx/hud/default/player_yellow.tga [new file with mode: 0644]
hud_luminos.cfg
hud_luminos_minimal.cfg
hud_luminos_minimal_xhair.cfg
hud_luminos_old.cfg
hud_nexuiz.cfg
qcsrc/client/autocvars.qh
qcsrc/client/hud.qc
qcsrc/client/hud_config.qc
qcsrc/server/arena.qc
qcsrc/server/autocvars.qh
qcsrc/server/defs.qh
qcsrc/server/g_world.qc
qcsrc/server/mutators/gamemode_freezetag.qc
qcsrc/server/teamplay.qc

index cb95f968132ba7145549310b491ec98885459a7a..b2bfcf6a0b2bb0b5084df2e4f67f15928edfc691 100644 (file)
@@ -194,7 +194,9 @@ seta hud_panel_modicons_bg_color_team "" "override panel color with team color i
 seta hud_panel_modicons_bg_alpha "" "if set to something else than \"\" = override default panel background alpha"
 seta hud_panel_modicons_bg_border "" "if set to something else than \"\" = override default size of border around the background"
 seta hud_panel_modicons_bg_padding "" "if set to something else than \"\" = override default padding of contents from border"
 seta hud_panel_modicons_bg_alpha "" "if set to something else than \"\" = override default panel background alpha"
 seta hud_panel_modicons_bg_border "" "if set to something else than \"\" = override default size of border around the background"
 seta hud_panel_modicons_bg_padding "" "if set to something else than \"\" = override default padding of contents from border"
+seta hud_panel_modicons_ca_layout "" "2 possible layouts: 0) number of alive players; 1) icons and number of alive players"
 seta hud_panel_modicons_dom_layout "" "3 possible layouts: 0) only icons; 1) icons and percentage of average pps (points per second); 2) icons and average pps"
 seta hud_panel_modicons_dom_layout "" "3 possible layouts: 0) only icons; 1) icons and percentage of average pps (points per second); 2) icons and average pps"
+seta hud_panel_modicons_freezetag_layout "" "2 possible layouts: 0) number of alive players; 1) icons and number of alive players"
 
 seta hud_panel_pressedkeys "" "enable/disable this panel, 1 = show only when spectating other players, 2 = show always"
 seta hud_panel_pressedkeys_pos "" "position of this base of the panel"
 
 seta hud_panel_pressedkeys "" "enable/disable this panel, 1 = show only when spectating other players, 2 = show always"
 seta hud_panel_pressedkeys_pos "" "position of this base of the panel"
index 6cff7e5a42666ab32954c8ec8d5abb757b1a09f6..515b8ce6c8aa7e74a62446e266569ceffa540483 100644 (file)
@@ -168,6 +168,9 @@ set g_ca_spectate_enemies 0 "Allow spectating enemy player by dead player during
 set g_ca_warmup 10 "how long the players will have time to run around the map before the round starts"
 set g_ca_damage2score_multiplier 0.01
 set g_ca_round_timelimit 180
 set g_ca_warmup 10 "how long the players will have time to run around the map before the round starts"
 set g_ca_damage2score_multiplier 0.01
 set g_ca_round_timelimit 180
+seta g_ca_teams_override 0
+set g_ca_teams 0
+
 
 
 // ==================
 
 
 // ==================
@@ -283,6 +286,8 @@ seta g_freezetag_revive_speed 0.4 "Speed for reviving a frozen teammate"
 seta g_freezetag_revive_clearspeed 1.6 "Speed at which reviving progress gets lost when out of range"
 seta g_freezetag_revive_extra_size 100 "Distance in qu that you can stand from a frozen teammate to keep reviving him"
 seta g_freezetag_frozen_force 0.6 "How much to multiply the force on a frozen player with"
 seta g_freezetag_revive_clearspeed 1.6 "Speed at which reviving progress gets lost when out of range"
 seta g_freezetag_revive_extra_size 100 "Distance in qu that you can stand from a frozen teammate to keep reviving him"
 seta g_freezetag_frozen_force 0.6 "How much to multiply the force on a frozen player with"
+seta g_freezetag_teams_override 0
+set g_freezetag_teams 0
 
 
 // ==========
 
 
 // ==========
diff --git a/gfx/hud/default/player_pink.tga b/gfx/hud/default/player_pink.tga
new file mode 100644 (file)
index 0000000..89a7659
Binary files /dev/null and b/gfx/hud/default/player_pink.tga differ
diff --git a/gfx/hud/default/player_yellow.tga b/gfx/hud/default/player_yellow.tga
new file mode 100644 (file)
index 0000000..8717d8f
Binary files /dev/null and b/gfx/hud/default/player_yellow.tga differ
index 6472a257963fad8c9526546031d3d6e7c716779f..c5be520950ab917851ac819043da4375efda7c54 100644 (file)
@@ -192,7 +192,9 @@ seta hud_panel_modicons_bg_color_team ""
 seta hud_panel_modicons_bg_alpha ""
 seta hud_panel_modicons_bg_border ""
 seta hud_panel_modicons_bg_padding "0"
 seta hud_panel_modicons_bg_alpha ""
 seta hud_panel_modicons_bg_border ""
 seta hud_panel_modicons_bg_padding "0"
+seta hud_panel_modicons_ca_layout "1"
 seta hud_panel_modicons_dom_layout "1"
 seta hud_panel_modicons_dom_layout "1"
+seta hud_panel_modicons_freezetag_layout "1"
 
 seta hud_panel_pressedkeys 1
 seta hud_panel_pressedkeys_pos "0.450000 0.720000"
 
 seta hud_panel_pressedkeys 1
 seta hud_panel_pressedkeys_pos "0.450000 0.720000"
index bb7e0662e32e3bcbce1060385a3f0d42a6961549..843ff14a981cb7c58af7b309919ec78dbee28070 100644 (file)
@@ -192,7 +192,9 @@ seta hud_panel_modicons_bg_color_team ""
 seta hud_panel_modicons_bg_alpha ""
 seta hud_panel_modicons_bg_border ""
 seta hud_panel_modicons_bg_padding ""
 seta hud_panel_modicons_bg_alpha ""
 seta hud_panel_modicons_bg_border ""
 seta hud_panel_modicons_bg_padding ""
+seta hud_panel_modicons_ca_layout "1"
 seta hud_panel_modicons_dom_layout "1"
 seta hud_panel_modicons_dom_layout "1"
+seta hud_panel_modicons_freezetag_layout "1"
 
 seta hud_panel_pressedkeys 1
 seta hud_panel_pressedkeys_pos "0.450000 0.650000"
 
 seta hud_panel_pressedkeys 1
 seta hud_panel_pressedkeys_pos "0.450000 0.650000"
index e0921ad35337d272f8e0c91a0032864349981cac..835c7d2c1bc4e7a8b0131e362d046ad11a2ef168 100644 (file)
@@ -192,7 +192,9 @@ seta hud_panel_modicons_bg_color_team ""
 seta hud_panel_modicons_bg_alpha ""
 seta hud_panel_modicons_bg_border ""
 seta hud_panel_modicons_bg_padding ""
 seta hud_panel_modicons_bg_alpha ""
 seta hud_panel_modicons_bg_border ""
 seta hud_panel_modicons_bg_padding ""
+seta hud_panel_modicons_ca_layout "1"
 seta hud_panel_modicons_dom_layout "1"
 seta hud_panel_modicons_dom_layout "1"
+seta hud_panel_modicons_freezetag_layout "1"
 
 seta hud_panel_pressedkeys 1
 seta hud_panel_pressedkeys_pos "0.450000 0.690000"
 
 seta hud_panel_pressedkeys 1
 seta hud_panel_pressedkeys_pos "0.450000 0.690000"
index 119f7b18f6f8cd3f163e7e6ac172db53ed4516ad..20673e3f5a6d1c817e76bfbee5339082d0440160 100644 (file)
@@ -192,7 +192,9 @@ seta hud_panel_modicons_bg_color_team ""
 seta hud_panel_modicons_bg_alpha ""
 seta hud_panel_modicons_bg_border ""
 seta hud_panel_modicons_bg_padding ""
 seta hud_panel_modicons_bg_alpha ""
 seta hud_panel_modicons_bg_border ""
 seta hud_panel_modicons_bg_padding ""
+seta hud_panel_modicons_ca_layout "1"
 seta hud_panel_modicons_dom_layout "1"
 seta hud_panel_modicons_dom_layout "1"
+seta hud_panel_modicons_freezetag_layout "1"
 
 seta hud_panel_pressedkeys 1
 seta hud_panel_pressedkeys_pos "0.410000 0.710000"
 
 seta hud_panel_pressedkeys 1
 seta hud_panel_pressedkeys_pos "0.410000 0.710000"
index 3cf0feb753e5e08b748ce408a03f42affc78393d..4980795618d8fa097e5d70730f75b3d7aefc25c2 100644 (file)
@@ -192,7 +192,9 @@ seta hud_panel_modicons_bg_color_team ""
 seta hud_panel_modicons_bg_alpha ""
 seta hud_panel_modicons_bg_border ""
 seta hud_panel_modicons_bg_padding ""
 seta hud_panel_modicons_bg_alpha ""
 seta hud_panel_modicons_bg_border ""
 seta hud_panel_modicons_bg_padding ""
+seta hud_panel_modicons_ca_layout "1"
 seta hud_panel_modicons_dom_layout "1"
 seta hud_panel_modicons_dom_layout "1"
+seta hud_panel_modicons_freezetag_layout "1"
 
 seta hud_panel_pressedkeys 1
 seta hud_panel_pressedkeys_pos "0.440000 0.760000"
 
 seta hud_panel_pressedkeys 1
 seta hud_panel_pressedkeys_pos "0.440000 0.760000"
index ed56f718381cc0e2ecfe61c29d8e3ed2a59a261c..d91288b6d0198a7335bf1c979fca5aa88a02ba95 100644 (file)
@@ -246,7 +246,9 @@ float autocvar_hud_panel_healtharmor_text;
 float autocvar_hud_panel_infomessages;
 float autocvar_hud_panel_infomessages_flip;
 float autocvar_hud_panel_modicons;
 float autocvar_hud_panel_infomessages;
 float autocvar_hud_panel_infomessages_flip;
 float autocvar_hud_panel_modicons;
+float autocvar_hud_panel_modicons_ca_layout;
 float autocvar_hud_panel_modicons_dom_layout;
 float autocvar_hud_panel_modicons_dom_layout;
+float autocvar_hud_panel_modicons_freezetag_layout;
 float autocvar_hud_panel_notify;
 float autocvar_hud_panel_notify_fadetime;
 float autocvar_hud_panel_notify_flip;
 float autocvar_hud_panel_notify;
 float autocvar_hud_panel_notify_fadetime;
 float autocvar_hud_panel_notify_flip;
index 13f37b70eb9b594cc8c68dcfde1f42936385ea41..f2b9901453861491a312c6f4217bace1960c9c1d 100644 (file)
@@ -3281,32 +3281,93 @@ void HUD_VoteWindow(void)
 
 float mod_active; // is there any active mod icon?
 
 
 float mod_active; // is there any active mod icon?
 
-// Clan Arena HUD modicons
-void HUD_Mod_CA(vector pos, vector mySize)
+void DrawCAItem(vector myPos, vector mySize, float aspect_ratio, float layout, float i)
 {
 {
-       mod_active = 1; // CA should never hide the mod icons panel
-       float redalive, bluealive;
-       redalive = getstati(STAT_REDALIVE);
-       bluealive = getstati(STAT_BLUEALIVE);
+       float stat;
+       string pic;
+       vector color;
+       switch(i)
+       {
+               case 0:
+                       stat = getstati(STAT_REDALIVE);
+                       pic = "player_red.tga";
+                       color = '1 0 0';
+                       break;
+               case 1:
+                       stat = getstati(STAT_BLUEALIVE);
+                       pic = "player_blue.tga";
+                       color = '0 0 1';
+                       break;
+               case 2:
+                       stat = getstati(STAT_YELLOWALIVE);
+                       pic = "player_yellow.tga";
+                       color = '1 1 0';
+                       break;
+               case 3:
+                       stat = getstati(STAT_PINKALIVE);
+                       pic = "player_pink.tga";
+                       color = '1 0 1';
+       }
 
 
-       vector redpos, bluepos;
-       if(mySize_x > mySize_y)
+       if(mySize_x/mySize_y > aspect_ratio)
        {
        {
-               redpos = pos;
-               bluepos = pos + eY * 0.5 * mySize_y;
-               drawpic_aspect_skin(redpos, "player_red.tga", 0.5 * mySize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
-               drawstring_aspect(redpos + eX * 0.5 * mySize_x, ftos(redalive), 0.5 * mySize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
-               drawpic_aspect_skin(bluepos, "player_blue.tga", 0.5 * mySize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
-               drawstring_aspect(bluepos + eX * 0.5 * mySize_x, ftos(bluealive), 0.5 * mySize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+               i = aspect_ratio * mySize_y;
+               myPos_x = myPos_x + (mySize_x - i) / 2;
+               mySize_x = i;
        }
        else
        {
        }
        else
        {
-               redpos = pos;
-               bluepos = pos + eY * 0.5 * mySize_y;
-               drawpic_aspect_skin(redpos, "player_red.tga", eX * mySize_x + eY * 0.3 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
-               drawstring_aspect(redpos + eY * 0.3 * mySize_y, ftos(redalive), eX * mySize_x + eY * 0.2 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
-               drawpic_aspect_skin(bluepos, "player_blue.tga", eX * mySize_x + eY * 0.3 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
-               drawstring_aspect(bluepos + eY * 0.3 * mySize_y, ftos(bluealive), eX * mySize_x + eY * 0.2 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+               i = 1/aspect_ratio * mySize_x;
+               myPos_y = myPos_y + (mySize_y - i) / 2;
+               mySize_y = i;
+       }
+
+       if(layout)
+       {
+               drawpic_aspect_skin(myPos, pic, eX * 0.7 * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+               drawstring_aspect(myPos + eX * 0.7 * mySize_x, ftos(stat), eX * 0.3 * mySize_x + eY * mySize_y, color, panel_fg_alpha, DRAWFLAG_NORMAL);
+       }
+       else
+               drawstring_aspect(myPos, ftos(stat), mySize, color, panel_fg_alpha, DRAWFLAG_NORMAL);
+}
+
+// Clan Arena and Freeze Tag HUD modicons
+void HUD_Mod_CA(vector myPos, vector mySize)
+{
+       mod_active = 1; // required in each mod function that always shows something
+       entity tm;
+       float teams_count;
+       for(tm = teams.sort_next; tm; tm = tm.sort_next)
+               if(tm.team != COLOR_SPECTATOR)
+                       ++teams_count;
+
+       float layout;
+       if(gametype == MAPINFO_TYPE_CA)
+               layout = autocvar_hud_panel_modicons_ca_layout;
+       else //if(gametype == MAPINFO_TYPE_FREEZETAG)
+               layout = autocvar_hud_panel_modicons_freezetag_layout;
+       float rows, columns, aspect_ratio;
+       rows = mySize_y/mySize_x;
+       aspect_ratio = (layout) ? 2 : 1;
+       rows = bound(1, floor((sqrt((4 * aspect_ratio * teams_count + rows) * rows) + rows + 0.5) / 2), teams_count);
+       columns = ceil(teams_count/rows);
+
+       int i;
+       float row, column;
+       for(i=0; i<teams_count; ++i)
+       {
+               vector pos, itemSize;
+               pos = myPos + eX * column * mySize_x*(1/columns) + eY * row * mySize_y*(1/rows);
+               itemSize = eX * mySize_x*(1/columns) + eY * mySize_y*(1/rows);
+
+               DrawCAItem(pos, itemSize, aspect_ratio, layout, i);
+
+               ++row;
+               if(row >= rows)
+               {
+                       row = 0;
+                       ++column;
+               }
        }
 }
 
        }
 }
 
index 75c1d2c0e4328b362ca38598fc4c4788c323bfa7..23e9f8e4b188963a0c5f96fadafa3a97778ffc9f 100644 (file)
@@ -135,7 +135,9 @@ void HUD_Panel_ExportCfg(string cfgname)
                                        HUD_Write_PanelCvar_q("_alreadyvoted_alpha");
                                        break;
                                case HUD_PANEL_MODICONS:
                                        HUD_Write_PanelCvar_q("_alreadyvoted_alpha");
                                        break;
                                case HUD_PANEL_MODICONS:
+                                       HUD_Write_PanelCvar_q("_ca_layout");
                                        HUD_Write_PanelCvar_q("_dom_layout");
                                        HUD_Write_PanelCvar_q("_dom_layout");
+                                       HUD_Write_PanelCvar_q("_freezetag_layout");
                                        break;
                                case HUD_PANEL_PRESSEDKEYS:
                                        HUD_Write_PanelCvar_q("_attack");
                                        break;
                                case HUD_PANEL_PRESSEDKEYS:
                                        HUD_Write_PanelCvar_q("_attack");
index 14caab85b81cdb98b6b5231380efc2dcd1aaa5b7..4f986d1384a5db6ea7375b6ece6d850893bcd553 100644 (file)
@@ -19,6 +19,8 @@ float redalive, bluealive, yellowalive, pinkalive;
 .float redalive_stat, bluealive_stat, yellowalive_stat, pinkalive_stat;
 float red_players, blue_players, yellow_players, pink_players;
 float total_players;
 .float redalive_stat, bluealive_stat, yellowalive_stat, pinkalive_stat;
 float red_players, blue_players, yellow_players, pink_players;
 float total_players;
+#define CA_TEAMS() ((red_players > 0) + (blue_players > 0) + (yellow_players > 0) + (pink_players > 0))
+#define CA_TEAMS_OK() (CA_TEAMS() == ca_teams)
 
 /**
  * Resets the state of all clients, items, flags, runes, keys, weapons, waypoints, ... of the map.
 
 /**
  * Resets the state of all clients, items, flags, runes, keys, weapons, waypoints, ... of the map.
@@ -224,7 +226,7 @@ void Arena_Warmup()
                        allowed_to_spawn = 1;
                else if (warmup == 0) //first warmup or warmup cleared
                {
                        allowed_to_spawn = 1;
                else if (warmup == 0) //first warmup or warmup cleared
                {
-                       if (red_players && blue_players)
+                       if(CA_TEAMS_OK())
                                reset_map(TRUE);
                        else if(f != roundStartTime_prev)
                        {
                                reset_map(TRUE);
                        else if(f != roundStartTime_prev)
                        {
@@ -251,7 +253,7 @@ void Arena_Warmup()
                if(f != roundStartTime_prev) {
                        roundStartTime_prev = f;
 
                if(f != roundStartTime_prev) {
                        roundStartTime_prev = f;
 
-                       if(g_ca && !(red_players && blue_players)) {
+                       if(g_ca && !CA_TEAMS_OK()) {
                                warmup = 0;
                                return;
                        }
                                warmup = 0;
                                return;
                        }
@@ -281,7 +283,7 @@ void Arena_Warmup()
        {
                roundStartTime_prev = f;
                if(g_ca) {
        {
                roundStartTime_prev = f;
                if(g_ca) {
-                       if(red_players && blue_players)
+                       if(CA_TEAMS_OK())
                                allowed_to_spawn = 0;
                        else
                        {
                                allowed_to_spawn = 0;
                        else
                        {
@@ -343,13 +345,44 @@ void count_alive_players()
                        redalive += 1;
                else if (self.team == COLOR_TEAM2 && self.health >= 1)
                        bluealive += 1;
                        redalive += 1;
                else if (self.team == COLOR_TEAM2 && self.health >= 1)
                        bluealive += 1;
+               else if (self.team == COLOR_TEAM3 && self.health >= 1)
+                       yellowalive += 1;
+               else if (self.team == COLOR_TEAM4 && self.health >= 1)
+                       pinkalive += 1;
        }
        FOR_EACH_REALCLIENT(self) {
                self.redalive_stat = redalive;
                self.bluealive_stat = bluealive;
        }
        FOR_EACH_REALCLIENT(self) {
                self.redalive_stat = redalive;
                self.bluealive_stat = bluealive;
+               self.yellowalive_stat = yellowalive;
+               self.pinkalive_stat = pinkalive;
        }
 }
 
        }
 }
 
+float CA_GetWinnerTeam()
+{
+       float winner_team;
+       if(redalive >= 1)
+               winner_team = COLOR_TEAM1;
+       if(bluealive >= 1)
+       {
+               if(winner_team) return 0;
+               winner_team = COLOR_TEAM2;
+       }
+       if(yellowalive >= 1)
+       {
+               if(winner_team) return 0;
+               winner_team = COLOR_TEAM3;
+       }
+       if(pinkalive >= 1)
+       {
+               if(winner_team) return 0;
+               winner_team = COLOR_TEAM4;
+       }
+       if(winner_team)
+               return winner_team;
+       return -1; // no player left
+}
+
 /**
  * This function finds out whether an arena round is over 1 player is left.
  * It determines the last player who's still alive and saves it's entity reference
 /**
  * This function finds out whether an arena round is over 1 player is left.
  * It determines the last player who's still alive and saves it's entity reference
@@ -363,22 +396,18 @@ void Spawnqueue_Check()
                return;
 
        if(g_ca) {
                return;
 
        if(g_ca) {
+               float winner_team;
                if(allowed_to_spawn) // round is not started yet
                        return;
                if(!next_round) {
                if(allowed_to_spawn) // round is not started yet
                        return;
                if(!next_round) {
-                       if(!(redalive && bluealive)) {
-                               // every player of (at least) one team is dead, round ends here
-                               if(redalive) {
-                                       play2all("ctf/red_capture.wav");
-                                       FOR_EACH_CLIENT(self) centerprint(self, "^1RED ^7team wins the round");
-                                       TeamScore_AddToTeam(COLOR_TEAM1, ST_SCORE, +1);
+                       winner_team = CA_GetWinnerTeam();
+                       if(winner_team) {
+                               if(winner_team > 0) {
+                                       FOR_EACH_CLIENT(self)
+                                               centerprint(self, strcat(ColoredTeamName(winner_team), " wins the round"));
+                                       TeamScore_AddToTeam(winner_team, ST_SCORE, +1);
                                }
                                }
-                               else if(bluealive) {
-                                       play2all("ctf/blue_capture.wav");
-                                       FOR_EACH_CLIENT(self) centerprint(self, "^4BLUE ^7team wins the round");
-                                       TeamScore_AddToTeam(COLOR_TEAM2, ST_SCORE, +1);
-                               }
-                               else
+                               else //if(winner_team  == -1) // no player left
                                        FOR_EACH_CLIENT(self) centerprint(self, "^7Round tied");
                                next_round = -1;
                        }
                                        FOR_EACH_CLIENT(self) centerprint(self, "^7Round tied");
                                next_round = -1;
                        }
@@ -389,7 +418,7 @@ void Spawnqueue_Check()
                }
                else if(next_round == -1) {
                        // wait for killed players to be put as spectators
                }
                else if(next_round == -1) {
                        // wait for killed players to be put as spectators
-                       if(!(red_players && blue_players))
+                       if(!CA_TEAMS_OK())
                                next_round = time + 5;
                }
                else if((next_round > 0 && next_round < time))
                                next_round = time + 5;
                }
                else if((next_round > 0 && next_round < time))
index ae57831a6d8aa94740917b253cf31191a2aa7990..bbae1e234df093a51a91820b8adebdfdc9ac97ff 100644 (file)
@@ -743,6 +743,8 @@ float autocvar_g_ca_point_leadlimit;
 float autocvar_g_ca_point_limit;
 float autocvar_g_ca_round_timelimit;
 float autocvar_g_ca_spectate_enemies;
 float autocvar_g_ca_point_limit;
 float autocvar_g_ca_round_timelimit;
 float autocvar_g_ca_spectate_enemies;
+float autocvar_g_ca_teams;
+float autocvar_g_ca_teams_override;
 float autocvar_g_ca_warmup;
 float autocvar_g_campaign;
 #define autocvar_g_campaign_forceteam cvar("g_campaign_forceteam")
 float autocvar_g_ca_warmup;
 float autocvar_g_campaign;
 #define autocvar_g_campaign_forceteam cvar("g_campaign_forceteam")
@@ -854,6 +856,8 @@ float autocvar_g_freezetag_point_limit;
 float autocvar_g_freezetag_revive_extra_size;
 float autocvar_g_freezetag_revive_speed;
 float autocvar_g_freezetag_revive_clearspeed;
 float autocvar_g_freezetag_revive_extra_size;
 float autocvar_g_freezetag_revive_speed;
 float autocvar_g_freezetag_revive_clearspeed;
+float autocvar_g_freezetag_teams;
+float autocvar_g_freezetag_teams_override;
 float autocvar_g_freezetag_warmup;
 #define autocvar_g_friendlyfire cvar("g_friendlyfire")
 #define autocvar_g_friendlyfire_virtual cvar("g_friendlyfire_virtual")
 float autocvar_g_freezetag_warmup;
 #define autocvar_g_friendlyfire cvar("g_friendlyfire")
 #define autocvar_g_friendlyfire_virtual cvar("g_friendlyfire_virtual")
index c57efb54bcf96dbb4c9cb33d1debd2f6cf8448fe..0b3d1e7529bc568c76079693febe661f76897056 100644 (file)
@@ -58,6 +58,8 @@ float team1_score, team2_score, team3_score, team4_score;
 
 float maxclients;
 
 
 float maxclients;
 
+float ca_teams;
+
 // Fields
 
 .void(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) event_damage;
 // Fields
 
 .void(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) event_damage;
index 5ab72ce4efd20776ceacc1d8d2064ade5b14121b..eed0a7914b688c0123264f59d9cba8d50d275c76 100644 (file)
@@ -806,12 +806,6 @@ void spawnfunc_worldspawn (void)
 
        addstat(STAT_HAGAR_LOAD, AS_INT, hagar_load);
 
 
        addstat(STAT_HAGAR_LOAD, AS_INT, hagar_load);
 
-       if(g_ca)
-       {
-               addstat(STAT_REDALIVE, AS_INT, redalive_stat);
-               addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat);
-       }
-
        // g_movementspeed hack
        addstat(STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW, AS_FLOAT, stat_sv_airspeedlimit_nonqw);
        addstat(STAT_MOVEVARS_MAXSPEED, AS_FLOAT, stat_sv_maxspeed);
        // g_movementspeed hack
        addstat(STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW, AS_FLOAT, stat_sv_airspeedlimit_nonqw);
        addstat(STAT_MOVEVARS_MAXSPEED, AS_FLOAT, stat_sv_maxspeed);
index ca06458b0b562bbd7ae390e027af7a5b6a439736..4e7fbd1d7daec5a7104280499a002ac1b9ca3236 100644 (file)
@@ -1,3 +1,4 @@
+float freezetag_teams;
 float freezetag_CheckTeams();
 float freezetag_CheckWinner();
 void freezetag_Initialize()
 float freezetag_CheckTeams();
 float freezetag_CheckWinner();
 void freezetag_Initialize()
@@ -49,24 +50,14 @@ void freezetag_count_alive_players()
                e.pinkalive_stat = pinkalive;
        }
 }
                e.pinkalive_stat = pinkalive;
        }
 }
-
-float freezetag_TeamsCanPlay()
-{
-       if((redalive >= 1 && bluealive >= 1)
-               || (redalive >= 1 && yellowalive >= 1)
-               || (redalive >= 1 && pinkalive >= 1)
-               || (bluealive >= 1 && yellowalive >= 1)
-               || (bluealive >= 1 && pinkalive >= 1)
-               || (yellowalive >= 1 && pinkalive >= 1))
-               return 1; // we still have active players on two or more teams, nobody won yet
-       return 0;
-}
+#define FREEZETAG_ALIVE_TEAMS() ((redalive > 0) + (bluealive > 0) + (yellowalive > 0) + (pinkalive > 0))
+#define FREEZETAG_ALIVE_TEAMS_OK() (FREEZETAG_ALIVE_TEAMS() == freezetag_teams)
 
 float prev_total_players;
 float freezetag_CheckTeams()
 {
        entity e;
 
 float prev_total_players;
 float freezetag_CheckTeams()
 {
        entity e;
-       if(freezetag_TeamsCanPlay())
+       if(FREEZETAG_ALIVE_TEAMS_OK())
        {
                if(prev_total_players != -1)
                {
        {
                if(prev_total_players != -1)
                {
@@ -81,6 +72,10 @@ float freezetag_CheckTeams()
                string teams_missing;
                if(!redalive)   teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM1), ", ");
                if(!bluealive)  teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM2), ", ");
                string teams_missing;
                if(!redalive)   teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM1), ", ");
                if(!bluealive)  teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM2), ", ");
+               if(freezetag_teams >= 3)
+               if(!yellowalive)        teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM3), ", ");
+               if(freezetag_teams == 4)
+               if(!pinkalive)  teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM4), ", ");
                teams_missing = substring(teams_missing, 0, strlen(teams_missing)-2);
 
                FOR_EACH_REALCLIENT(e)
                teams_missing = substring(teams_missing, 0, strlen(teams_missing)-2);
 
                FOR_EACH_REALCLIENT(e)
@@ -89,31 +84,54 @@ float freezetag_CheckTeams()
        }
        return 0;
 }
        }
        return 0;
 }
+
+float freezetag_getWinnerTeam()
+{
+       float winner_team;
+       if(redalive >= 1)
+               winner_team = COLOR_TEAM1;
+       if(bluealive >= 1)
+       {
+               if(winner_team) return 0;
+               winner_team = COLOR_TEAM2;
+       }
+       if(yellowalive >= 1)
+       {
+               if(winner_team) return 0;
+               winner_team = COLOR_TEAM3;
+       }
+       if(pinkalive >= 1)
+       {
+               if(winner_team) return 0;
+               winner_team = COLOR_TEAM4;
+       }
+       if(winner_team)
+               return winner_team;
+       return -1; // no player left
+}
+
 float freezetag_CheckWinner()
 {
 float freezetag_CheckWinner()
 {
-       if(freezetag_TeamsCanPlay())
+       if(FREEZETAG_ALIVE_TEAMS() > 1)
                return 0;
 
                return 0;
 
-       entity e, winner;
+       entity e;
+       float winner_team;
        string teamname;
        string teamname;
-       winner = world;
-
-       FOR_EACH_PLAYER(e)
-       {
-               if(e.freezetag_frozen == 0 && e.health >= 1) // here's one player from the winning team... good
-               {
-                       winner = e;
-                       break; // break, we found the winner
-               }
-       }
-
-       if(winner != world) // just in case a winner wasn't found
+       winner_team = freezetag_getWinnerTeam();
+       if(winner_team > 0)
        {
        {
-               teamname = ColoredTeamName(winner.team);
+               teamname = ColoredTeamName(winner_team);
                FOR_EACH_REALCLIENT(e)
                        centerprint(e, strcat(teamname, "^5 wins the round, all other teams were frozen."));
                bprint(teamname, "^5 wins the round since all the other teams were frozen.\n");
                FOR_EACH_REALCLIENT(e)
                        centerprint(e, strcat(teamname, "^5 wins the round, all other teams were frozen."));
                bprint(teamname, "^5 wins the round since all the other teams were frozen.\n");
-               TeamScore_AddToTeam(winner.team, ST_SCORE, +1);
+               TeamScore_AddToTeam(winner_team, ST_SCORE, +1);
+       }
+       else if(winner_team == -1)
+       {
+               FOR_EACH_REALCLIENT(e)
+                       centerprint(e, "^5Round tied! All teams were frozen.");
+               bprint("^5Round tied! All teams were frozen.\n");
        }
 
        return 1;
        }
 
        return 1;
@@ -570,6 +588,16 @@ MUTATOR_HOOKFUNCTION(freezetag_SpectateCopy)
        return 0;
 }
 
        return 0;
 }
 
+MUTATOR_HOOKFUNCTION(freezetag_GetTeamCount)
+{
+       freezetag_teams = autocvar_g_freezetag_teams_override;
+       if(freezetag_teams < 2)
+               freezetag_teams = autocvar_g_freezetag_teams;
+       freezetag_teams = bound(2, freezetag_teams, 4);
+       ret_float = freezetag_teams;
+       return 0;
+}
+
 MUTATOR_DEFINITION(gamemode_freezetag)
 {
        MUTATOR_HOOK(MakePlayerObserver, freezetag_RemovePlayer, CBC_ORDER_ANY);
 MUTATOR_DEFINITION(gamemode_freezetag)
 {
        MUTATOR_HOOK(MakePlayerObserver, freezetag_RemovePlayer, CBC_ORDER_ANY);
@@ -584,6 +612,7 @@ MUTATOR_DEFINITION(gamemode_freezetag)
        MUTATOR_HOOK(ForbidThrowCurrentWeapon, freezetag_ForbidThrowCurrentWeapon, CBC_ORDER_ANY);
        MUTATOR_HOOK(HavocBot_ChooseRule, freezetag_BotRoles, CBC_ORDER_ANY);
        MUTATOR_HOOK(SpectateCopy, freezetag_SpectateCopy, CBC_ORDER_ANY);
        MUTATOR_HOOK(ForbidThrowCurrentWeapon, freezetag_ForbidThrowCurrentWeapon, CBC_ORDER_ANY);
        MUTATOR_HOOK(HavocBot_ChooseRule, freezetag_BotRoles, CBC_ORDER_ANY);
        MUTATOR_HOOK(SpectateCopy, freezetag_SpectateCopy, CBC_ORDER_ANY);
+       MUTATOR_HOOK(GetTeamCount, freezetag_GetTeamCount, CBC_ORDER_EXCLUSIVE);
 
        MUTATOR_ONADD
        {
 
        MUTATOR_ONADD
        {
index 61b9f06fdc5064127c14e19d5c408ac3adcaad6b..0314104b1d3f353e9be1f235553a90f5cdc57617 100644 (file)
@@ -182,8 +182,14 @@ void InitGameplayMode()
                fraglimit_override = autocvar_g_ca_point_limit;
                leadlimit_override = autocvar_g_ca_point_leadlimit;
                allowed_to_spawn = TRUE;
                fraglimit_override = autocvar_g_ca_point_limit;
                leadlimit_override = autocvar_g_ca_point_leadlimit;
                allowed_to_spawn = TRUE;
-               precache_sound("ctf/red_capture.wav");
-               precache_sound("ctf/blue_capture.wav");
+               ca_teams = autocvar_g_ca_teams_override;
+               if(ca_teams < 2)
+                       ca_teams = autocvar_g_ca_teams;
+               ca_teams = bound(2, ca_teams, 4);
+               addstat(STAT_REDALIVE, AS_INT, redalive_stat);
+               addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat);
+               addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat);
+               addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat);
        }
        if(g_keyhunt)
        {
        }
        if(g_keyhunt)
        {
@@ -476,6 +482,8 @@ void CheckAllowedTeams (entity for_whom)
                // cover anything else by treating it like tdm with no teams spawned
                if(g_race)
                        dm = race_teams;
                // cover anything else by treating it like tdm with no teams spawned
                if(g_race)
                        dm = race_teams;
+               else if(g_ca)
+                       dm = ca_teams;
                else
                        dm = 2;
 
                else
                        dm = 2;