]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into Juhu/scoreboard-strafe Juhu/scoreboard-strafe
authorJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Thu, 22 Jun 2023 01:47:43 +0000 (03:47 +0200)
committerJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Thu, 22 Jun 2023 01:47:43 +0000 (03:47 +0200)
Fixed merge conflict caused by new SCO_LABEL macro

1  2 
.gitlab-ci.yml
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/common/scores.qh

diff --combined .gitlab-ci.yml
index 6f5c8c2d5bb6a40f15d3c19c26b6b64e4a88c976,5637179f1953643a4cbb29999eaa708d710038b1..5af7d56d147d1570d3be94d65115d859ea1e3522
- workflow:\r
-   rules:\r
-     - if: $CI_COMMIT_MESSAGE =~ /Transifex autosync/\r
-       when: never\r
-     - when: always\r
\r
- before_script:\r
-   - ln -s $PWD data/xonotic-data.pk3dir\r
\r
-   - export MAKEFLAGS=-j$(nproc); echo MAKEFLAGS=$MAKEFLAGS\r
- #   FIXME: -march=native -mtune=native _changes the hash_, why?!?\r
- # - export CC="gcc -pipe -march=native -mtune=native"\r
-   - export CC="gcc -pipe"\r
\r
-   - >\r
-     if wget -nv https://beta.xonotic.org/pipeline-bin/gmqcc ; then\r
-       export QCC="$PWD/gmqcc"\r
-       chmod +x "$QCC"\r
-     else\r
-       git clone --depth=1 --branch=main https://gitlab.com/xonotic/gmqcc.git gmqcc\r
-       make -C gmqcc || exit 1\r
-       export QCC="$PWD/gmqcc/gmqcc"\r
-     fi\r
\r
-   # Makefile: don't complain about lack of tags (fetching them is slow)\r
-   - export QCCFLAGS_WATERMARK=gitlab_pipeline\r
-   # Makefile: don't compress anything or complain about lack of zip program\r
-   - export ZIP=/bin/true\r
\r
- test_compilation_units:\r
-   rules:\r
-     - changes:\r
-       - qcsrc/**/*\r
-   stage: test\r
-   script:\r
-     - make test\r
\r
- test_sv_game:\r
-   stage: test\r
-   script:\r
-     - >\r
-       if wget -nv https://beta.xonotic.org/pipeline-bin/xonotic-linux64-dedicated ; then\r
-         export ENGINE="$PWD/xonotic-linux64-dedicated"\r
-         chmod +x "$ENGINE"\r
-       else\r
-         git clone --depth=1 --branch=div0-stable https://gitlab.com/xonotic/darkplaces.git darkplaces\r
-         make -C darkplaces sv-release || exit 1\r
-         export ENGINE="$PWD/darkplaces/darkplaces-dedicated -xonotic"\r
-       fi\r
-     - export ENGINE="$ENGINE -noconfig -nohome"\r
\r
-     - make qc || exit 1\r
\r
-     - mkdir -p data/maps\r
-     - wget -nv -O data/maps/_init.bsp https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/_init/_init.bsp\r
\r
-     - while read LINE; do\r
-         echo $LINE;\r
-         [ "$LINE" = "All tests OK" ] && PASS=1;\r
-       done < <(${ENGINE} +developer 1 +map _init +sv_cmd runtest +wait +quit)\r
-     - test "$PASS" = "1" || { echo 'sv_cmd runtest failed!'; exit 1; }\r
\r
-     - ${ENGINE} +map _init +sv_cmd dumpnotifs +wait +quit\r
-     - diff notifications.cfg data/data/notifications_dump.cfg ||\r
-         { echo 'Please update notifications.cfg using `dumpnotifs`!'; exit 1; }\r
\r
- #    - wget -nv -O data/stormkeep.pk3 http://beta.xonotic.org/autobuild-bsp/latest/stormkeep.pk3\r
- # ^^ INCORRECT: /latest/stormkeep.pk3 is the most recently built, not necessarily the one built from master!\r
- # we can't get the one from master directly as there's no /stable/stormkeep.pk3 or /master/stormkeep.pk3\r
- # and we can't run misc/tools/xonotic-map-compiler-autobuild as it uses commit hashes from xonotic-maps.pk3dir to generate filenames\r
- # but the autobuild server can run it and provide us the resulting pk3:\r
-     - wget -nv -O data/stormkeep.pk3 https://beta.xonotic.org/pipeline-bin/stormkeep.pk3\r
- # see also: misc/infrastructure/xonotic-release-build.cron\r
-     - wget -nv -O data/maps/stormkeep.mapinfo https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.mapinfo\r
-     - wget -nv -O data/maps/stormkeep.waypoints https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints\r
-     - wget -nv -O data/maps/stormkeep.waypoints.cache https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints.cache\r
\r
-     - EXPECT=3db0ae13a7c4437997f04036773b6b3e\r
-     - HASH=$(${ENGINE} +timestamps 1 +exec serverbench.cfg\r
-       | tee /dev/stderr\r
-       | sed -e 's,^\[[^]]*\] ,,'\r
-       | grep '^:'\r
-       | grep -v '^:gamestart:'\r
-       | grep -v '^:anticheat:'\r
-       | md5sum | awk '{ print $1 }')\r
-     - echo 'expected:' $EXPECT\r
-     - echo '  actual:' $HASH\r
-     - test "$HASH" == "$EXPECT"\r
-     - exit $?\r
\r
\r
- # NOTE: The generated docs are incomplete - they don't contain code behind SVQC CSQC MENUQC GAMEQC ifdefs.\r
- # With them added to PREDEFINED, it would take over half an hour to generate the docs and even then\r
- # they might not be complete. Doxygen doesn't handle #elif and might not understand some QC definitions.\r
- #doxygen:  # rename to 'pages' when gitlab.com allows pages to exceed 100MiB\r
- #  before_script:\r
- #    - ln -s $PWD data/xonotic-data.pk3dir # is this needed?\r
- #    - apt-get update\r
- #    - apt-get -y install doxygen graphviz\r
- #  stage: deploy\r
- #  script:\r
- #    - cd qcsrc && doxygen\r
- #    - mv html ../public\r
- #    - mkdir -p ~/.ssh\r
- #    - for i in {0..0}; do eval $(printf "echo \$id_rsa_%02d\n" $i) >> ~/.ssh/id_rsa_base64; done\r
- #    - base64 --decode ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa\r
- #    - chmod 600 ~/.ssh/id_rsa\r
- #    - echo -e "Host *\n\tStrictHostKeyChecking no\n\tLogLevel ERROR\n" >> ~/.ssh/config\r
- #    - git config --global user.name "Gitlab CI"\r
- #    - git config --global user.email "<>"\r
- #    - git clone --single-branch --depth 1 ${DEPLOY_HOST}:${DEPLOY_REPO} ~/deploy_\r
- #    - mkdir ~/deploy && mv ~/deploy_/.git ~/deploy && rm -r ~/deploy_\r
- #    - cp -r ../public/* ~/deploy\r
- #    - cd ~/deploy && git add -A . && git commit -m "Deploy ${CI_BUILD_REF}" && git push origin gh-pages\r
- #  artifacts:\r
- #    paths:\r
- #      - public\r
- #  only:\r
- #    - master\r
+ workflow:
+   rules:
+     - if: $CI_COMMIT_MESSAGE =~ /Transifex autosync/
+       when: never
+     - when: always
+ before_script:
+   - ln -s $PWD data/xonotic-data.pk3dir
+   - export MAKEFLAGS=-j$(nproc); echo MAKEFLAGS=$MAKEFLAGS
+ #   FIXME: -march=native -mtune=native _changes the hash_, why?!?
+ # - export CC="gcc -pipe -march=native -mtune=native"
+   - export CC="gcc -pipe"
+   - >
+     if wget -nv https://beta.xonotic.org/pipeline-bin/gmqcc ; then
+       export QCC="$PWD/gmqcc"
+       chmod +x "$QCC"
+     else
+       git clone --depth=1 --branch=main https://gitlab.com/xonotic/gmqcc.git gmqcc
+       make -C gmqcc || exit 1
+       export QCC="$PWD/gmqcc/gmqcc"
+     fi
+   # Makefile: don't complain about lack of tags (fetching them is slow)
+   - export QCCFLAGS_WATERMARK=gitlab_pipeline
+   # Makefile: don't compress anything or complain about lack of zip program
+   - export ZIP=/bin/true
+ test_compilation_units:
+   rules:
+     - changes:
+       - qcsrc/**/*
+   stage: test
+   script:
+     - make test
+ test_sv_game:
+   stage: test
+   script:
+     - >
+       if wget -nv https://beta.xonotic.org/pipeline-bin/xonotic-linux64-dedicated ; then
+         export ENGINE="$PWD/xonotic-linux64-dedicated"
+         chmod +x "$ENGINE"
+       else
+         git clone --depth=1 --branch=div0-stable https://gitlab.com/xonotic/darkplaces.git darkplaces
+         make -C darkplaces sv-release || exit 1
+         export ENGINE="$PWD/darkplaces/darkplaces-dedicated -xonotic"
+       fi
+     - export ENGINE="$ENGINE -noconfig -nohome"
+     - make qc || exit 1
+     - mkdir -p data/maps
+     - wget -nv -O data/maps/_init.bsp https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/_init/_init.bsp
+     - while read LINE; do
+         echo $LINE;
+         [ "$LINE" = "All tests OK" ] && PASS=1;
+       done < <(${ENGINE} +developer 1 +map _init +sv_cmd runtest +wait +quit)
+     - test "$PASS" = "1" || { echo 'sv_cmd runtest failed!'; exit 1; }
+     - ${ENGINE} +map _init +sv_cmd dumpnotifs +wait +quit
+     - diff notifications.cfg data/data/notifications_dump.cfg ||
+         { echo 'Please update notifications.cfg using `dumpnotifs`!'; exit 1; }
+ #    - wget -nv -O data/stormkeep.pk3 http://beta.xonotic.org/autobuild-bsp/latest/stormkeep.pk3
+ # ^^ INCORRECT: /latest/stormkeep.pk3 is the most recently built, not necessarily the one built from master!
+ # we can't get the one from master directly as there's no /stable/stormkeep.pk3 or /master/stormkeep.pk3
+ # and we can't run misc/tools/xonotic-map-compiler-autobuild as it uses commit hashes from xonotic-maps.pk3dir to generate filenames
+ # but the autobuild server can run it and provide us the resulting pk3:
+     - wget -nv -O data/stormkeep.pk3 https://beta.xonotic.org/pipeline-bin/stormkeep.pk3
+ # see also: misc/infrastructure/xonotic-release-build.cron
+     - wget -nv -O data/maps/stormkeep.mapinfo https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.mapinfo
+     - wget -nv -O data/maps/stormkeep.waypoints https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints
+     - wget -nv -O data/maps/stormkeep.waypoints.cache https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints.cache
 -    - EXPECT=57325fe74835910e451ba42d31de8f34
