]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/scores.qc
Transifex autosync
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / scores.qc
index 38fd7f40e16ee2a2c76d3db8bd476f08fcc7ed55..40bbec64424689f94e11551dbbc6e3c4b284c969 100644 (file)
@@ -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)));
                }
     });