X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fscores.qc;h=3a8b830d74c04e82063566368b0c949bc7f52878;hb=490873e0e642771efcb3f48ea43236ac0370cacd;hp=102dd6a33ef326af860bdd8d66c0ba537f5f8a89;hpb=d8e541e5cabb4e7981c0ab2e86f859440f0138f1;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/scores.qc b/qcsrc/server/scores.qc index 102dd6a33..3a8b830d7 100644 --- a/qcsrc/server/scores.qc +++ b/qcsrc/server/scores.qc @@ -10,11 +10,11 @@ var .float teamscores_primary; float scores_flags_primary; float teamscores_flags_primary; -vector ScoreField_Compare(entity t1, entity t2, .float field, float fieldflags, vector previous) // returns: cmp value, best prio +vector ScoreField_Compare(entity t1, entity t2, .float field, float fieldflags, vector previous, float strict) // returns: cmp value, best prio { - if(!(fieldflags & SFL_SORT_PRIO_MASK)) // column does not sort + if(!strict && !(fieldflags & SFL_SORT_PRIO_MASK)) // column does not sort return previous; - if(fieldflags & SFL_SORT_PRIO_MASK < previous_y) + if((fieldflags & SFL_SORT_PRIO_MASK) < previous_y) return previous; if(t1.field == t2.field) return previous; @@ -123,7 +123,7 @@ float TeamScore_Add(entity player, float scorefield, float score) return TeamScore_AddToTeam(player.team, scorefield, score); } -float TeamScore_Compare(entity t1, entity t2) +float TeamScore_Compare(entity t1, entity t2, float strict) { if(!t1 || !t2) return (!t2) - !t1; @@ -133,8 +133,12 @@ float TeamScore_Compare(entity t1, entity t2) { var .float f; f = teamscores[i]; - result = ScoreField_Compare(t1, t2, f, teamscores_flags[i], result); + result = ScoreField_Compare(t1, t2, f, teamscores_flags[i], result, strict); } + + if (result_x == 0 && strict) + result_x = t1.team - t2.team; + return result_x; } @@ -146,7 +150,7 @@ void ScoreInfo_SetLabel_PlayerScore(float i, string label, float scoreflags) { scores_label[i] = label; scores_flags[i] = scoreflags; - if(scoreflags & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_PRIMARY) + if((scoreflags & SFL_SORT_PRIO_MASK) == SFL_SORT_PRIO_PRIMARY) { scores_primary = scores[i]; scores_flags_primary = scoreflags; @@ -162,11 +166,16 @@ void ScoreInfo_SetLabel_TeamScore(float i, string label, float scoreflags) { teamscores_label[i] = label; teamscores_flags[i] = scoreflags; - if(scoreflags & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_PRIMARY) + if((scoreflags & SFL_SORT_PRIO_MASK) == SFL_SORT_PRIO_PRIMARY) { teamscores_primary = teamscores[i]; teamscores_flags_primary = scoreflags; } + if(label != "") + { + PlayerStats_AddEvent(strcat(PLAYERSTATS_TOTAL, label)); + PlayerStats_AddEvent(strcat(PLAYERSTATS_SCOREBOARD, label)); + } } float ScoreInfo_SendEntity(entity to, float sf) @@ -200,13 +209,13 @@ void ScoreInfo_Init(float teams) Net_LinkEntity(scores_initialized, FALSE, 0, ScoreInfo_SendEntity); } if(teams >= 1) - TeamScore_Spawn(COLOR_TEAM1, "Red"); + TeamScore_Spawn(NUM_TEAM_1, "Red"); if(teams >= 2) - TeamScore_Spawn(COLOR_TEAM2, "Blue"); + TeamScore_Spawn(NUM_TEAM_2, "Blue"); if(teams >= 3) - TeamScore_Spawn(COLOR_TEAM3, "Yellow"); + TeamScore_Spawn(NUM_TEAM_3, "Yellow"); if(teams >= 4) - TeamScore_Spawn(COLOR_TEAM4, "Pink"); + TeamScore_Spawn(NUM_TEAM_4, "Pink"); } /* @@ -244,18 +253,18 @@ float PlayerScore_SendEntity(entity to, float sendflags) return TRUE; } -void PlayerScore_Clear(entity player) +float PlayerScore_Clear(entity player) { entity sk; float i; if(teamscores_entities_count) - return; + return 0; + + if(MUTATOR_CALLHOOK(ForbidPlayerScore_Clear)) return 0; - if(g_lms) return; - if(g_arena || g_ca) return; - if(g_cts) return; // in CTS, you don't lose score by observing - if(g_race && g_race_qualifying) return; // in qualifying, you don't lose score by observing + if(g_cts) return 0; // in CTS, you don't lose score by observing + if(g_race && g_race_qualifying) return 0; // in qualifying, you don't lose score by observing sk = player.scorekeeper; for(i = 0; i < MAX_SCORE; ++i) @@ -265,6 +274,8 @@ void PlayerScore_Clear(entity player) sk.SendFlags |= pow(2, i); sk.(scores[i]) = 0; } + + return 1; } void Score_ClearAll() @@ -323,7 +334,7 @@ float PlayerScore_Add(entity player, float scorefield, float score) entity s; if(gameover) - if not(g_lms && scorefield == SP_LMS_RANK) // allow writing to this field in intermission as it is needed for newly joining players + if(!(g_lms && scorefield == SP_LMS_RANK)) // allow writing to this field in intermission as it is needed for newly joining players score = 0; if(!scores_initialized) return 0; // FIXME remove this when everything uses this system @@ -338,7 +349,7 @@ float PlayerScore_Add(entity player, float scorefield, float score) if(score) if(scores_label[scorefield] != "") s.SendFlags |= pow(2, scorefield); - if(!inWarmupStage) + if(!warmup_stage) PlayerStats_Event(s.owner, strcat(PLAYERSTATS_TOTAL, scores_label[scorefield]), score); return (s.(scores[scorefield]) += score); } @@ -352,7 +363,7 @@ float PlayerTeamScore_Add(entity player, float pscorefield, float tscorefield, f return r; } -float PlayerScore_Compare(entity t1, entity t2) +float PlayerScore_Compare(entity t1, entity t2, float strict) { if(!t1 || !t2) return (!t2) - !t1; @@ -362,8 +373,12 @@ float PlayerScore_Compare(entity t1, entity t2) { var .float f; f = scores[i]; - result = ScoreField_Compare(t1, t2, f, scores_flags[i], result); + result = ScoreField_Compare(t1, t2, f, scores_flags[i], result, strict); } + + if (result_x == 0 && strict) + result_x = num_for_edict(t1.owner) - num_for_edict(t2.owner); + return result_x; } @@ -383,15 +398,15 @@ void WinningConditionHelper() // so to match pure, match for :P0: // to match full, match for :S0: + fullstatus = autocvar_g_full_getstatus_responses; + s = GetGametype(); s = strcat(s, ":", autocvar_g_xonoticversion); s = strcat(s, ":P", ftos(cvar_purechanges_count)); s = strcat(s, ":S", ftos(nJoinAllowed(world))); s = strcat(s, ":F", ftos(serverflags)); s = strcat(s, ":M", modname); - s = strcat(s, "::", GetPlayerScoreString(world, 1)); // make this 1 once we can, note: this doesn't contain any : - - fullstatus = autocvar_g_full_getstatus_responses; + s = strcat(s, "::", GetPlayerScoreString(world, (fullstatus ? 1 : 2))); if(teamscores_entities_count) { @@ -409,7 +424,7 @@ void WinningConditionHelper() for(t = 0; t < 16; ++t) { sk = teamscorekeepers[t]; - c = TeamScore_Compare(winnerscorekeeper, sk); + c = TeamScore_Compare(winnerscorekeeper, sk, 1); if(c < 0) { WinningConditionHelper_secondteam = WinningConditionHelper_winnerteam; @@ -419,7 +434,7 @@ void WinningConditionHelper() } else { - c = TeamScore_Compare(secondscorekeeper, sk); + c = TeamScore_Compare(secondscorekeeper, sk, 1); if(c < 0) { WinningConditionHelper_secondteam = t + 1; @@ -428,7 +443,7 @@ void WinningConditionHelper() } } - WinningConditionHelper_equality = (TeamScore_Compare(winnerscorekeeper, secondscorekeeper) == 0); + WinningConditionHelper_equality = (TeamScore_Compare(winnerscorekeeper, secondscorekeeper, 0) == 0); if(WinningConditionHelper_equality) WinningConditionHelper_winnerteam = WinningConditionHelper_secondteam = -1; @@ -449,7 +464,7 @@ void WinningConditionHelper() FOR_EACH_PLAYER(p) { sk = p.scorekeeper; - c = PlayerScore_Compare(winnerscorekeeper, sk); + c = PlayerScore_Compare(winnerscorekeeper, sk, 1); if(c < 0) { WinningConditionHelper_second = WinningConditionHelper_winner; @@ -459,7 +474,7 @@ void WinningConditionHelper() } else { - c = PlayerScore_Compare(secondscorekeeper, sk); + c = PlayerScore_Compare(secondscorekeeper, sk, 1); if(c < 0) { WinningConditionHelper_second = p; @@ -468,7 +483,7 @@ void WinningConditionHelper() } } - WinningConditionHelper_equality = (PlayerScore_Compare(winnerscorekeeper, secondscorekeeper) == 0); + WinningConditionHelper_equality = (PlayerScore_Compare(winnerscorekeeper, secondscorekeeper, 0) == 0); if(WinningConditionHelper_equality) WinningConditionHelper_winner = WinningConditionHelper_second = world; @@ -513,16 +528,16 @@ void WinningConditionHelper() if(fullstatus) { s = GetPlayerScoreString(p, 1); - if(clienttype(p) == CLIENTTYPE_REAL) + if(IS_REAL_CLIENT(p)) s = strcat(s, ":human"); else s = strcat(s, ":bot"); - if(p.classname != "player" && !g_arena && !g_ca && !g_lms) + if(!IS_PLAYER(p) && p.caplayer != 1 && !g_lms) s = strcat(s, ":spectator"); } else { - if(p.classname == "player" || g_arena || g_ca || g_lms) + if(IS_PLAYER(p) || p.caplayer == 1 || g_lms) s = GetPlayerScoreString(p, 2); else s = "-666"; @@ -538,9 +553,9 @@ string GetScoreLogLabel(string label, float fl) { if(fl & SFL_LOWER_IS_BETTER) label = strcat(label, "<"); - if(fl & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_PRIMARY) + if((fl & SFL_SORT_PRIO_MASK) == SFL_SORT_PRIO_PRIMARY) label = strcat(label, "!!"); - else if(fl & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_SECONDARY) + else if((fl & SFL_SORT_PRIO_MASK) == SFL_SORT_PRIO_SECONDARY) label = strcat(label, "!"); return label; } @@ -557,7 +572,7 @@ string GetPlayerScoreString(entity pl, float shortString) { // label for(i = 0; i < MAX_SCORE; ++i) - if(scores_flags[i] & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_PRIMARY) + if((scores_flags[i] & SFL_SORT_PRIO_MASK) == SFL_SORT_PRIO_PRIMARY) { f = scores_flags[i]; l = scores_label[i]; @@ -565,7 +580,7 @@ string GetPlayerScoreString(entity pl, float shortString) } if(shortString < 2) for(i = 0; i < MAX_SCORE; ++i) - if(scores_flags[i] & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_SECONDARY) + if((scores_flags[i] & SFL_SORT_PRIO_MASK) == SFL_SORT_PRIO_SECONDARY) { f = scores_flags[i]; l = scores_label[i]; @@ -573,8 +588,8 @@ string GetPlayerScoreString(entity pl, float shortString) } if(shortString < 1) for(i = 0; i < MAX_SCORE; ++i) - if(scores_flags[i] & SFL_SORT_PRIO_MASK != SFL_SORT_PRIO_PRIMARY) - if(scores_flags[i] & SFL_SORT_PRIO_MASK != SFL_SORT_PRIO_SECONDARY) + if((scores_flags[i] & SFL_SORT_PRIO_MASK) != SFL_SORT_PRIO_PRIMARY) + if((scores_flags[i] & SFL_SORT_PRIO_MASK) != SFL_SORT_PRIO_SECONDARY) { f = scores_flags[i]; l = scores_label[i]; @@ -585,16 +600,16 @@ string GetPlayerScoreString(entity pl, float shortString) else if((sk = pl.scorekeeper)) { for(i = 0; i < MAX_SCORE; ++i) - if(scores_flags[i] & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_PRIMARY) + if((scores_flags[i] & SFL_SORT_PRIO_MASK) == SFL_SORT_PRIO_PRIMARY) out = strcat(out, ftos(sk.(scores[i])), ","); if(shortString < 2) for(i = 0; i < MAX_SCORE; ++i) - if(scores_flags[i] & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_SECONDARY) + if((scores_flags[i] & SFL_SORT_PRIO_MASK) == SFL_SORT_PRIO_SECONDARY) out = strcat(out, ftos(sk.(scores[i])), ","); if(shortString < 1) for(i = 0; i < MAX_SCORE; ++i) - if(scores_flags[i] & SFL_SORT_PRIO_MASK != SFL_SORT_PRIO_PRIMARY) - if(scores_flags[i] & SFL_SORT_PRIO_MASK != SFL_SORT_PRIO_SECONDARY) + if((scores_flags[i] & SFL_SORT_PRIO_MASK) != SFL_SORT_PRIO_PRIMARY) + if((scores_flags[i] & SFL_SORT_PRIO_MASK) != SFL_SORT_PRIO_SECONDARY) out = strcat(out, ftos(sk.(scores[i])), ","); out = substring(out, 0, strlen(out) - 1); } @@ -612,25 +627,25 @@ string GetTeamScoreString(float tm, float shortString) if(tm == 0) { // label - for(i = 0; i < MAX_SCORE; ++i) - if(teamscores_flags[i] & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_PRIMARY) + for(i = 0; i < MAX_TEAMSCORE; ++i) + if((teamscores_flags[i] & SFL_SORT_PRIO_MASK) == SFL_SORT_PRIO_PRIMARY) { f = teamscores_flags[i]; l = teamscores_label[i]; out = strcat(out, GetScoreLogLabel(l, f), ","); } if(shortString < 2) - for(i = 0; i < MAX_SCORE; ++i) - if(teamscores_flags[i] & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_SECONDARY) + for(i = 0; i < MAX_TEAMSCORE; ++i) + if((teamscores_flags[i] & SFL_SORT_PRIO_MASK) == SFL_SORT_PRIO_SECONDARY) { f = teamscores_flags[i]; l = teamscores_label[i]; out = strcat(out, GetScoreLogLabel(l, f), ","); } if(shortString < 1) - for(i = 0; i < MAX_SCORE; ++i) - if(teamscores_flags[i] & SFL_SORT_PRIO_MASK != SFL_SORT_PRIO_PRIMARY) - if(teamscores_flags[i] & SFL_SORT_PRIO_MASK != SFL_SORT_PRIO_SECONDARY) + for(i = 0; i < MAX_TEAMSCORE; ++i) + if((teamscores_flags[i] & SFL_SORT_PRIO_MASK) != SFL_SORT_PRIO_PRIMARY) + if((teamscores_flags[i] & SFL_SORT_PRIO_MASK) != SFL_SORT_PRIO_SECONDARY) { f = teamscores_flags[i]; l = teamscores_label[i]; @@ -641,67 +656,73 @@ string GetTeamScoreString(float tm, float shortString) else if((sk = teamscorekeepers[tm - 1])) { for(i = 0; i < MAX_TEAMSCORE; ++i) - if(teamscores_flags[i] & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_PRIMARY) + if((teamscores_flags[i] & SFL_SORT_PRIO_MASK) == SFL_SORT_PRIO_PRIMARY) out = strcat(out, ftos(sk.(teamscores[i])), ","); if(shortString < 2) for(i = 0; i < MAX_TEAMSCORE; ++i) - if(teamscores_flags[i] & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_SECONDARY) + if((teamscores_flags[i] & SFL_SORT_PRIO_MASK) == SFL_SORT_PRIO_SECONDARY) out = strcat(out, ftos(sk.(teamscores[i])), ","); if(shortString < 1) for(i = 0; i < MAX_TEAMSCORE; ++i) - if(teamscores_flags[i] & SFL_SORT_PRIO_MASK != SFL_SORT_PRIO_PRIMARY) - if(teamscores_flags[i] & SFL_SORT_PRIO_MASK != SFL_SORT_PRIO_SECONDARY) + if((teamscores_flags[i] & SFL_SORT_PRIO_MASK) != SFL_SORT_PRIO_PRIMARY) + if((teamscores_flags[i] & SFL_SORT_PRIO_MASK) != SFL_SORT_PRIO_SECONDARY) out = strcat(out, ftos(sk.(teamscores[i])), ","); out = substring(out, 0, strlen(out) - 1); } return out; } -float PlayerTeamScore_Compare(entity p1, entity p2) +float PlayerTeamScore_Compare(entity p1, entity p2, float teams, float strict) { - if(teamscores_entities_count) + if(teams && teamscores_entities_count) + { if(p1.team != p2.team) { entity t1, t2; float r; t1 = teamscorekeepers[p1.team - 1]; t2 = teamscorekeepers[p2.team - 1]; - r = TeamScore_Compare(t1, t2); - if(r == 0) // ensure a deterministic order - r = p1.team - p2.team; + r = TeamScore_Compare(t1, t2, ((teams >= 0) ? 1 : strict)); return r; } - - return PlayerScore_Compare(p1.scorekeeper, p2.scorekeeper); + if(teams < 0) + return 0; + } + + return PlayerScore_Compare(p1.scorekeeper, p2.scorekeeper, strict); } -entity PlayerScore_Sort(.float field) +entity PlayerScore_Sort(.float field, float teams, float strict, float nospectators) { entity p, plist, pprev, pbest, pbestprev, pfirst, plast; - float i; + float i, j; plist = world; FOR_EACH_CLIENT(p) p.field = 0; - FOR_EACH_PLAYER(p) if(p.scorekeeper) + FOR_EACH_CLIENT(p) if(p.scorekeeper) { + if(nospectators) + if(p.frags == FRAGS_SPECTATOR) + continue; + p.chain = plist; plist = p; } // Now plist points to the whole list. - + pfirst = plast = world; - i = 0; + i = j = 0; while(plist) { pprev = pbestprev = world; pbest = plist; for(p = plist; (pprev = p), (p = p.chain); ) { - if(PlayerTeamScore_Compare(p, pbest) > 0) + if(PlayerTeamScore_Compare(p, pbest, teams, strict) > 0) { pbest = p; pbestprev = pprev; @@ -715,9 +736,13 @@ entity PlayerScore_Sort(.float field) pbestprev.chain = pbest.chain; pbest.chain = world; - pbest.field = ++i; + ++i; + if(!plast || PlayerTeamScore_Compare(plast, pbest, teams, 0)) + j = i; - if not(pfirst) + pbest.field = j; + + if (!pfirst) pfirst = pbest; if(plast) plast.chain = pbest; @@ -740,7 +765,7 @@ float TeamScore_GetCompareValue(float t) } sk = teamscorekeepers[t - 1]; - if not(sk) + if (!sk) return -999999999; s = sk.teamscores_primary; if(teamscores_flags_primary & SFL_ZERO_IS_WORST) @@ -775,7 +800,7 @@ void Score_NicePrint_Team(entity to, float t, float w) sk = teamscorekeepers[t - 1]; if(sk) { - s = strcat(s, ColoredTeamName(t)); + s = strcat(s, Team_ColoredFullName(t)); for(i = 0; i < MAX_TEAMSCORE; ++i) if(teamscores_label[i] != "") { @@ -788,7 +813,7 @@ void Score_NicePrint_Team(entity to, float t, float w) s = "Scores:"; s = strcat(s, strpad(max(0, NAMEWIDTH - strlennocol(s)), "")); - + for(i = 0; i < MAX_SCORE; ++i) if(scores_label[i] != "") { @@ -822,7 +847,7 @@ void Score_NicePrint_Player(entity to, entity p, float w) break; } } - + for(i = 0; i < MAX_SCORE; ++i) if(scores_label[i] != "") { @@ -857,7 +882,7 @@ void Score_NicePrint(entity to) ++t; w = bound(6, floor(SCORESWIDTH / t - 1), 9); - p = PlayerScore_Sort(score_dummyfield); + p = PlayerScore_Sort(score_dummyfield, 1, 1, 0); t = -1; if(!teamscores_entities_count) @@ -871,12 +896,12 @@ void Score_NicePrint(entity to) t = p.team; p = p.chain; } - + t = 0; FOR_EACH_CLIENT(p) - if(p.classname != "player") + if (!IS_PLAYER(p)) { - if not(t) + if (!t) Score_NicePrint_Spectators(to); Score_NicePrint_Spectator(to, p); t = 1; @@ -907,6 +932,7 @@ void PlayerScore_TeamStats(void) for(i = 0; i < MAX_TEAMSCORE; ++i) if(sk.(teamscores[i]) != 0) if(teamscores_label[i] != "") - PlayerStats_TeamScore(t, strcat(PLAYERSTATS_SCOREBOARD, teamscores_label[i]), sk.(teamscores[i])); + // the +1 is important here! + PlayerStats_TeamScore(t+1, strcat(PLAYERSTATS_SCOREBOARD, teamscores_label[i]), sk.(teamscores[i])); } }