From: drjaska Date: Sat, 17 Sep 2022 22:06:31 +0000 (+0300) Subject: add a feature in CA for less stalemates when round timer runs out X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=76a1139ff599d266c01e988b6ac9d90a5bef4942;p=xonotic%2Fxonotic-data.pk3dir.git add a feature in CA for less stalemates when round timer runs out --- diff --git a/gamemodes-server.cfg b/gamemodes-server.cfg index a57c8f135..44942ceb8 100644 --- a/gamemodes-server.cfg +++ b/gamemodes-server.cfg @@ -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_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_weaponarena "most" "starting weapons - takes the same options as g_weaponarena" diff --git a/qcsrc/common/gamemodes/gamemode/clanarena/.sv_clanarena.qc.swp b/qcsrc/common/gamemodes/gamemode/clanarena/.sv_clanarena.qc.swp new file mode 100644 index 000000000..b6d775053 Binary files /dev/null and b/qcsrc/common/gamemodes/gamemode/clanarena/.sv_clanarena.qc.swp differ diff --git a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc index 7803108c6..aa3c0f188 100644 --- a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc +++ b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc @@ -2,6 +2,7 @@ float autocvar_g_ca_damage2score = 100; bool autocvar_g_ca_spectate_enemies; +bool autocvar_g_ca_less_stalemates; float autocvar_g_ca_start_health = 200; float autocvar_g_ca_start_armor = 200; @@ -44,10 +45,124 @@ void CA_count_alive_players() void nades_Clear(entity player); -float CA_CheckWinner() +float CA_LessStalemates() { - if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0) +print("less CA stalemates is active\n"); + int highestHealthTeam = 0; + int secondHighestHealthTeam = 0; + // REFACTORME: remove this array and use team.health instead + float teamAlivePlayers[NUM_TEAMS]; + for(int i = 0; i < NUM_TEAMS; i++){ + teamAlivePlayers[i] = 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 = 0; i < NUM_TEAMS; i++){ + if (ca_teams & Team_IndexToBit(i+1)){ + if (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i+1)) > 0 && highestHealthTeam == 0 + || Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i+1)) > teamAlivePlayers[highestHealthTeam-1]) + { + teamAlivePlayers[i] = Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i+1)); + secondHighestHealthTeam = highestHealthTeam; + highestHealthTeam = i+1; + } else { + if (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i+1)) > 0 && secondHighestHealthTeam == 0 + || Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i+1)) > teamAlivePlayers[secondHighestHealthTeam-1]) + { + teamAlivePlayers[i] = Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i+1)); + secondHighestHealthTeam = i+1; + } + } + } + } + +print("amount of players alive in teams\n"); + for (int i = 0; i < NUM_TEAMS; i++){ + print(sprintf("%f", teamAlivePlayers[i]), "\n"); + } + + // check if we have a team with more alive players than others + if (teamAlivePlayers[highestHealthTeam-1] != teamAlivePlayers[secondHighestHealthTeam-1]) { +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; + } + + // check which team has more health then +print("checking health\n"); + // REFACTORME: remove this array and use team.health instead + float teamHealth[NUM_TEAMS]; + for (int i = 0; i < NUM_TEAMS; i++){ + teamHealth[i] = 0; + } + + // fetch health amount of each player for each team + FOREACH_CLIENT(IS_PLAYER(it) && Entity_HasValidTeam(it), + { + if (IS_DEAD(it)){ + continue; + } + float health = GetResource(it, RES_HEALTH); + float armor = GetResource(it, RES_ARMOR); + + for (int i = 0; i < NUM_TEAMS; i++) + if(it.team == Team_IndexToTeam(i+1)) + teamHealth[i] += health+armor; + }); + +print("amount of health in teams\n"); + for (int i = 0; i < NUM_TEAMS; i++){ + print(sprintf("%f", teamHealth[i]), "\n"); + } + + highestHealthTeam = 0; + secondHighestHealthTeam = 0; + + // compare which teams have the most health + for (int i = 0; i < NUM_TEAMS; i++){ + if (teamHealth[i] > 0 && highestHealthTeam == 0 + || teamHealth[i] > teamHealth[highestHealthTeam-1]) + { + secondHighestHealthTeam = highestHealthTeam; + highestHealthTeam = i+1; + } else { + if (teamHealth[i] > 0 && secondHighestHealthTeam == 0 + || teamHealth[i] > teamHealth[secondHighestHealthTeam-1]) + { + secondHighestHealthTeam = i+1; + } + } + } + + // award round win to the team with highest total health + if (teamHealth[highestHealthTeam-1] > teamHealth[secondHighestHealthTeam-1]){ +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); }); + + 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); }); @@ -57,6 +172,26 @@ float CA_CheckWinner() round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit); return 1; } +} + +float CA_CheckWinner() +{ + 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); + return 1; + } else { + if (CA_LessStalemates()) + return 1; + } + } CA_count_alive_players(); int winner_team = Team_GetWinnerAliveTeam();