++    - EXPECT=0697ef57c3dca0ff122074b29495c5da
+     - HASH=$(${ENGINE} +exec serverbench.cfg
+       | tee /dev/stderr
+       | grep '^:'
+       | grep -v '^:gamestart:'
+       | grep -v '^:anticheat:'
+       | md5sum | awk '{ print $1 }')
+     - echo 'expected:' $EXPECT
+     - echo '  actual:' $HASH
+     - test "$HASH" == "$EXPECT"
+     - exit $?
+ # NOTE: The generated docs are incomplete - they don't contain code behind SVQC CSQC MENUQC GAMEQC ifdefs.
+ # With them added to PREDEFINED, it would take over half an hour to generate the docs and even then
+ # they might not be complete. Doxygen doesn't handle #elif and might not understand some QC definitions.
+ #doxygen:  # rename to 'pages' when gitlab.com allows pages to exceed 100MiB
+ #  before_script:
+ #    - ln -s $PWD data/xonotic-data.pk3dir # is this needed?
+ #    - apt-get update
+ #    - apt-get -y install doxygen graphviz
+ #  stage: deploy
+ #  script:
+ #    - cd qcsrc && doxygen
+ #    - mv html ../public
+ #    - mkdir -p ~/.ssh
+ #    - for i in {0..0}; do eval $(printf "echo \$id_rsa_%02d\n" $i) >> ~/.ssh/id_rsa_base64; done
+ #    - base64 --decode ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
+ #    - chmod 600 ~/.ssh/id_rsa
+ #    - echo -e "Host *\n\tStrictHostKeyChecking no\n\tLogLevel ERROR\n" >> ~/.ssh/config
+ #    - git config --global user.name "Gitlab CI"
+ #    - git config --global user.email "<>"
+ #    - git clone --single-branch --depth 1 ${DEPLOY_HOST}:${DEPLOY_REPO} ~/deploy_
+ #    - mkdir ~/deploy && mv ~/deploy_/.git ~/deploy && rm -r ~/deploy_
+ #    - cp -r ../public/* ~/deploy
+ #    - cd ~/deploy && git add -A . && git commit -m "Deploy ${CI_BUILD_REF}" && git push origin gh-pages
+ #  artifacts:
+ #    paths:
+ #      - public
+ #  only:
+ #    - master
index d22dc5f0994933da77e86643f97b5f4fdbc5b014,35227ffab524c63bb077dfb624b4005f19ed4032..f3b1091bde9a1721dff195148af74fbdf09ca94c
@@@ -106,9 -106,16 +106,16 @@@ float autocvar_hud_panel_scoreboard_min
  bool autocvar_hud_panel_scoreboard_playerid = false;
  string autocvar_hud_panel_scoreboard_playerid_prefix = "#";
  string autocvar_hud_panel_scoreboard_playerid_suffix = " ";
