]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'drjaska/ca-less-stalemates' into 'master'
authorterencehill <piuntn@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 opt-in feature for less stalemates in CA when round timer runs out

See merge request xonotic/xonotic-data.pk3dir!1068

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;