X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fscores.qc;h=fd2c2cc55439e8dd09d8c2d3cf61f68e23d79f7d;hp=38fd7f40e16ee2a2c76d3db8bd476f08fcc7ed55;hb=HEAD;hpb=47d309fde9bbfd7b3cfdcdb0f98a48b94382907c diff --git a/qcsrc/server/scores.qc b/qcsrc/server/scores.qc index 38fd7f40e..40bbec644 100644 --- a/qcsrc/server/scores.qc +++ b/qcsrc/server/scores.qc @@ -23,36 +23,35 @@ var .float scores_primary; var .float teamscores_primary; float scores_flags_primary; float teamscores_flags_primary; +var .float scores_secondary; +float scores_flags_secondary; -vector ScoreField_Compare(entity t1, entity t2, .float field, float fieldflags, vector previous, bool strict) // returns: cmp value, best prio +// returns cmp value +int ScoreField_Compare(entity t1, entity t2, .float field, float fieldflags, int previous) { - if(!strict && !(fieldflags & SFL_SORT_PRIO_MASK)) // column does not sort - return previous; - if((fieldflags & SFL_SORT_PRIO_MASK) < previous.y) + if(fieldflags & SFL_NOT_SORTABLE) // column does not sort return previous; if (t1.(field) == t2.(field)) return previous; - previous.y = fieldflags & SFL_SORT_PRIO_MASK; - if(fieldflags & SFL_ZERO_IS_WORST) { if (t1.(field) == 0) { - previous.x = -1; + previous = -1; return previous; } else if (t2.(field) == 0) { - previous.x = +1; + previous = +1; return previous; } } if (fieldflags & SFL_LOWER_IS_BETTER) - previous.x = (t2.(field) - t1.(field)); + previous = (t2.(field) - t1.(field)); else - previous.x = (t1.(field) - t2.(field)); + previous = (t1.(field) - t2.(field)); return previous; } @@ -139,23 +138,28 @@ float TeamScore_Add(entity player, float scorefield, float score) return TeamScore_AddToTeam(player.team, scorefield, score); } -float TeamScore_Compare(entity t1, entity t2, bool strict) +// strict: compare others fields too besides primary and secondary +int TeamScore_Compare(entity t1, entity t2, bool strict) { if(!t1 || !t2) return (!t2) - !t1; - vector result = '0 0 0'; - float i; - for(i = 0; i < MAX_TEAMSCORE; ++i) + // supporting MAX_TEAMSCORE > 2 requires keeping track of primary and secondary teamscore + if (MAX_TEAMSCORE > 2) + error("MAX_TEAMSCORE > 2 not supported"); + + // first compare primary, then others (don't check secondary flag since there are only 2 teamscores) + int result = 0; + int i = boolean(teamscores_primary && teamscores_primary == teamscores(1)); + result = ScoreField_Compare(t1, t2, teamscores(i), teamscores_flags(i), result); + if (result == 0 && strict) { - var .float f; - f = teamscores(i); - result = ScoreField_Compare(t1, t2, f, teamscores_flags(i), result, strict); + i = (i + 1) % MAX_TEAMSCORE; + result = ScoreField_Compare(t1, t2, teamscores(i), teamscores_flags(i), result); + if (result == 0) + result = t1.team - t2.team; } - if (result.x == 0 && strict) - result.x = t1.team - t2.team; - - return result.x; + return result; } /* @@ -171,6 +175,11 @@ void ScoreInfo_SetLabel_PlayerScore(PlayerScoreField i, string label, float scor scores_primary = scores(i); scores_flags_primary = scoreflags; } + else if((scoreflags & SFL_SORT_PRIO_MASK) == SFL_SORT_PRIO_SECONDARY) + { + scores_secondary = scores(i); + scores_flags_secondary = scoreflags; + } if(label != "") { PlayerStats_GameReport_AddEvent(strcat(PLAYERSTATS_TOTAL, label)); @@ -194,12 +203,15 @@ void ScoreInfo_SetLabel_TeamScore(float i, string label, float scoreflags) } } -.bool welcome_msg_already_sent_on_connection; bool ScoreInfo_SendEntity(entity this, entity to, int sf) { float i; WriteHeader(MSG_ENTITY, ENT_CLIENT_SCORES_INFO); WriteRegistered(Gametypes, MSG_ENTITY, MapInfo_LoadedGametype); + string gt_name = ""; + if (loaded_gametype_custom_string != "") + gt_name = cvar_string(strcat("sv_vote_gametype_", loaded_gametype_custom_string, "_name")); + WriteString(MSG_ENTITY, gt_name); FOREACH(Scores, true, { WriteString(MSG_ENTITY, scores_label(it)); WriteByte(MSG_ENTITY, scores_flags(it)); @@ -209,14 +221,13 @@ bool ScoreInfo_SendEntity(entity this, entity to, int sf) WriteString(MSG_ENTITY, teamscores_label(i)); WriteByte(MSG_ENTITY, teamscores_flags(i)); } - bool welcome_msg_too = (!to.welcome_msg_already_sent_on_connection); + // prevent sending the welcome message again when score types are sent again because the scoring system has changed + // it can happen in some game modes like Race when the qualyfing session ends and the race starts + bool welcome_msg_too = (!CS(to) || time < CS(to).jointime + 5); WriteByte(MSG_ENTITY, welcome_msg_too); // welcome message is sent here because it needs to know the gametype if (welcome_msg_too) - { - SendWelcomemessage_msg_type(this, false, MSG_ENTITY); - to.welcome_msg_already_sent_on_connection = true; - } + SendWelcomeMessage(to, MSG_ENTITY); return true; } @@ -405,27 +416,39 @@ float PlayerTeamScore_Add(entity player, PlayerScoreField pscorefield, float tsc return r; } +// strict: compare others fields too besides primary and secondary float PlayerScore_Compare(entity t1, entity t2, bool strict) { if(!t1 || !t2) return (!t2) - !t1; - vector result = '0 0 0'; - FOREACH(Scores, true, { - var .float f = scores(it); - result = ScoreField_Compare(t1, t2, f, scores_flags(it), result, strict); - }); + int result = 0; + result = ScoreField_Compare(t1, t2, scores_primary, scores_flags_primary, result); + // NOTE: if (scores_secondary) doesn't work because it's a field pointer + if (result == 0 && scores_flags_secondary) + result = ScoreField_Compare(t1, t2, scores_secondary, scores_flags_secondary, result); - if (result.x == 0 && strict) - result.x = t1.owner.playerid - t2.owner.playerid; + if (result == 0 && strict) + { + FOREACH(Scores, true, { + if (scores_flags(it) & SFL_SORT_PRIO_MASK) + continue; + if (scores_label(it) == "") + continue; + var .float f = scores(it); + result = ScoreField_Compare(t1, t2, f, scores_flags(it), result); + if (result) break; + }); + if (result == 0) + result = t1.owner.playerid - t2.owner.playerid; + } - return result.x; + return result; } void WinningConditionHelper(entity this) { float c; string s; - float fullstatus; entity winnerscorekeeper; entity secondscorekeeper; entity sk; @@ -436,16 +459,17 @@ void WinningConditionHelper(entity this) // 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(this, NULL))); - s = strcat(s, ":F", ftos(serverflags)); - s = strcat(s, ":T", sv_termsofservice_url_escaped); - s = strcat(s, ":M", modname); - s = strcat(s, "::", GetPlayerScoreString(NULL, (fullstatus ? 1 : 2))); + // NOTE can't use a single strcat because strcat concatenates max 8 strings + s = strcat(GetGametype(), + ":", autocvar_g_xonoticversion, + ":P", ftos(cvar_purechanges_count), + ":S", ftos(nJoinAllowed(this, NULL))); + s = strcat(s, + ":F", ftos(serverflags), + ":T", sv_termsofservice_url_escaped, + ":M", modname); + s = strcat(s, + "::", GetPlayerScoreString(NULL, (autocvar_g_full_getstatus_responses ? 1 : 2))); if(teamscores_entities_count) { @@ -463,7 +487,7 @@ void WinningConditionHelper(entity this) for(t = 0; t < 16; ++t) { sk = teamscorekeepers[t]; - c = TeamScore_Compare(winnerscorekeeper, sk, 1); + c = TeamScore_Compare(winnerscorekeeper, sk, true); if(c < 0) { WinningConditionHelper_secondteam = WinningConditionHelper_winnerteam; @@ -473,7 +497,7 @@ void WinningConditionHelper(entity this) } else { - c = TeamScore_Compare(secondscorekeeper, sk, 1); + c = TeamScore_Compare(secondscorekeeper, sk, true); if(c < 0) { WinningConditionHelper_secondteam = t + 1; @@ -482,7 +506,7 @@ void WinningConditionHelper(entity this) } } - WinningConditionHelper_equality = (TeamScore_Compare(winnerscorekeeper, secondscorekeeper, 0) == 0); + WinningConditionHelper_equality = (TeamScore_Compare(winnerscorekeeper, secondscorekeeper, false) == 0); if(WinningConditionHelper_equality) WinningConditionHelper_winnerteam = WinningConditionHelper_secondteam = -1; @@ -558,11 +582,12 @@ void WinningConditionHelper(entity this) } } - strcpy(worldstatus, s); + if (s != worldstatus) + strcpy(worldstatus, s); FOREACH_CLIENT(true, { string s = ""; - if(fullstatus) + if(autocvar_g_full_getstatus_responses) { s = GetPlayerScoreString(it, 1); s = strcat(s, IS_REAL_CLIENT(it) ? ":human" : ":bot"); @@ -577,7 +602,8 @@ void WinningConditionHelper(entity this) s = "-666"; } - strcpy(it.clientstatus, s); + if (s != it.clientstatus) + strcpy(it.clientstatus, s); }); } @@ -710,7 +736,8 @@ string GetTeamScoreString(float tm, float shortString) return out; } -float PlayerTeamScore_Compare(entity p1, entity p2, float teams, bool strict) +// strict: compare others fields too besides primary and secondary +int PlayerTeamScore_Compare(entity p1, entity p2, float teams, bool strict) { if(teams && teamscores_entities_count) { @@ -843,7 +870,7 @@ void Score_NicePrint_Team(entity to, float t, float w) { fl = teamscores_flags(i); sc = sk.(teamscores(i)); - s = strcat(s, " ", Score_NicePrint_ItemColor(fl), ScoreString(fl, sc)); + s = strcat(s, " ", Score_NicePrint_ItemColor(fl), ScoreString(fl, sc, 0)); } } else @@ -891,7 +918,7 @@ void Score_NicePrint_Player(entity to, entity p, float w) { fl = scores_flags(it); sc = sk.(scores(it)); - s = strcat(s, " ", Score_NicePrint_ItemColor(fl), strpad(-w, ScoreString(fl, sc))); + s = strcat(s, " ", Score_NicePrint_ItemColor(fl), strpad(-w, ScoreString(fl, sc, 0))); } });