+ bool autocvar_hud_panel_scoreboard_scores_per_round;
  
  float scoreboard_time;
  
+ SHUTDOWN(scoreboard)
+ {
+       if(autocvar_hud_panel_scoreboard_scores_per_round)
+               cvar_set("hud_panel_scoreboard_scores_per_round", "0");
+ }
  // mode 0: returns translated label
  // mode 1: prints name and description of all the labels
  string Label_getInfo(string label, int mode)
        if (mode == 1)
                label = "bckills"; // first case in the switch
  
+ #define SCO_LABEL(strlabel, label, padding, help) \
+       case label: \
+               if (!mode) \
+                       return CTX(strlabel); \
+               LOG_HELP("^3", label, padding, "^7", help);
        switch(label)
        {
-               case "bckills":      if (!mode) return CTX(_("SCO^bckills"));      else LOG_HELP(strcat("^3", "bckills", "            ^7", _("Number of ball carrier kills")));
-               case "bctime":       if (!mode) return CTX(_("SCO^bctime"));       else LOG_HELP(strcat("^3", "bctime", "             ^7", _("Total amount of time holding the ball in Keepaway")));
-               case "caps":         if (!mode) return CTX(_("SCO^caps"));         else LOG_HELP(strcat("^3", "caps", "               ^7", _("How often a flag (CTF) or a key (KeyHunt) was captured")));
-               case "captime":      if (!mode) return CTX(_("SCO^captime"));      else LOG_HELP(strcat("^3", "captime", "            ^7", _("Time of fastest capture (CTF)")));
-               case "deaths":       if (!mode) return CTX(_("SCO^deaths"));       else LOG_HELP(strcat("^3", "deaths", "             ^7", _("Number of deaths")));
-               case "destroyed":    if (!mode) return CTX(_("SCO^destroyed"));    else LOG_HELP(strcat("^3", "destroyed", "          ^7", _("Number of keys destroyed by pushing them into void")));
-               case "dmg":          if (!mode) return CTX(_("SCO^damage"));       else LOG_HELP(strcat("^3", "dmg", "                ^7", _("The total damage done")));
-               case "dmgtaken":     if (!mode) return CTX(_("SCO^dmgtaken"));     else LOG_HELP(strcat("^3", "dmgtaken", "           ^7", _("The total damage taken")));
-               case "drops":        if (!mode) return CTX(_("SCO^drops"));        else LOG_HELP(strcat("^3", "drops", "              ^7", _("Number of flag drops")));
-               case "elo":          if (!mode) return CTX(_("SCO^elo"));          else LOG_HELP(strcat("^3", "elo", "                ^7", _("Player ELO")));
-               case "fastest":      if (!mode) return CTX(_("SCO^fastest"));      else LOG_HELP(strcat("^3", "fastest", "            ^7", _("Time of fastest lap (Race/CTS)")));
-               case "faults":       if (!mode) return CTX(_("SCO^faults"));       else LOG_HELP(strcat("^3", "faults", "             ^7", _("Number of faults committed")));
-               case "fckills":      if (!mode) return CTX(_("SCO^fckills"));      else LOG_HELP(strcat("^3", "fckills", "            ^7", _("Number of flag carrier kills")));
-               case "fps":          if (!mode) return CTX(_("SCO^fps"));          else LOG_HELP(strcat("^3", "fps", "                ^7", _("FPS")));
-               case "frags":        if (!mode) return CTX(_("SCO^frags"));        else LOG_HELP(strcat("^3", "frags", "              ^7", _("Number of kills minus suicides")));
-               case "goals":        if (!mode) return CTX(_("SCO^goals"));        else LOG_HELP(strcat("^3", "goals", "              ^7", _("Number of goals scored")));
-               case "kckills":      if (!mode) return CTX(_("SCO^kckills"));      else LOG_HELP(strcat("^3", "kckills", "            ^7", _("Number of keys carrier kills")));
-               case "kd":           if (!mode) return CTX(_("SCO^k/d"));          else LOG_HELP(strcat("^3", "kd", "                 ^7", _("The kill-death ratio")));
-               case "kdr":          if (!mode) return CTX(_("SCO^kdr"));          else LOG_HELP(strcat("^3", "kdr", "                ^7", _("The kill-death ratio")));
-               case "kdratio":      if (!mode) return CTX(_("SCO^kdratio"));      else LOG_HELP(strcat("^3", "kdratio", "            ^7", _("The kill-death ratio")));
-               case "kills":        if (!mode) return CTX(_("SCO^kills"));        else LOG_HELP(strcat("^3", "kills", "              ^7", _("Number of kills")));
-               case "laps":         if (!mode) return CTX(_("SCO^laps"));         else LOG_HELP(strcat("^3", "laps", "               ^7", _("Number of laps finished (Race/CTS)")));
-               case "lives":        if (!mode) return CTX(_("SCO^lives"));        else LOG_HELP(strcat("^3", "lives", "              ^7", _("Number of lives (LMS)")));
-               case "losses":       if (!mode) return CTX(_("SCO^losses"));       else LOG_HELP(strcat("^3", "losses", "             ^7", _("Number of times a key was lost")));
-               case "name":         if (!mode) return CTX(_("SCO^name"));         else LOG_HELP(strcat("^3", "name", "               ^7", _("Player name")));
-               case "nick":         if (!mode) return CTX(_("SCO^nick"));         else LOG_HELP(strcat("^3", "nick", "               ^7", _("Player name")));
-               case "objectives":   if (!mode) return CTX(_("SCO^objectives"));   else LOG_HELP(strcat("^3", "objectives", "         ^7", _("Number of objectives destroyed")));
-               case "pickups":      if (!mode) return CTX(_("SCO^pickups"));      else LOG_HELP(strcat("^3", "pickups", "            ^7", _("How often a flag (CTF) or a key (KeyHunt) or a ball (Keepaway) was picked up")));
-               case "ping":         if (!mode) return CTX(_("SCO^ping"));         else LOG_HELP(strcat("^3", "ping", "               ^7", _("Ping time")));
-               case "pl":           if (!mode) return CTX(_("SCO^pl"));           else LOG_HELP(strcat("^3", "pl", "                 ^7", _("Packet loss")));
-               case "pushes":       if (!mode) return CTX(_("SCO^pushes"));       else LOG_HELP(strcat("^3", "pushes", "             ^7", _("Number of players pushed into void")));
-               case "rank":         if (!mode) return CTX(_("SCO^rank"));         else LOG_HELP(strcat("^3", "rank", "               ^7", _("Player rank")));
-               case "returns":      if (!mode) return CTX(_("SCO^returns"));      else LOG_HELP(strcat("^3", "returns", "            ^7", _("Number of flag returns")));
-               case "revivals":     if (!mode) return CTX(_("SCO^revivals"));     else LOG_HELP(strcat("^3", "revivals", "           ^7", _("Number of revivals")));
-               case "rounds":       if (!mode) return CTX(_("SCO^rounds won"));   else LOG_HELP(strcat("^3", "rounds", "             ^7", _("Number of rounds won")));
-               case "score":        if (!mode) return CTX(_("SCO^score"));        else LOG_HELP(strcat("^3", "score", "              ^7", _("Total score")));
-               case "avgspeed":     if (!mode) return CTX(_("SCO^average speed"));else LOG_HELP(strcat("^3", "avgspeed", "           ^7", _("Average speed (CTS)")));
-               case "topspeed":     if (!mode) return CTX(_("SCO^top speed"));    else LOG_HELP(strcat("^3", "topspeed", "           ^7", _("Top speed (CTS)")));
-               case "startspeed":   if (!mode) return CTX(_("SCO^start speed"));  else LOG_HELP(strcat("^3", "startspeed", "         ^7", _("Start speed (CTS)")));
-               case "strafe":       if (!mode) return CTX(_("SCO^strafe"));       else LOG_HELP(strcat("^3", "strafe", "             ^7", _("Strafe efficiency (CTS)")));
-               case "suicides":     if (!mode) return CTX(_("SCO^suicides"));     else LOG_HELP(strcat("^3", "suicides", "           ^7", _("Number of suicides")));
-               case "sum":          if (!mode) return CTX(_("SCO^sum"));          else LOG_HELP(strcat("^3", "sum", "                ^7", _("Number of kills minus deaths")));
-               case "takes":        if (!mode) return CTX(_("SCO^takes"));        else LOG_HELP(strcat("^3", "takes", "              ^7", _("Number of domination points taken (Domination)")));
-               case "teamkills":    if (!mode) return CTX(_("SCO^teamkills"));    else LOG_HELP(strcat("^3", "teamkills", "          ^7", _("Number of teamkills")));
-               case "ticks":        if (!mode) return CTX(_("SCO^ticks"));        else LOG_HELP(strcat("^3", "ticks", "              ^7", _("Number of ticks (Domination)")));
-               case "time":         if (!mode) return CTX(_("SCO^time"));         else LOG_HELP(strcat("^3", "time", "               ^7", _("Total time raced (Race/CTS)")));
-               default: return label;
+               SCO_LABEL(_("SCO^bckills"),       "bckills", "            ", _("Number of ball carrier kills"));
+               SCO_LABEL(_("SCO^bctime"),        "bctime", "             ", _("Total amount of time holding the ball in Keepaway"));
+               SCO_LABEL(_("SCO^caps"),          "caps", "               ", _("How often a flag (CTF) or a key (KeyHunt) was captured"));
+               SCO_LABEL(_("SCO^captime"),       "captime", "            ", _("Time of fastest capture (CTF)"));
+               SCO_LABEL(_("SCO^deaths"),        "deaths", "             ", _("Number of deaths"));
+               SCO_LABEL(_("SCO^destroyed"),     "destroyed", "          ", _("Number of keys destroyed by pushing them into void"));
+               SCO_LABEL(_("SCO^damage"),        "dmg", "                ", _("The total damage done"));
+               SCO_LABEL(_("SCO^dmgtaken"),      "dmgtaken", "           ", _("The total damage taken"));
+               SCO_LABEL(_("SCO^drops"),         "drops", "              ", _("Number of flag drops"));
+               SCO_LABEL(_("SCO^elo"),           "elo", "                ", _("Player ELO"));
+               SCO_LABEL(_("SCO^fastest"),       "fastest", "            ", _("Time of fastest lap (Race/CTS)"));
+               SCO_LABEL(_("SCO^faults"),        "faults", "             ", _("Number of faults committed"));
+               SCO_LABEL(_("SCO^fckills"),       "fckills", "            ", _("Number of flag carrier kills"));
+               SCO_LABEL(_("SCO^fps"),           "fps", "                ", _("FPS"));
+               SCO_LABEL(_("SCO^frags"),         "frags", "              ", _("Number of kills minus suicides"));
+               SCO_LABEL(_("SCO^goals"),         "goals", "              ", _("Number of goals scored"));
+               SCO_LABEL(_("SCO^hunts"),         "hunts", "              ", _("Number of hunts (Survival)"));
+               SCO_LABEL(_("SCO^kckills"),       "kckills", "            ", _("Number of keys carrier kills"));
+               SCO_LABEL(_("SCO^k/d"),           "kd", "                 ", _("The kill-death ratio"));
+               SCO_LABEL(_("SCO^kdr"),           "kdr", "                ", _("The kill-death ratio"));
+               SCO_LABEL(_("SCO^kdratio"),       "kdratio", "            ", _("The kill-death ratio"));
+               SCO_LABEL(_("SCO^kills"),         "kills", "              ", _("Number of kills"));
+               SCO_LABEL(_("SCO^laps"),          "laps", "               ", _("Number of laps finished (Race/CTS)"));
+               SCO_LABEL(_("SCO^lives"),         "lives", "              ", _("Number of lives (LMS)"));
+               SCO_LABEL(_("SCO^losses"),        "losses", "             ", _("Number of times a key was lost"));
+               SCO_LABEL(_("SCO^name"),          "name", "               ", _("Player name"));
+               SCO_LABEL(_("SCO^nick"),          "nick", "               ", _("Player name"));
+               SCO_LABEL(_("SCO^objectives"),    "objectives", "         ", _("Number of objectives destroyed"));
+               SCO_LABEL(_("SCO^pickups"),       "pickups", "            ", _("How often a flag (CTF) or a key (KeyHunt) or a ball (Keepaway) was picked up"));
+               SCO_LABEL(_("SCO^ping"),          "ping", "               ", _("Ping time"));
+               SCO_LABEL(_("SCO^pl"),            "pl", "                 ", _("Packet loss"));
+               SCO_LABEL(_("SCO^pushes"),        "pushes", "             ", _("Number of players pushed into void"));
+               SCO_LABEL(_("SCO^rank"),          "rank", "               ", _("Player rank"));
+               SCO_LABEL(_("SCO^returns"),       "returns", "            ", _("Number of flag returns"));
+               SCO_LABEL(_("SCO^revivals"),      "revivals", "           ", _("Number of revivals"));
+               SCO_LABEL(_("SCO^rounds won"),    "rounds", "             ", _("Number of rounds won"));
+               SCO_LABEL(_("SCO^rounds played"), "rounds_pl", "          ", _("Number of rounds played"));
+               SCO_LABEL(_("SCO^score"),         "score", "              ", _("Total score"));
++              SCO_LABEL(_("SCO^average speed"), "avgspeed", "           ", _("Average speed (CTS)"));
++              SCO_LABEL(_("SCO^top speed"),     "topspeed", "           ", _("Top speed (CTS)"));
++              SCO_LABEL(_("SCO^start speed"),   "startspeed", "         ", _("Start speed (CTS)"));
++              SCO_LABEL(_("SCO^strafe"),        "strafe", "             ", _("Strafe efficiency (CTS)"));
+               SCO_LABEL(_("SCO^suicides"),      "suicides", "           ", _("Number of suicides"));
+               SCO_LABEL(_("SCO^sum"),           "sum", "                ", _("Number of kills minus deaths"));
+               SCO_LABEL(_("SCO^survivals"),     "survivals", "          ", _("Number of survivals"));
+               SCO_LABEL(_("SCO^takes"),         "takes", "              ", _("Number of domination points taken (Domination)"));
+               SCO_LABEL(_("SCO^teamkills"),     "teamkills", "          ", _("Number of teamkills"));
+               SCO_LABEL(_("SCO^ticks"),         "ticks", "              ", _("Number of ticks (Domination)"));
+               SCO_LABEL(_("SCO^time"),          "time", "               ", _("Total time raced (Race/CTS)"));
        }
        return label;
