From 6076fca112b355279b4e48f3ab5e30503b9452a1 Mon Sep 17 00:00:00 2001 From: z411 Date: Wed, 28 Sep 2022 20:11:34 -0300 Subject: [PATCH] Cleaner CA stalemate implementation --- gamemodes-server.cfg | 2 +- .../gamemode/clanarena/sv_clanarena.qc | 195 ++++++------------ .../gamemode/clanarena/sv_clanarena.qh | 2 - 3 files changed, 66 insertions(+), 133 deletions(-) diff --git a/gamemodes-server.cfg b/gamemodes-server.cfg index 44942ceb8..4afd6310f 100644 --- a/gamemodes-server.cfg +++ b/gamemodes-server.cfg @@ -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" diff --git a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc index e8e9fb63e..2b7f76def 100644 --- a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc +++ b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc @@ -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; diff --git a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh index fc2513e1c..da93badef 100644 --- a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh +++ b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh @@ -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; -- 2.39.2