From: terencehill Date: Tue, 4 Jan 2022 00:27:48 +0000 (+0100) Subject: Add API to handle in-game status for game modes that temporarily turn players into... X-Git-Tag: xonotic-v0.8.5~246 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=682a8916075a54a070e6e2da21278bd578de400c;p=xonotic%2Fxonotic-data.pk3dir.git Add API to handle in-game status for game modes that temporarily turn players into spectators/observers when they are eliminated but keeping them "in game". Replaces caplayer and lmsplayer and the GetPlayerStatus mutator hook --- diff --git a/qcsrc/common/ent_cs.qc b/qcsrc/common/ent_cs.qc index a3691386b..fb2f9d5d3 100644 --- a/qcsrc/common/ent_cs.qc +++ b/qcsrc/common/ent_cs.qc @@ -188,7 +188,7 @@ ENTCS_PROP(SOLID, true, sv_solid, solid, ENTCS_SET_NORMAL, { if (radar_showenemies) break; if (SAME_TEAM(to, player)) break; - if (!(IS_PLAYER(to) || to.caplayer)) break; + if (!(IS_PLAYER(to) || INGAME(to))) break; } sf &= ENTCS_PUBLICMASK; // no private updates } while (0); diff --git a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc index 3d0c29261..866a00419 100644 --- a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc +++ b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc @@ -125,9 +125,9 @@ bool CA_CheckTeams() bool ca_isEliminated(entity e) { - if(e.caplayer == 1 && (IS_DEAD(e) || e.frags == FRAGS_PLAYER_OUT_OF_GAME)) + if(INGAME_JOINED(e) && (IS_DEAD(e) || e.frags == FRAGS_PLAYER_OUT_OF_GAME)) return true; - if(e.caplayer == 0.5) + if(INGAME_JOINING(e)) return true; return false; } @@ -154,7 +154,7 @@ MUTATOR_HOOKFUNCTION(ca, PlayerSpawn) { entity player = M_ARGV(0, entity); - player.caplayer = 1; + INGAME_STATUS_SET(player, INGAME_STATUS_JOINED); if (!warmup_stage) eliminatedPlayers.SendFlags |= 1; } @@ -166,7 +166,7 @@ MUTATOR_HOOKFUNCTION(ca, ForbidSpawn) // spectators / observers that weren't playing can join; they are // immediately forced to observe in the PutClientInServer hook // this way they are put in a team and can play in the next round - if (!allowed_to_spawn && player.caplayer) + if (!allowed_to_spawn && INGAME(player)) return true; return false; } @@ -178,9 +178,9 @@ 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 (CS(player).jointime != time && !player.caplayer) // not when connecting + if (CS(player).jointime != time && !INGAME(player)) // not when connecting { - player.caplayer = 0.5; + INGAME_STATUS_SET(player, INGAME_STATUS_JOINING); Send_Notification(NOTIF_ONE_ONLY, player, MSG_INFO, INFO_CA_JOIN_LATE); } } @@ -190,15 +190,15 @@ MUTATOR_HOOKFUNCTION(ca, reset_map_players) { FOREACH_CLIENT(true, { CS(it).killcount = 0; - if (!it.caplayer && IS_BOT_CLIENT(it)) + if (!INGAME(it) && IS_BOT_CLIENT(it)) { it.team = -1; - it.caplayer = 1; + INGAME_STATUS_SET(it, INGAME_STATUS_JOINED); } - if (it.caplayer) + if (INGAME(it)) { TRANSMUTE(Player, it); - it.caplayer = 1; + INGAME_STATUS_SET(it, INGAME_STATUS_JOINED); PutClientInServer(it); } }); @@ -273,21 +273,21 @@ MUTATOR_HOOKFUNCTION(ca, MakePlayerObserver) entity player = M_ARGV(0, entity); bool is_forced = M_ARGV(1, bool); - if (is_forced && player.caplayer) - player.caplayer = 0; + if (is_forced && INGAME(player)) + INGAME_STATUS_CLEAR(player); if (IS_PLAYER(player) && !IS_DEAD(player)) ca_LastPlayerForTeam_Notify(player); if (player.killindicator_teamchange == -2) // player wants to spectate { entcs_update_players(player); - player.caplayer = 0; + INGAME_STATUS_CLEAR(player); } - if (player.caplayer) + if (INGAME(player)) player.frags = FRAGS_PLAYER_OUT_OF_GAME; if (!warmup_stage) eliminatedPlayers.SendFlags |= 1; - if (!player.caplayer) + if (!INGAME(player)) return false; // allow team reset return true; // prevent team reset } @@ -411,7 +411,7 @@ MUTATOR_HOOKFUNCTION(ca, SpectateSet) entity client = M_ARGV(0, entity); entity targ = M_ARGV(1, entity); - if (!autocvar_g_ca_spectate_enemies && client.caplayer) + if (!autocvar_g_ca_spectate_enemies && INGAME(client)) if (DIFF_TEAM(targ, client)) return true; } @@ -420,7 +420,7 @@ MUTATOR_HOOKFUNCTION(ca, SpectateNext) { entity client = M_ARGV(0, entity); - if (!autocvar_g_ca_spectate_enemies && client.caplayer + if (!autocvar_g_ca_spectate_enemies && INGAME(client) && Team_GetNumberOfAlivePlayers(Entity_GetTeam(client))) { entity targ = M_ARGV(1, entity); @@ -435,7 +435,7 @@ MUTATOR_HOOKFUNCTION(ca, SpectatePrev) entity targ = M_ARGV(1, entity); entity first = M_ARGV(2, entity); - if (!autocvar_g_ca_spectate_enemies && client.caplayer + if (!autocvar_g_ca_spectate_enemies && INGAME(client) && Team_GetNumberOfAlivePlayers(Entity_GetTeam(client))) { do { targ = targ.chain; } @@ -460,7 +460,7 @@ MUTATOR_HOOKFUNCTION(ca, SpectatePrev) MUTATOR_HOOKFUNCTION(ca, Bot_FixCount, CBC_ORDER_EXCLUSIVE) { FOREACH_CLIENT(IS_REAL_CLIENT(it), { - if (IS_PLAYER(it) || it.caplayer == 1) + if (IS_PLAYER(it) || INGAME_JOINED(it)) ++M_ARGV(0, int); ++M_ARGV(1, int); }); @@ -471,7 +471,7 @@ MUTATOR_HOOKFUNCTION(ca, ClientCommand_Spectate) { entity player = M_ARGV(0, entity); - if (player.caplayer) + if (INGAME(player)) { // they're going to spec, we can do other checks if (autocvar_sv_spectate && (IS_SPEC(player) || IS_OBSERVER(player))) @@ -487,13 +487,6 @@ 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); - - return player.caplayer == 1; -} - MUTATOR_HOOKFUNCTION(ca, SetWeaponArena) { if (M_ARGV(0, string) == "0" || M_ARGV(0, string) == "") diff --git a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh index 869860f7d..c7e147a21 100644 --- a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh +++ b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh @@ -51,6 +51,3 @@ REGISTER_MUTATOR(ca, false) } return 0; } - -// should be removed in the future, as other code should not have to care -.float caplayer; // 0.5 if scheduled to join the next round diff --git a/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc b/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc index 51a352a67..76a565016 100644 --- a/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc +++ b/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc @@ -134,7 +134,7 @@ MUTATOR_HOOKFUNCTION(lms, reset_map_players) } CS(it).killcount = 0; - it.lmsplayer = 0; + INGAME_STATUS_CLEAR(it); it.lms_spectate_warning = 0; GameRules_scoring_add(it, LMS_RANK, -GameRules_scoring_add(it, LMS_RANK, 0)); GameRules_scoring_add(it, LMS_LIVES, -GameRules_scoring_add(it, LMS_LIVES, 0)); @@ -158,12 +158,12 @@ MUTATOR_HOOKFUNCTION(lms, ReadLevelCvars) // returns true if player is added to the game bool lms_AddPlayer(entity player) { - if (!player.lmsplayer) + if (!INGAME(player)) { int lives = GameRules_scoring_add(player, LMS_LIVES, LMS_NewPlayerLives()); if(lives <= 0) return false; - player.lmsplayer = 2; // temp value indicating player has just joined the game (but not spawned yet) + INGAME_STATUS_SET(player, INGAME_STATUS_JOINING); // this is just to delay setting health and armor that can't be done here } if (warmup_stage || time <= game_starttime) { @@ -204,7 +204,7 @@ MUTATOR_HOOKFUNCTION(lms, PlayerSpawn) if (warmup_stage || time < game_starttime) return true; - if (player.lmsplayer == 2) // just joined the game + if (INGAME_JOINING(player)) { // spawn player with the same amount of health / armor // as the least healthy player with the least number of lives @@ -221,7 +221,7 @@ MUTATOR_HOOKFUNCTION(lms, PlayerSpawn) SetResource(player, RES_HEALTH, max(1, min_health)); if (min_armorvalue != start_armorvalue) SetResource(player, RES_ARMOR, min_armorvalue); - player.lmsplayer = 1; + INGAME_STATUS_SET(player, INGAME_STATUS_JOINED); } } @@ -266,7 +266,7 @@ void lms_RemovePlayer(entity player) }); GameRules_scoring_add(player, LMS_RANK, pl_cnt + 1); } - else if (player.lmsplayer) + else if (INGAME(player)) { int min_forfeiter_rank = 665; // different from 666 FOREACH_CLIENT(it != player, { @@ -311,7 +311,7 @@ MUTATOR_HOOKFUNCTION(lms, ClientDisconnect) player.lms_spectate_warning = 3; lms_RemovePlayer(player); - player.lmsplayer = 0; + INGAME_STATUS_CLEAR(player); } MUTATOR_HOOKFUNCTION(lms, MakePlayerObserver) @@ -327,7 +327,7 @@ MUTATOR_HOOKFUNCTION(lms, MakePlayerObserver) GameRules_scoring_add(player, LMS_LIVES, -GameRules_scoring_add(player, LMS_LIVES, 0)); player.frags = FRAGS_SPECTATOR; TRANSMUTE(Observer, player); - player.lmsplayer = 0; + INGAME_STATUS_CLEAR(player); } else { @@ -474,7 +474,7 @@ MUTATOR_HOOKFUNCTION(lms, ItemTouch) MUTATOR_HOOKFUNCTION(lms, Bot_FixCount, CBC_ORDER_EXCLUSIVE) { FOREACH_CLIENT(IS_REAL_CLIENT(it), { - if (it.lmsplayer && it.lms_spectate_warning < 2) + if (INGAME(it) && it.lms_spectate_warning < 2) ++M_ARGV(0, int); // activerealplayers ++M_ARGV(1, int); // realplayers }); @@ -515,13 +515,6 @@ MUTATOR_HOOKFUNCTION(lms, SetWeaponArena) M_ARGV(0, string) = autocvar_g_lms_weaponarena; } -MUTATOR_HOOKFUNCTION(lms, GetPlayerStatus) -{ - entity player = M_ARGV(0, entity); - - return boolean(player.lmsplayer); -} - MUTATOR_HOOKFUNCTION(lms, AddPlayerScore) { if(game_stopped) diff --git a/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qh b/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qh index 191553012..bf02920d2 100644 --- a/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qh +++ b/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qh @@ -7,7 +7,6 @@ // 2 when player goes spectator (presses F3 to spectate for the second time) // 3 when player disconnects .int lms_spectate_warning; -.int lmsplayer; #define autocvar_g_lms_lives_override cvar("g_lms_lives_override") string autocvar_g_lms_weaponarena = "most_available"; diff --git a/qcsrc/common/gamemodes/sv_rules.qh b/qcsrc/common/gamemodes/sv_rules.qh index 34f2f921c..4fabea39c 100644 --- a/qcsrc/common/gamemodes/sv_rules.qh +++ b/qcsrc/common/gamemodes/sv_rules.qh @@ -7,6 +7,21 @@ int autocvar_leadlimit_override; // TODO: find a better location for these? int total_players; +.int ingame; +#define INGAME_STATUS_NONE 0 +#define INGAME_STATUS_JOINING 0.5 +#define INGAME_STATUS_JOINED 1 + +// typically used by game modes that temporarily turn players into spectators/observers +// when they are eliminated but keeping them "in game", i.e. listed among players +#define INGAME_STATUS_SET(it, s) (it).ingame = s +#define INGAME_STATUS_CLEAR(it) INGAME_STATUS_SET(it, INGAME_STATUS_NONE) + +#define INGAME(it) ((it).ingame) +#define INGAME_JOINED(it) ((it).ingame == INGAME_STATUS_JOINED) +#define INGAME_JOINING(it) ((it).ingame == INGAME_STATUS_JOINING) + + // todo: accept the number of teams as a parameter void GameRules_teams(bool value); diff --git a/qcsrc/server/chat.qc b/qcsrc/server/chat.qc index 204ed1341..a73de2a1f 100644 --- a/qcsrc/server/chat.qc +++ b/qcsrc/server/chat.qc @@ -31,7 +31,7 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc msgin = formatmessage(source, msgin); string colorstr; - if (!(IS_PLAYER(source) || source.caplayer)) + if (!(IS_PLAYER(source) || INGAME(source))) colorstr = "^0"; // black for spectators else if(teamplay) colorstr = Team_ColorCode(source.team); @@ -224,7 +224,7 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc sourcecmsgstr = cmsgstr; } - if (!privatesay && source && !(IS_PLAYER(source) || source.caplayer) && !game_stopped + if (!privatesay && source && !(IS_PLAYER(source) || INGAME(source)) && !game_stopped && (teamsay || CHAT_NOSPECTATORS())) { teamsay = -1; // spectators @@ -258,8 +258,8 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc ret = 1; } - if (privatesay && source && !(IS_PLAYER(source) || source.caplayer) && !game_stopped - && (IS_PLAYER(privatesay) || privatesay.caplayer) && CHAT_NOSPECTATORS()) + if (privatesay && source && !(IS_PLAYER(source) || INGAME(source)) && !game_stopped + && (IS_PLAYER(privatesay) || INGAME(privatesay)) && CHAT_NOSPECTATORS()) { ret = -1; // just hide the message completely } @@ -304,7 +304,7 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc dedicated_print(msgstr); // send to server console too if(sourcecmsgstr != "") centerprint(source, sourcecmsgstr); - FOREACH_CLIENT((IS_PLAYER(it) || it.caplayer) && IS_REAL_CLIENT(it) && it != source && it.team == source.team && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), { + FOREACH_CLIENT((IS_PLAYER(it) || INGAME(it)) && IS_REAL_CLIENT(it) && it != source && it.team == source.team && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), { sprint(it, msgstr); if(cmsgstr != "") centerprint(it, cmsgstr); @@ -315,7 +315,7 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc { sprint(source, sourcemsgstr); dedicated_print(msgstr); // send to server console too - FOREACH_CLIENT(!(IS_PLAYER(it) || it.caplayer) && IS_REAL_CLIENT(it) && it != source && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), { + FOREACH_CLIENT(!(IS_PLAYER(it) || INGAME(it)) && IS_REAL_CLIENT(it) && it != source && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), { sprint(it, msgstr); }); event_log_msg = sprintf(":chat_spec:%d:%s", source.playerid, strreplace("\n", " ", msgin)); diff --git a/qcsrc/server/client.qc b/qcsrc/server/client.qc index 2cf6f95f6..edefc0d28 100644 --- a/qcsrc/server/client.qc +++ b/qcsrc/server/client.qc @@ -2011,8 +2011,7 @@ int nJoinAllowed(entity this, entity ignore) FOREACH_CLIENT(true, { if(it != ignore) ++totalClients; - if(IS_REAL_CLIENT(it)) - if(IS_PLAYER(it) || it.caplayer) + if(IS_REAL_CLIENT(it) && (IS_PLAYER(it) || INGAME(it))) ++currentlyPlaying; }); @@ -2025,7 +2024,7 @@ int nJoinAllowed(entity this, entity ignore) free_slots = min(maxclients - totalClients, player_limit - currentlyPlaying); static float msg_time = 0; - if(this && !this.caplayer && ignore && !free_slots && time > msg_time) + if(this && !INGAME(this) && ignore && !free_slots && time > msg_time) { Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_JOIN_PREVENT); msg_time = time + 0.5; @@ -2401,7 +2400,7 @@ void PlayerPreThink (entity this) // WORKAROUND: only use dropclient in server frames (frametime set). // Never use it in cl_movement frames (frametime zero). if (blockSpectators && IS_REAL_CLIENT(this) - && (IS_SPEC(this) || IS_OBSERVER(this)) && !this.caplayer + && (IS_SPEC(this) || IS_OBSERVER(this)) && !INGAME(this) && time > (CS(this).spectatortime + autocvar_g_maxplayers_spectator_blocktime)) { if (dropclient_schedule(this)) diff --git a/qcsrc/server/command/cmd.qc b/qcsrc/server/command/cmd.qc index 7241b7415..c9ceb31b6 100644 --- a/qcsrc/server/command/cmd.qc +++ b/qcsrc/server/command/cmd.qc @@ -381,13 +381,13 @@ void ClientCommand_ready(entity caller, int request) // todo: anti-spam for tog if (caller.ready) // toggle { caller.ready = false; - if(IS_PLAYER(caller) || caller.caplayer == 1) + if (IS_PLAYER(caller) || INGAME_JOINED(caller)) bprint(playername(caller.netname, caller.team, false), "^2 is ^1NOT^2 ready\n"); } else { caller.ready = true; - if(IS_PLAYER(caller) || caller.caplayer == 1) + if (IS_PLAYER(caller) || INGAME_JOINED(caller)) bprint(playername(caller.netname, caller.team, false), "^2 is ready\n"); } diff --git a/qcsrc/server/command/sv_cmd.qc b/qcsrc/server/command/sv_cmd.qc index daa59b5cf..ca6b268e2 100644 --- a/qcsrc/server/command/sv_cmd.qc +++ b/qcsrc/server/command/sv_cmd.qc @@ -1132,12 +1132,9 @@ void GameCommand_nospectators(int request) { blockSpectators = 1; // give every spectator seconds time to become a player - FOREACH_CLIENT(IS_REAL_CLIENT(it) && (IS_SPEC(it) || IS_OBSERVER(it)) && !it.caplayer, { - if(!it.caplayer) - { - CS(it).spectatortime = time; - Send_Notification(NOTIF_ONE_ONLY, it, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime); - } + FOREACH_CLIENT(IS_REAL_CLIENT(it) && (IS_SPEC(it) || IS_OBSERVER(it)) && !INGAME(it), { + CS(it).spectatortime = time; + Send_Notification(NOTIF_ONE_ONLY, it, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime); }); bprint(strcat("^7All spectators will be automatically kicked when not joining the game after ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds!\n")); return; @@ -1253,7 +1250,7 @@ void shuffleteams() return; } - FOREACH_CLIENT(IS_PLAYER(it) || it.caplayer, { + FOREACH_CLIENT(IS_PLAYER(it) || INGAME(it), { if (Player_HasRealForcedTeam(it)) { // we could theoretically assign forced players to their teams // and shuffle the rest to fill the empty spots but in practise @@ -1275,7 +1272,7 @@ void shuffleteams() TeamBalance_Destroy(balance); int team_index = 0; - FOREACH_CLIENT_RANDOM(IS_PLAYER(it) || it.caplayer, { + FOREACH_CLIENT_RANDOM(IS_PLAYER(it) || INGAME(it), { int target_team_index = team_index + 1; if (Entity_GetTeamIndex(it) != target_team_index) { diff --git a/qcsrc/server/command/vote.qc b/qcsrc/server/command/vote.qc index f8345bd83..6b39ab7b6 100644 --- a/qcsrc/server/command/vote.qc +++ b/qcsrc/server/command/vote.qc @@ -499,7 +499,7 @@ void ReadyCount() float ready_needed_factor, ready_needed_count; float t_ready = 0, t_players = 0; - FOREACH_CLIENT(IS_REAL_CLIENT(it) && (IS_PLAYER(it) || it.caplayer == 1), { + FOREACH_CLIENT(IS_REAL_CLIENT(it) && (IS_PLAYER(it) || INGAME_JOINED(it)), { ++t_players; if (it.ready) ++t_ready; }); diff --git a/qcsrc/server/scores.qc b/qcsrc/server/scores.qc index fd2c2cc55..7e1bfd1e5 100644 --- a/qcsrc/server/scores.qc +++ b/qcsrc/server/scores.qc @@ -556,12 +556,12 @@ void WinningConditionHelper(entity this) { s = GetPlayerScoreString(it, 1); s = strcat(s, IS_REAL_CLIENT(it) ? ":human" : ":bot"); - if(!IS_PLAYER(it) && !MUTATOR_CALLHOOK(GetPlayerStatus, it)) + if(!(IS_PLAYER(it) || INGAME_JOINED(it))) s = strcat(s, ":spectator"); } else { - if (IS_PLAYER(it) || MUTATOR_CALLHOOK(GetPlayerStatus, it)) + if (IS_PLAYER(it) || INGAME_JOINED(it)) s = GetPlayerScoreString(it, 2); else s = "-666"; diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index 7257156a9..0bc7e7cbb 100644 --- a/qcsrc/server/teamplay.qc +++ b/qcsrc/server/teamplay.qc @@ -714,7 +714,7 @@ void TeamBalance_GetTeamCounts(entity balance, entity ignore) } int team_num; // TODO: Reconsider when the player is truly on the team. - if (IS_CLIENT(it) || (it.caplayer)) + if (IS_CLIENT(it) || INGAME(it)) { team_num = it.team; } diff --git a/qcsrc/server/world.qc b/qcsrc/server/world.qc index 580073830..a438e633f 100644 --- a/qcsrc/server/world.qc +++ b/qcsrc/server/world.qc @@ -1213,7 +1213,7 @@ void DumpStats(float final) FOREACH_CLIENT(IS_REAL_CLIENT(it) || (IS_BOT_CLIENT(it) && autocvar_sv_logscores_bots), { s = strcat(":player:see-labels:", GetPlayerScoreString(it, 0), ":"); s = strcat(s, ftos(rint(time - CS(it).jointime)), ":"); - if(IS_PLAYER(it) || MUTATOR_CALLHOOK(GetPlayerStatus, it)) + if(IS_PLAYER(it) || INGAME_JOINED(it)) s = strcat(s, ftos(it.team), ":"); else s = strcat(s, "spectator:"); @@ -1300,7 +1300,7 @@ void NextLevel() GameLogClose(); int winner_team = 0; - FOREACH_CLIENT(IS_PLAYER(it) || it.caplayer, { + FOREACH_CLIENT(IS_PLAYER(it) || INGAME(it), { FixIntermissionClient(it); if(it.winning) { @@ -1390,13 +1390,13 @@ float GetWinningCode(float fraglimitreached, float equality) // set the .winning flag for exactly those players with a given field value void SetWinners(.float field, float value) { - FOREACH_CLIENT(IS_PLAYER(it) || it.caplayer, { it.winning = (it.(field) == value); }); + FOREACH_CLIENT(IS_PLAYER(it) || INGAME(it), { it.winning = (it.(field) == value); }); } // set the .winning flag for those players with a given field value void AddWinners(.float field, float value) { - FOREACH_CLIENT(IS_PLAYER(it) || it.caplayer, { + FOREACH_CLIENT(IS_PLAYER(it) || INGAME(it), { if(it.(field) == value) it.winning = 1; }); @@ -1405,7 +1405,7 @@ void AddWinners(.float field, float value) // clear the .winning flags void ClearWinners() { - FOREACH_CLIENT(IS_PLAYER(it) || it.caplayer, { it.winning = 0; }); + FOREACH_CLIENT(IS_PLAYER(it) || INGAME(it), { it.winning = 0; }); } int fragsleft_last;