]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
New opt-in feature for less stalemates in CA when round timer runs out
authorDr. Jaska <drjaska83@gmail.com>
Sun, 16 Oct 2022 19:53:24 +0000 (19:53 +0000)
committerterencehill <piuntn@gmail.com>
Sun, 16 Oct 2022 19:53:24 +0000 (19:53 +0000)
New cvar: `g_ca_prevent_stalemate 0|1`
First the amount of players alive in each team is checked, if there is a single highest then that team wins the round.
If two teams have the same amount of players then their total health counts are calculated and compared.
If there is the same amount of players and total health in the 2 top teams then it's still a stalemate.

Code cleanup by z411

gamemodes-server.cfg
qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc
qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh

index a57c8f135c70aa561cf68ee2a0e52bb02aa80947..4afd6310fc34bfb6cdabd4fccf7b4efed56a6062 100644 (file)
@@ -229,6 +229,7 @@ set g_ca_round_timelimit 180 "round time limit in seconds"
 set g_ca_teams_override 0
 set g_ca_team_spawns 0 "when 1, players spawn from the team spawnpoints of the map, if any"
 set g_ca_teams 0
+set g_ca_prevent_stalemate 0 "when round time ends instead of instant stalemate give round win to the team with most survivors or with the most total health"
 set g_ca_weaponarena "most" "starting weapons - takes the same options as g_weaponarena"
 
 
index 7803108c6c00010cb896fce7fde81da0fbfebc00..d64ce3604a293b4221d21ab5c1de21da31a32bac 100644 (file)
@@ -2,6 +2,7 @@
 
 float autocvar_g_ca_damage2score = 100;
 bool autocvar_g_ca_spectate_enemies;
+bool autocvar_g_ca_prevent_stalemate;
 
 float autocvar_g_ca_start_health = 200;
 float autocvar_g_ca_start_armor = 200;
@@ -44,22 +45,99 @@ void CA_count_alive_players()
 
 void nades_Clear(entity player);
 
+int CA_PreventStalemate()
+{
+       //LOG_INFO("PreventStalemate running");
+       int winnerTeam = 0;
+       int secondTeam = 0;
+
+       for(int i = 1; i <= AVAILABLE_TEAMS; i++)
+       {
+               if(!winnerTeam || Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) > Team_GetNumberOfAlivePlayers(Team_GetTeam(winnerTeam)))
+               {
+                       secondTeam = winnerTeam;
+                       winnerTeam = Team_IndexToTeam(i);
+               }
+               else
+               {
+                       if(!secondTeam || Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) > Team_GetNumberOfAlivePlayers(Team_GetTeam(secondTeam)))
+                               secondTeam = Team_IndexToTeam(i);
+               }
+       }
+
+       if(Team_GetNumberOfAlivePlayers(Team_GetTeam(winnerTeam)) != Team_GetNumberOfAlivePlayers(Team_GetTeam(secondTeam)))
+       {
+               LOG_INFOF("Stalemate broken by alive players. Best team: %s%s (%d)^7 - Trailing team: %s%s (%d)",
+                       Team_ColorCode(winnerTeam), Team_ColorName(winnerTeam), Team_GetNumberOfAlivePlayers(Team_GetTeam(winnerTeam)),
+                       Team_ColorCode(secondTeam), Team_ColorName(secondTeam), Team_GetNumberOfAlivePlayers(Team_GetTeam(secondTeam)));
+               return winnerTeam;
+       }
+
+       // Equality. Let's check which team has more health now
+       //LOG_INFO("Equality. Checking health now.");
+       winnerTeam = 0;
+       secondTeam = 0;
+       int winnerTeamHealth = 0;
+       int secondTeamHealth = 0;
+       int teamIndex, teamHealth;
+
+       for(int i = 1; i <= AVAILABLE_TEAMS; i++)
+       {
+               teamIndex = i;
+               teamHealth = 0;
+
+               // Add up health for the players in this team
+               FOREACH_CLIENT(IS_PLAYER(it) && Entity_HasValidTeam(it) && it.team == Team_IndexToTeam(teamIndex),
+               {
+                       if (IS_DEAD(it))
+                               continue;
+                       teamHealth += GetResource(it, RES_HEALTH) + GetResource(it, RES_ARMOR);
+               });
+
+               // Set the winner teams
+               if(!winnerTeam || teamHealth > winnerTeamHealth)
+               {
+                       secondTeam = winnerTeam;
+                       secondTeamHealth = winnerTeamHealth;
+                       winnerTeam = Team_IndexToTeam(i);
+                       winnerTeamHealth = teamHealth;
+               }
+               else
+               {
+                       if(!secondTeam || teamHealth > secondTeamHealth)
+                       {
+                               secondTeam = Team_IndexToTeam(i);
+                               secondTeamHealth = teamHealth;
+                       }
+               }
+       }
+
+       if(winnerTeamHealth != secondTeamHealth)
+       {
+               LOG_INFOF("Stalemate broken by team health. Best team: %s%s (%d)^7 - Trailing team: %s%s (%d)",
+                       Team_ColorCode(winnerTeam), Team_ColorName(winnerTeam), winnerTeamHealth,
+                       Team_ColorCode(secondTeam), Team_ColorName(secondTeam), secondTeamHealth);
+               return winnerTeam;
+       }
+       else
+               return -2; // Equality. Can't avoid the stalemate.
+}
+
 float CA_CheckWinner()
 {
+       int winner_team = 0;
+
        if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
        {
-               Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_ROUND_OVER);
-               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ROUND_OVER);
-               FOREACH_CLIENT(IS_PLAYER(it), { nades_Clear(it); });
-
-               allowed_to_spawn = false;
-               game_stopped = true;
-               round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit);
-               return 1;
+               if(autocvar_g_ca_prevent_stalemate)
+                       winner_team = CA_PreventStalemate();
+               else
+                       winner_team = -2;
        }
 
        CA_count_alive_players();
-       int winner_team = Team_GetWinnerAliveTeam();
+       if (!winner_team)
+               winner_team = Team_GetWinnerAliveTeam();
        if (!winner_team)
                return 0;
 
@@ -74,6 +152,11 @@ float CA_CheckWinner()
                Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_ROUND_TIED);
                Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ROUND_TIED);
        }
+       else if(winner_team == -2)
+       {
+               Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_ROUND_OVER);
+               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ROUND_OVER);
+       }
 
        allowed_to_spawn = false;
        game_stopped = true;
index c7e147a21a95d6d4c7c54f321b605600aa693034..da93badef1a1e306865df500b8498207c8ccbe64 100644 (file)
@@ -14,7 +14,6 @@ int autocvar_g_ca_teams_override;
 float autocvar_g_ca_warmup;
 string autocvar_g_ca_weaponarena = "most";
 
-
 int ca_teams;
 bool allowed_to_spawn;