+ #undef SCO_LABEL
  }
  
  bool scoreboard_ui_disabling;
@@@ -471,6 -483,13 +487,13 @@@ float HUD_Scoreboard_InputEvent(float b
                        }
                }
        }
+       else if(nPrimary == 'r' && (hudShiftState & S_CTRL))
+       {
+               if (!key_pressed)
+                       return true;
+               if (scoreboard_selected_panel == SB_PANEL_SCOREBOARD)
+                       localcmd("toggle hud_panel_scoreboard_scores_per_round\n");
+       }
        else if(nPrimary == 't' && (hudShiftState & S_CTRL))
        {
                if (!key_pressed)
@@@ -722,19 -741,20 +745,20 @@@ void Cmd_Scoreboard_Help(
  // e.g. -teams,rc,cts,lms/kills ?+rc/kills
  #define SCOREBOARD_DEFAULT_COLUMNS \
  "ping pl fps name |" \
- " -teams,rc,cts,inv,lms/kills +ft,tdm/kills ?+rc,inv/kills" \
- " -teams,lms/deaths +ft,tdm/deaths" \
+ " -teams,rc,cts,surv,inv,lms/kills +ft,tdm,tmayhem/kills ?+rc,inv/kills" \
+ " -teams,surv,lms/deaths +ft,tdm,tmayhem/deaths" \
  " +tdm/sum" \
- " -teams,lms,rc,cts,inv,ka/suicides +ft,tdm/suicides ?+rc,inv/suicides" \
- " -cts,dm,tdm,ka,ft/frags" /* tdm already has this in "score" */ \
- " +tdm,ft,dom,ons,as/teamkills"\
- " -rc,cts,nb/dmg -rc,cts,nb/dmgtaken" \
+ " -teams,lms,rc,cts,surv,inv,ka/suicides +ft,tdm,tmayhem/suicides ?+rc,inv/suicides" \
+ " -cts,dm,tdm,surv,ka,ft,mayhem,tmayhem/frags" /* tdm already has this in "score" */ \
+ " +tdm,ft,dom,ons,as,tmayhem/teamkills"\
+ " -rc,cts,surv,nb/dmg -rc,cts,surv,nb/dmgtaken" \
+ " +surv/survivals +surv/hunts" \
  " +ctf/pickups +ctf/fckills +ctf/returns +ctf/caps +ons/takes +ons/caps" \
  " +lms/lives +lms/rank" \
  " +kh/kckills +kh/losses +kh/caps" \
 -" ?+rc/laps ?+rc/time +rc,cts/fastest" \
 +" ?+rc/laps ?+rc/time ?+cts/strafe ?+cts/startspeed ?+cts/avgspeed ?+cts/topspeed +rc,cts/fastest" \
  " +as/objectives +nb/faults +nb/goals" \
- " +ka/pickups +ka/bckills +ka/bctime +ft/revivals" \
+ " +ka,tka/pickups +ka,tka/bckills +ka,tka/bctime +ft/revivals" \
  " +dom/ticks +dom/takes" \
  " -lms,rc,cts,inv,nb/score"
  
@@@ -959,7 -979,13 +983,13 @@@ string Scoreboard_GetName(entity pl
        }
        else if(!teamplay)
        {
-               int f = entcs_GetClientColors(pl.sv_entnum);
+               int f;
+               // NOTE: always adding 1024 allows saving the colormap 0 as a value != 0
+               if (playerslots[pl.sv_entnum].colormap >= 1024)
+                       f = playerslots[pl.sv_entnum].colormap - 1024; // override server-side player colors
+               else
+                       f = entcs_GetClientColors(pl.sv_entnum);
                {
                        sbt_field_icon0 = "gfx/scoreboard/playercolor_base";
                        sbt_field_icon1 = "gfx/scoreboard/playercolor_shirt";
        return entcs_GetName(pl.sv_entnum);
  }
  
- string Scoreboard_GetField(entity pl, PlayerScoreField field)
+ int autocvar_hud_panel_scoreboard_ping_best = 0;
+ int autocvar_hud_panel_scoreboard_ping_medium = 70;
+ int autocvar_hud_panel_scoreboard_ping_high = 100;
+ int autocvar_hud_panel_scoreboard_ping_worst = 150;
+ vector autocvar_hud_panel_scoreboard_ping_best_color = '0 1 0';
+ vector autocvar_hud_panel_scoreboard_ping_medium_color = '1 1 0';
+ vector autocvar_hud_panel_scoreboard_ping_high_color = '1 0.5 0';
+ vector autocvar_hud_panel_scoreboard_ping_worst_color = '1 0 0';
+ #define PING_BEST autocvar_hud_panel_scoreboard_ping_best
+ #define PING_MED autocvar_hud_panel_scoreboard_ping_medium
+ #define PING_HIGH autocvar_hud_panel_scoreboard_ping_high
+ #define PING_WORST autocvar_hud_panel_scoreboard_ping_worst
+ #define COLOR_BEST autocvar_hud_panel_scoreboard_ping_best_color
+ #define COLOR_MED autocvar_hud_panel_scoreboard_ping_medium_color
+ #define COLOR_HIGH autocvar_hud_panel_scoreboard_ping_high_color
+ #define COLOR_WORST autocvar_hud_panel_scoreboard_ping_worst_color
+ string Scoreboard_GetField(entity pl, PlayerScoreField field, bool per_round)
  {
        float tmp, num, denom;
        int f;
        sbt_field_icon0_rgb = '1 1 1';
        sbt_field_icon1_rgb = '1 1 1';
        sbt_field_icon2_rgb = '1 1 1';
+       int rounds_played = 0;
+       if (per_round)
+               rounds_played = pl.(scores(SP_ROUNDS_PL));
        switch(field)
        {
                case SP_PING:
                        f = pl.ping;
                        if(f == 0)
                                return _("N/A");
-                       tmp = max(0, min(220, f-80)) / 220;
-                       sbt_field_rgb = '1 1 1' - '0 1 1' * tmp;
+                       if(f < PING_BEST)
+                               sbt_field_rgb = COLOR_BEST;
+                       else if(f < PING_MED)
+                               sbt_field_rgb = COLOR_BEST + (COLOR_MED - COLOR_BEST) * ((f - PING_BEST) / (PING_MED - PING_BEST));
+                       else if(f < PING_HIGH)
+                               sbt_field_rgb = COLOR_MED + (COLOR_HIGH - COLOR_MED) * ((f - PING_MED) / (PING_HIGH - PING_MED));
+                       else if(f < PING_WORST)
+                               sbt_field_rgb = COLOR_HIGH + (COLOR_WORST - COLOR_HIGH) * ((f - PING_HIGH) / (PING_WORST - PING_HIGH));
+                       else
+                               sbt_field_rgb = COLOR_WORST;
                        return ftos(f);
  
                case SP_PL:
                case SP_FRAGS:
                        f = pl.(scores(SP_KILLS));
                        f -= pl.(scores(SP_SUICIDES));
+                       if (rounds_played)
+                               return sprintf("%.1f", f / rounds_played);
                        return ftos(f);
  
                case SP_KDRATIO:
  
                        if(denom == 0) {
                                sbt_field_rgb = '0 1 0';
-                               str = sprintf("%d", num);
+                               if (rounds_played)
+                                       str = sprintf("%.1f", num / rounds_played);
+                               else
+                                       str = sprintf("%d", num);
                        } else if(num <= 0) {
                                sbt_field_rgb = '1 0 0';
-                               str = sprintf("%.1f", num/denom);
+                               if (rounds_played)
+                                       str = sprintf("%.2f", num / (denom * rounds_played));
+                               else
+                                       str = sprintf("%.1f", num / denom);
                        } else
-                               str = sprintf("%.1f", num/denom);
+                       {
+                               if (rounds_played)
+                                       str = sprintf("%.2f", num / (denom * rounds_played));
+                               else
+                                       str = sprintf("%.1f", num / denom);
+                       }
                        return str;
  
                case SP_SUM:
                        } else {
                                sbt_field_rgb = '1 0 0';
                        }
+                       if (rounds_played)
+                               return sprintf("%.1f", f / rounds_played);
                        return ftos(f);
  
                case SP_ELO:
                        return ftos(fps);
                }
  
+               case SP_ROUNDS_PL:
+                       return ftos(pl.(scores(field)));
                case SP_DMG: case SP_DMGTAKEN:
+                       if (rounds_played)
+                               return sprintf("%.2f k", pl.(scores(field)) / (1000 * rounds_played));
                        return sprintf("%.1f k", pl.(scores(field)) / 1000);
  
 +              case SP_CTS_STRAFE:
 +              {
 +                      float strafe_efficiency = pl.(scores(field)) / 1000;
 +                      if(strafe_efficiency < -1) return "";
 +                      sbt_field_rgb = '1 1 1' - (strafe_efficiency > 0 ? '1 0 1' : '0 1 1') * fabs(strafe_efficiency);
 +                      return sprintf("%.1f%%", strafe_efficiency * 100);
 +              }
 +
 +              case SP_CTS_STARTSPEED:
 +              case SP_CTS_AVGSPEED:
 +              case SP_CTS_TOPSPEED:
 +              {
 +                      float speed = pl.(scores(field)) * GetSpeedUnitFactor(autocvar_hud_speed_unit);
 +                      if(speed < 0) return "";
 +                      return sprintf("%d%s", speed, GetSpeedUnit(autocvar_hud_speed_unit));
 +              }
 +
                default: case SP_SCORE:
                        tmp = pl.(scores(field));
                        f = scores_flags(field);
                                sbt_field_rgb = '0 1 1';
                        else
                                sbt_field_rgb = '1 1 1';
-                       return ScoreString(f, tmp);
+                       return ScoreString(f, tmp, rounds_played);
        }
        //return "error";
  }
@@@ -1274,7 -1330,7 +1351,7 @@@ void Scoreboard_DrawItem(vector item_po
                        pos.x += sbt_field_size[i] + hud_fontsize.x;
                        continue;
                }
-               str = Scoreboard_GetField(pl, field);
+               str = Scoreboard_GetField(pl, field, autocvar_hud_panel_scoreboard_scores_per_round);
                str = Scoreboard_FixColumnWidth(i, str);
  
                pos.x += sbt_field_size[i] + hud_fontsize.x;
                                continue;
                        }
  
