]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Cleaner CA stalemate implementation
authorz411 <z411@omaera.org>
Wed, 28 Sep 2022 23:11:34 +0000 (20:11 -0300)
committerz411 <z411@omaera.org>
Wed, 28 Sep 2022 23:11:34 +0000 (20:11 -0300)
gamemodes-server.cfg
qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc
qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh

index 44942ceb83bc7e66fe9c52b7ffaf8bfec1f6f1ce..4afd6310fc34bfb6cdabd4fccf7b4efed56a6062 100644 (file)
@@ -229,7 +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_less_stalemates 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_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 e8e9fb63e9a480b7aa032993dc66e366c5386030..2b7f76defb6569758904fdb736f610c38cd1cf65 100644 (file)
@@ -2,7 +2,7 @@
 
 float autocvar_g_ca_damage2score = 100;
 bool autocvar_g_ca_spectate_enemies;
-bool autocvar_g_ca_less_stalemates;
+bool autocvar_g_ca_prevent_stalemate;
 
 float autocvar_g_ca_start_health = 200;
 float autocvar_g_ca_start_armor = 200;
@@ -45,163 +45,93 @@ void CA_count_alive_players()
 
 void nades_Clear(entity player);
 
-float CA_LessStalemates()
+int CA_PreventStalemate()
 {
-print("less CA stalemates is active\n");
-       int highestHealthTeam = 0;
-       int secondHighestHealthTeam = 0;
+       int winnerTeam = 0;
+       int secondTeam = 0;
 
        // change AvailableTeams() to AVAILABLE_TEAMS when this is merged to this branch
        //  https://gitlab.com/xonotic/xonotic-data.pk3dir/-/merge_requests/1022/
-       for(int i = 1; i <= AvailableTeams(); i++){
-               Team_GetTeamFromIndex(i).health = 0;
-       }
-
-       // fetch the amount of alive players for each team
-       // and at the same time order them on the two index pointers based on which one of them has the most of them
-       for (int i = 1; i <= AvailableTeams(); i++){
-               if (ca_teams & Team_IndexToBit(i)){
-                       if (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) > 0 && highestHealthTeam == 0
-                                       || Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) > Team_GetTeamFromIndex(highestHealthTeam).health)
+       for(int i = 1; i <= AvailableTeams(); i++)
+       {
+               if(!winnerTeam || Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) > Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(winnerTeam)))
+               {
+                       secondTeam = winnerTeam;
+                       winnerTeam = i;
+               }
+               else
+               {
+                       if(!secondTeam || Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) > Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(secondTeam)))
                        {
-                               Team_GetTeamFromIndex(i).health = Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i));
-                               secondHighestHealthTeam = highestHealthTeam;
-                               highestHealthTeam = i;
-                       } else {
-                               if (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) > 0 && secondHighestHealthTeam == 0
-                                               || Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) > Team_GetTeamFromIndex(secondHighestHealthTeam).health)
-                               {
-                                       Team_GetTeamFromIndex(i).health = Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i));
-                                       secondHighestHealthTeam = i;
-                               }
+                               secondTeam = i;
                        }
                }
        }
 
-print("amount of players alive in teams\n");
-       for (int i = 1; i <= AvailableTeams(); i++){
-               print(sprintf("%f", Team_GetTeamFromIndex(i).health), "\n");
-       }
-
-       // check if we have a team with more alive players than others
-       if (Team_GetTeamFromIndex(highestHealthTeam).health != Team_GetTeamFromIndex(secondHighestHealthTeam).health)
-       {
-print("different amount of players alive in teams\n");
-               Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, APP_TEAM_NUM(Team_IndexToTeam(highestHealthTeam), CENTER_ROUND_TEAM_WIN));
-               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(Team_IndexToTeam(highestHealthTeam), INFO_ROUND_TEAM_WIN));
-               TeamScore_AddToTeam(Team_IndexToTeam(highestHealthTeam), ST_CA_ROUNDS, +1);
-
-               allowed_to_spawn = false;
-               game_stopped = true;
-               round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit);
-
-               FOREACH_CLIENT(IS_PLAYER(it), { nades_Clear(it); });
-
-               return 1;
-       }
+       if(Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(winnerTeam)) != Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(secondTeam)))
+               return Team_IndexToTeam(winnerTeam);
 
-       // check which team has more health then
-print("checking health\n");
-       for (int i = 1; i <= AvailableTeams(); i++){
-               Team_GetTeamFromIndex(i).health = 0;
-       }
+       // Equality. Let's check which team has more health now
+       winnerTeam = 0;
+       secondTeam = 0;
+       int winnerTeamHealth = 0;
+       int secondTeamHealth = 0;
+       int teamIndex, teamHealth;
 
