#define MAX_SCORE 64
#define REGISTER_SP(id) REGISTER(Scores, SP, id, m_id, new_pure(PlayerScoreField))
-REGISTRY(Scores, MAX_SCORE);
+REGISTRY(Scores, MAX_SCORE)
REGISTER_REGISTRY(Scores)
-REGISTRY_SORT(Scores);
-REGISTRY_CHECK(Scores);
+// do not sort alphabetically, player sort priority is based on score registration order
+//REGISTRY_SORT(Scores)
+REGISTRY_CHECK(Scores)
REGISTRY_DEFINE_GET(Scores, NULL)
STATIC_INIT(Scores_renumber) { FOREACH(Scores, true, it.m_id = i); }
/*
* Score indices
*/
-
-// game mode specific indices are not in common/, but in server/scores_rules.qc!
#ifdef GAMEQC
-REGISTER_SP(END);
-
-REGISTER_SP(PING);
-REGISTER_SP(PL);
-REGISTER_SP(NAME);
-REGISTER_SP(KDRATIO);
-REGISTER_SP(SUM);
-
-REGISTER_SP(SEPARATOR);
-
-REGISTER_SP(SCORE);
-
-REGISTER_SP(DMG);
-REGISTER_SP(DMGTAKEN);
-
-REGISTER_SP(KILLS);
-REGISTER_SP(DEATHS);
-REGISTER_SP(SUICIDES);
-REGISTER_SP(TEAMKILLS);
-REGISTER_SP(FRAGS);
-
-REGISTER_SP(ELO);
+// networked fields
+// NOTE: score registration order is used as player sort priority (after primary and secondary)
-REGISTER_SP(FPS);
+// TODO: move gamemode scores to gamemode files
+// TODO: allow gamemodes to fully customize player sorting priority, even the common ones
-// TODO: move to common mutators
-
-REGISTER_SP(RACE_TIME);
REGISTER_SP(RACE_LAPS);
+REGISTER_SP(RACE_TIME);
REGISTER_SP(RACE_FASTEST);
-//REGISTER_SP(CTS_TIME);
-//REGISTER_SP(CTS_LAPS);
-//REGISTER_SP(CTS_FASTEST);
-
REGISTER_SP(ASSAULT_OBJECTIVES);
-REGISTER_SP(CTF_PICKUPS);
+REGISTER_SP(CTF_CAPS);
REGISTER_SP(CTF_FCKILLS);
REGISTER_SP(CTF_RETURNS);
-REGISTER_SP(CTF_CAPS);
-REGISTER_SP(CTF_CAPTIME);
REGISTER_SP(CTF_DROPS);
+REGISTER_SP(CTF_PICKUPS);
+REGISTER_SP(CTF_CAPTIME);
REGISTER_SP(DOM_TAKES);
REGISTER_SP(DOM_TICKS);
REGISTER_SP(FREEZETAG_REVIVALS);
-REGISTER_SP(KEEPAWAY_PICKUPS);
REGISTER_SP(KEEPAWAY_BCTIME);
REGISTER_SP(KEEPAWAY_CARRIERKILLS);
+REGISTER_SP(KEEPAWAY_PICKUPS);
-REGISTER_SP(KH_PICKUPS);
REGISTER_SP(KH_CAPS);
REGISTER_SP(KH_KCKILLS);
-REGISTER_SP(KH_PUSHES);
-REGISTER_SP(KH_DESTROYS);
REGISTER_SP(KH_LOSSES);
+REGISTER_SP(KH_DESTROYS);
+REGISTER_SP(KH_PUSHES);
+REGISTER_SP(KH_PICKUPS);
REGISTER_SP(LMS_RANK);
REGISTER_SP(LMS_LIVES);
REGISTER_SP(NEXBALL_GOALS);
REGISTER_SP(NEXBALL_FAULTS);
-REGISTER_SP(ONS_TAKES);
REGISTER_SP(ONS_CAPS);
+REGISTER_SP(ONS_TAKES);
+
+REGISTER_SP(TKA_PICKUPS);
+REGISTER_SP(TKA_BCTIME);
+REGISTER_SP(TKA_CARRIERKILLS);
+
+REGISTER_SP(SURV_SURVIVALS);
+REGISTER_SP(SURV_HUNTS);
+
+REGISTER_SP(SCORE);
+REGISTER_SP(KILLS);
+REGISTER_SP(DEATHS);
+REGISTER_SP(TEAMKILLS);
+REGISTER_SP(SUICIDES);
+REGISTER_SP(DMG);
+REGISTER_SP(DMGTAKEN);
+
+REGISTER_SP(ROUNDS_PL);
+
+REGISTER_SP(ELO); // not sortable
+REGISTER_SP(FPS); // not sortable
+
+// fields not networked via the score system
+REGISTER_SP(END);
+
+REGISTER_SP(PING);
+REGISTER_SP(PL);
+REGISTER_SP(NAME);
+REGISTER_SP(SEPARATOR);
+
+REGISTER_SP(KDRATIO); // kills / deaths
+REGISTER_SP(SUM); // kills - deaths
+REGISTER_SP(FRAGS); // kills - suicides
#endif
*/
const int SFL_TIME = BIT(6);
+const int SFL_NOT_SORTABLE = BIT(7); // don't sort by this field
+
// not an extra constant yet
#define SFL_ZERO_IS_WORST SFL_TIME
/**
* Scoring priority (NOTE: PRIMARY is used for fraglimit)
+ * NOTE: SFL_SORT_PRIO_SECONDARY value must be lower than SFL_SORT_PRIO_PRIMARY's
*/
-const int SFL_SORT_PRIO_SECONDARY = 4;
-const int SFL_SORT_PRIO_PRIMARY = 8;
-const int SFL_SORT_PRIO_MASK = 12;
+const int SFL_SORT_PRIO_SECONDARY = BIT(2);
+const int SFL_SORT_PRIO_PRIMARY = BIT(3);
+const int SFL_SORT_PRIO_MASK = SFL_SORT_PRIO_PRIMARY | SFL_SORT_PRIO_SECONDARY;
#define IS_INCREASING(x) ( (x) & SFL_LOWER_IS_BETTER )
#define IS_DECREASING(x) ( !((x) & SFL_LOWER_IS_BETTER) )