-                       str = Scoreboard_GetField(pl, field);
+                       str = Scoreboard_GetField(pl, field, autocvar_hud_panel_scoreboard_scores_per_round);
                        str = Scoreboard_FixColumnWidth(i, str);
  
                        if(field == SP_NAME) {
@@@ -1379,10 -1435,10 +1456,10 @@@ vector Scoreboard_DrawOthers(vector ite
                if(this_team == NUM_SPECTATOR)
                {
                        if(autocvar_hud_panel_scoreboard_spectators_showping)
-                               field = Scoreboard_GetField(pl, SP_PING);
+                               field = Scoreboard_GetField(pl, SP_PING, autocvar_hud_panel_scoreboard_scores_per_round);
                }
                else if(autocvar_hud_panel_scoreboard_others_showscore)
-                       field = Scoreboard_GetField(pl, SP_SCORE);
+                       field = Scoreboard_GetField(pl, SP_SCORE, autocvar_hud_panel_scoreboard_scores_per_round);
  
                string str = entcs_GetName(pl.sv_entnum);
                if (autocvar_hud_panel_scoreboard_playerid)
@@@ -2177,7 -2233,7 +2254,7 @@@ string Scoreboard_Fraglimit_Draw(float 
  {
        string s_label = (teamplay) ? teamscores_label(ts_primary) : scores_label(ps_primary);
        int s_flags = (teamplay) ? teamscores_flags(ts_primary) : scores_flags(ps_primary);
-       return sprintf((is_leadlimit ? _("^2+%s %s") : _("^5%s %s")), ScoreString(s_flags, limit),
+       return sprintf((is_leadlimit ? _("^2+%s %s") : _("^5%s %s")), ScoreString(s_flags, limit, 0),
                (s_label == "score") ? CTX(_("SCO^points")) :
                (s_label == "fastest") ? "" : TranslateScoresLabel(s_label));
  }
@@@ -2281,9 -2337,9 +2358,9 @@@ void Scoreboard_Draw(
        if (scoreboard_ui_enabled == 2)
        {
                if (scoreboard_selected_team)
-                       str = sprintf(_("^7Press ^3%s^7 to join the selected team"), getcommandkey(_("jump"), "+jump"));
+                       str = sprintf(_("^7Press ^3%s^7 to join the selected team"), translate_key("SPACE"));
                else
-                       str = sprintf(_("^7Press ^3%s^7 to auto-select a team and join"), getcommandkey(_("jump"), "+jump"));
+                       str = sprintf(_("^7Press ^3%s^7 to auto-select a team and join"), translate_key("SPACE"));
                drawcolorcodedstring(pos + '0.5 0 0' * (panel_size.x - stringwidth(str, true, sb_gameinfo_detail_fontsize)), str, sb_gameinfo_detail_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
  
                pos.y += sb_gameinfo_detail_fontsize.y + hud_fontsize.y * 0.3;
diff --combined qcsrc/common/scores.qh
index 8ff5304d5fba965c628df1c827b5dcc7471304b4,8a01893f1019c423927029d57b004baa8f66b88c..448712f78d7154bd7f7c3ef29f068ab1c4b5bc43
@@@ -26,11 -26,6 +26,11 @@@ REGISTER_SP(RACE_LAPS)
  REGISTER_SP(RACE_TIME);
  REGISTER_SP(RACE_FASTEST);
  
 +REGISTER_SP(CTS_STRAFE);
 +REGISTER_SP(CTS_STARTSPEED);
 +REGISTER_SP(CTS_AVGSPEED);
 +REGISTER_SP(CTS_TOPSPEED);
 +
  REGISTER_SP(ASSAULT_OBJECTIVES);
  
  REGISTER_SP(CTF_CAPS);
@@@ -65,6 -60,13 +65,13 @@@ REGISTER_SP(NEXBALL_FAULTS)
  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);
@@@ -73,6 -75,8 +80,8 @@@ REGISTER_SP(SUICIDES)
  REGISTER_SP(DMG);
  REGISTER_SP(DMGTAKEN);
  
+ REGISTER_SP(ROUNDS_PL);
  REGISTER_SP(ELO); // not sortable
  REGISTER_SP(FPS); // not sortable