-       // fetch health amount of each player for each team
-       FOREACH_CLIENT(IS_PLAYER(it) && Entity_HasValidTeam(it),
+       for(int i = 1; i <= AvailableTeams(); i++)
        {
-               if (IS_DEAD(it)){
-                       continue;
-               }
-               float healthValue = GetResource(it, RES_HEALTH);
-               float armorValue = GetResource(it, RES_ARMOR);
-
-               for (int i = 1; i <= AvailableTeams(); i++)
-                       if (it.team == Team_IndexToTeam(i))
-                               (Team_GetTeamFromIndex(i)).health += healthValue+armorValue;
-       });
-
-print("amount of health in teams\n");
-       for (int i = 1; i <= AvailableTeams(); i++){
-               print(sprintf("%f", Team_GetTeamFromIndex(i).health), "\n");
-       }
+               teamIndex = i;
+               teamHealth = 0;
 
-       highestHealthTeam = 0;
-       secondHighestHealthTeam = 0;
-
-       // compare which teams have the most health
-       for (int i = 1; i <= AvailableTeams(); i++){
-               if (Team_GetTeamFromIndex(i).health > 0 && highestHealthTeam == 0
-                               || Team_GetTeamFromIndex(i).health > Team_GetTeamFromIndex(highestHealthTeam).health)
+               // Add up health for the players in this team
+               FOREACH_CLIENT(IS_PLAYER(it) && Entity_HasValidTeam(it),
+               {
+                       if (it.team != Team_IndexToTeam(teamIndex))
+                               continue;
+                       if (IS_DEAD(it))
+                               continue;
+                       teamHealth += GetResource(it, RES_HEALTH) + GetResource(it, RES_ARMOR);
+               });
+
+               // Set the winner teams
+               if(!winnerTeam || teamHealth > winnerTeamHealth)
                {
-                       secondHighestHealthTeam = highestHealthTeam;
-                       highestHealthTeam = i;
-               } else {
-                       if (Team_GetTeamFromIndex(i).health > 0 && secondHighestHealthTeam == 0
-                                       || Team_GetTeamFromIndex(i).health > Team_GetTeamFromIndex(secondHighestHealthTeam).health)
+                       secondTeam = winnerTeam;
+                       secondTeamHealth = winnerTeamHealth;
+                       winnerTeam = i;
+                       winnerTeamHealth = teamHealth;
+               }
+               else
+               {
+                       if(!secondTeam || teamHealth > secondTeamHealth)
                        {
-                               secondHighestHealthTeam = i;
+                               secondTeam = i;
+                               secondTeamHealth = teamHealth;
                        }
                }
        }
 
-       // award round win to the team with highest total health
-       if (Team_GetTeamFromIndex(highestHealthTeam).health > Team_GetTeamFromIndex(secondHighestHealthTeam).health){
-print("different amount of health in teams\n");
-               Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, APP_TEAM_NUM(Team_IndexToTeam(highestHealthTeam), CENTER_ROUND_TEAM_WIN));
-               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(Team_IndexToTeam(highestHealthTeam), INFO_ROUND_TEAM_WIN));
-               TeamScore_AddToTeam(Team_IndexToTeam(highestHealthTeam), ST_CA_ROUNDS, +1);
-
-               allowed_to_spawn = false;
-               game_stopped = true;
-               round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit);
-
-               FOREACH_CLIENT(IS_PLAYER(it), { nades_Clear(it); });
-
-               for (int i = 1; i <= AvailableTeams(); i++){
-                       Team_GetTeamFromIndex(i).health = 0;
-               }
-
-               return 1;
-       }
-       else // two top teams have identical survivor count and total health? fine, stalemate...
-       {
-print("same amount of health in teams, still a stalemate...\n");
-               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);
-
-               for (int i = 1; i <= AvailableTeams(); i++){
-                       Team_GetTeamFromIndex(i).health = 0;
-               }
-
-               return 1;
-       }
+       if(winnerTeamHealth != secondTeamHealth)
+               return Team_IndexToTeam(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)
        {
-               if(!autocvar_g_ca_less_stalemates){
-                       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);
-               } else {
-                       CA_LessStalemates();
-               }
-               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;
 
@@ -216,6 +146,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 fc2513e1c6e0e86d4d89573aff9789fd08c0045a..da93badef1a1e306865df500b8498207c8ccbe64 100644 (file)
@@ -14,8 +14,6 @@ int autocvar_g_ca_teams_override;
 float autocvar_g_ca_warmup;
 string autocvar_g_ca_weaponarena = "most";
 
-.float health;
-
 int ca_teams;
 bool allowed_to_spawn;