X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fmutators%2Fmutator%2Fgamemode_ca.qc;h=52fc272dcb46182ac457c43706d230eeb57af031;hb=073cc17f87486bec59ac2b6f9c26bf1155dbd7d8;hp=561a30d222a40b223d14d41a702403efba0f2a14;hpb=6d94a5a44c5dd5977c82a296ff43331b7bd52335;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/mutators/mutator/gamemode_ca.qc b/qcsrc/server/mutators/mutator/gamemode_ca.qc index 561a30d22..52fc272dc 100644 --- a/qcsrc/server/mutators/mutator/gamemode_ca.qc +++ b/qcsrc/server/mutators/mutator/gamemode_ca.qc @@ -5,68 +5,83 @@ bool autocvar_g_ca_spectate_enemies; void CA_count_alive_players() { - total_players = redalive = bluealive = yellowalive = pinkalive = 0; - FOREACH_CLIENT(IS_PLAYER(it), LAMBDA( - switch(it.team) + total_players = 0; + for (int i = 1; i <= NUM_TEAMS; ++i) + { + Team_SetNumberOfAlivePlayers(Team_GetTeamFromIndex(i), 0); + } + FOREACH_CLIENT(IS_PLAYER(it) && Entity_HasValidTeam(it), + { + ++total_players; + if (IS_DEAD(it)) { - case NUM_TEAM_1: ++total_players; if(!IS_DEAD(it)) ++redalive; break; - case NUM_TEAM_2: ++total_players; if(!IS_DEAD(it)) ++bluealive; break; - case NUM_TEAM_3: ++total_players; if(!IS_DEAD(it)) ++yellowalive; break; - case NUM_TEAM_4: ++total_players; if(!IS_DEAD(it)) ++pinkalive; break; + continue; } - )); - FOREACH_CLIENT(IS_REAL_CLIENT(it), LAMBDA( - it.redalive_stat = redalive; - it.bluealive_stat = bluealive; - it.yellowalive_stat = yellowalive; - it.pinkalive_stat = pinkalive; - )); + entity team_ = Entity_GetTeam(it); + int num_alive = Team_GetNumberOfAlivePlayers(team_); + ++num_alive; + Team_SetNumberOfAlivePlayers(team_, num_alive); + }); + FOREACH_CLIENT(IS_REAL_CLIENT(it), + { + STAT(REDALIVE, it) = Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex( + 1)); + STAT(BLUEALIVE, it) = Team_GetNumberOfAlivePlayers( + Team_GetTeamFromIndex(2)); + STAT(YELLOWALIVE, it) = Team_GetNumberOfAlivePlayers( + Team_GetTeamFromIndex(3)); + STAT(PINKALIVE, it) = Team_GetNumberOfAlivePlayers( + Team_GetTeamFromIndex(4)); + }); } -float CA_GetWinnerTeam() +int CA_GetWinnerTeam() { - float winner_team = 0; - if(redalive >= 1) - winner_team = NUM_TEAM_1; - if(bluealive >= 1) + int winner_team = 0; + if (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(1)) >= 1) { - if(winner_team) return 0; - winner_team = NUM_TEAM_2; + winner_team = NUM_TEAM_1; } - if(yellowalive >= 1) + for (int i = 2; i <= NUM_TEAMS; ++i) { - if(winner_team) return 0; - winner_team = NUM_TEAM_3; + if (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) >= 1) + { + if (winner_team != 0) + { + return 0; + } + winner_team = Team_IndexToTeam(i); + } } - if(pinkalive >= 1) + if (winner_team) { - if(winner_team) return 0; - winner_team = NUM_TEAM_4; - } - if(winner_team) return winner_team; + } return -1; // no player left } void nades_Clear(entity player); -#define CA_ALIVE_TEAMS() ((redalive > 0) + (bluealive > 0) + (yellowalive > 0) + (pinkalive > 0)) -#define CA_ALIVE_TEAMS_OK() (CA_ALIVE_TEAMS() == NumTeams(ca_teams)) +#define CA_ALIVE_TEAMS_OK() (Team_GetNumberOfAliveTeams() == NumTeams(ca_teams)) float CA_CheckWinner() { 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); - FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(nades_Clear(it))); return 1; } CA_count_alive_players(); - if(CA_ALIVE_TEAMS() > 1) + if (Team_GetNumberOfAliveTeams() > 1) + { return 0; + } int winner_team = CA_GetWinnerTeam(); if(winner_team > 0) @@ -82,9 +97,10 @@ float CA_CheckWinner() } 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), LAMBDA(nades_Clear(it))); + FOREACH_CLIENT(IS_PLAYER(it), { nades_Clear(it); }); return 1; } @@ -114,14 +130,14 @@ bool CA_CheckTeams() return false; } int missing_teams_mask = 0; - if(ca_teams & BIT(0)) - missing_teams_mask += (!redalive) * 1; - if(ca_teams & BIT(1)) - missing_teams_mask += (!bluealive) * 2; - if(ca_teams & BIT(2)) - missing_teams_mask += (!yellowalive) * 4; - if(ca_teams & BIT(3)) - missing_teams_mask += (!pinkalive) * 8; + for (int i = 1; i <= NUM_TEAMS; ++i) + { + if ((ca_teams & Team_IndexToBit(i)) && + (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) == 0)) + { + missing_teams_mask |= Team_IndexToBit(i); + } + } if(prev_missing_teams_mask != missing_teams_mask) { Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask); @@ -185,7 +201,7 @@ MUTATOR_HOOKFUNCTION(ca, PutClientInServer) if (!allowed_to_spawn && IS_PLAYER(player)) // this is true even when player is trying to join { TRANSMUTE(Observer, player); - if (player.jointime != time && !player.caplayer) // not when connecting + if (CS(player).jointime != time && !player.caplayer) // not when connecting { player.caplayer = 0.5; Send_Notification(NOTIF_ONE_ONLY, player, MSG_INFO, INFO_CA_JOIN_LATE); @@ -196,7 +212,7 @@ MUTATOR_HOOKFUNCTION(ca, PutClientInServer) MUTATOR_HOOKFUNCTION(ca, reset_map_players) { FOREACH_CLIENT(true, { - it.killcount = 0; + CS(it).killcount = 0; if (!it.caplayer && IS_BOT_CLIENT(it)) { it.team = -1; @@ -227,9 +243,10 @@ MUTATOR_HOOKFUNCTION(ca, reset_map_global) return true; } -MUTATOR_HOOKFUNCTION(ca, CheckAllowedTeams, CBC_ORDER_EXCLUSIVE) +MUTATOR_HOOKFUNCTION(ca, TeamBalance_CheckAllowedTeams, CBC_ORDER_EXCLUSIVE) { M_ARGV(0, float) = ca_teams; + return true; } entity ca_LastPlayerForTeam(entity this) @@ -263,7 +280,12 @@ MUTATOR_HOOKFUNCTION(ca, PlayerDies) ca_LastPlayerForTeam_Notify(frag_target); if (!allowed_to_spawn) - frag_target.respawn_flags = RESPAWN_SILENT; + { + frag_target.respawn_flags = RESPAWN_SILENT; + // prevent unwanted sudden rejoin as spectator and movement of spectator camera + frag_target.respawn_time = time + 2; + } + frag_target.respawn_flags |= RESPAWN_FORCE; if (!warmup_stage) eliminatedPlayers.SendFlags |= 1; if(IS_BOT_CLIENT(frag_target)) @@ -321,7 +343,7 @@ MUTATOR_HOOKFUNCTION(ca, SetStartItems) start_ammo_fuel = warmup_start_ammo_fuel = cvar("g_lms_start_ammo_fuel"); } -MUTATOR_HOOKFUNCTION(ca, PlayerDamage_Calculate) +MUTATOR_HOOKFUNCTION(ca, Damage_Calculate) { entity frag_attacker = M_ARGV(1, entity); entity frag_target = M_ARGV(2, entity); @@ -363,7 +385,13 @@ MUTATOR_HOOKFUNCTION(ca, PlayerDamage_SplitHealthArmor) float excess = max(0, frag_damage - damage_take - damage_save); if (frag_target != frag_attacker && IS_PLAYER(frag_attacker)) - PlayerTeamScore_Add(frag_attacker, SP_SCORE, ST_SCORE, (frag_damage - excess) * autocvar_g_ca_damage2score_multiplier); + GameRules_scoring_add_team(frag_attacker, SCORE, (frag_damage - excess) * autocvar_g_ca_damage2score_multiplier); +} + +MUTATOR_HOOKFUNCTION(ca, CalculateRespawnTime) +{ + // no respawn calculations needed, player is forced to spectate anyway + return true; } MUTATOR_HOOKFUNCTION(ca, PlayerRegen) @@ -455,6 +483,11 @@ MUTATOR_HOOKFUNCTION(ca, WantWeapon) M_ARGV(2, bool) = true; // all weapons } +MUTATOR_HOOKFUNCTION(ca, HideTeamNagger) +{ + return true; // doesn't work well with the whole spectator as player thing +} + MUTATOR_HOOKFUNCTION(ca, GetPlayerStatus) { entity player = M_ARGV(0, entity);