Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e17f2ed6b | ||
|
|
07bbd4353b | ||
|
|
e1784106b1 | ||
|
|
e892945417 |
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8.4)
|
|||||||
|
|
||||||
# root CMakeLists for the SuperTuxKart project
|
# root CMakeLists for the SuperTuxKart project
|
||||||
project(SuperTuxKart)
|
project(SuperTuxKart)
|
||||||
set(PROJECT_VERSION "git")
|
set(PROJECT_VERSION "1.2")
|
||||||
|
|
||||||
if (MINGW AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
if (MINGW AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
set(LLVM_MINGW TRUE)
|
set(LLVM_MINGW TRUE)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: SuperTuxKart\n"
|
"Project-Id-Version: SuperTuxKart\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-07-29 01:02+0800\n"
|
"POT-Creation-Date: 2020-07-29 01:02+0800\n"
|
||||||
"PO-Revision-Date: 2020-08-23 18:54+0000\n"
|
"PO-Revision-Date: 2020-08-24 22:39+0000\n"
|
||||||
"Last-Translator: Omer I.S.\n"
|
"Last-Translator: Omer I.S.\n"
|
||||||
"Language-Team: Hebrew (http://www.transifex.com/supertuxkart/supertuxkart/language/he/)\n"
|
"Language-Team: Hebrew (http://www.transifex.com/supertuxkart/supertuxkart/language/he/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@@ -2381,7 +2381,7 @@ msgstr "כפתור (מקש) החילוץ יעיל מאוד."
|
|||||||
|
|
||||||
#. I18N: ./data/tips.xml
|
#. I18N: ./data/tips.xml
|
||||||
msgid "Be careful when close to other karts, they may attack you!"
|
msgid "Be careful when close to other karts, they may attack you!"
|
||||||
msgstr "יש להיזהר כאשר קרובים אל עגלות אחרות, הן אולי יתקפו אותך!"
|
msgstr "יש להיזהר כאשר קרובים אל עגלות אחרות, הן עלולות לתקוף אותך!"
|
||||||
|
|
||||||
#. I18N: ./data/tips.xml
|
#. I18N: ./data/tips.xml
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -2552,12 +2552,12 @@ msgstr "מה יש, ילדי פרחים קטנטנים? מנהיגכם הדגול
|
|||||||
#. I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
|
#. I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
|
||||||
#. I18N: ../stk-assets/tracks/introcutscene2/scene.xml
|
#. I18N: ../stk-assets/tracks/introcutscene2/scene.xml
|
||||||
msgid "Oh yes, see, he's in my castle now and will be served for supper..."
|
msgid "Oh yes, see, he's in my castle now and will be served for supper..."
|
||||||
msgstr "אה כן, הבנת, הוא בטירה שלי כעת ויוגש לארוחת ערב..."
|
msgstr "אה כן, תבינו, הוא כעת בטירה שלי ויוגש לארוחת ערב..."
|
||||||
|
|
||||||
#. I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
|
#. I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
|
||||||
#. I18N: ../stk-assets/tracks/introcutscene2/scene.xml
|
#. I18N: ../stk-assets/tracks/introcutscene2/scene.xml
|
||||||
msgid "But I'm a fair creature, so I'll make you a deal."
|
msgid "But I'm a fair creature, so I'll make you a deal."
|
||||||
msgstr "אבל יצור הוגן הנני, אז אעשה אתכם עסקה."
|
msgstr "אך יצור הוגן הנני, אז אעשה אתכם עסקה."
|
||||||
|
|
||||||
#. I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
|
#. I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
|
||||||
#. I18N: ../stk-assets/tracks/introcutscene2/scene.xml
|
#. I18N: ../stk-assets/tracks/introcutscene2/scene.xml
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
# This file is distributed under the same license as the supertuxkart package.
|
# This file is distributed under the same license as the supertuxkart package.
|
||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# Benau, 2018-2019
|
# Benau, 2018-2020
|
||||||
# Bruno Ramalhete <bram.512@gmail.com>, 2015
|
# Bruno Ramalhete <bram.512@gmail.com>, 2015
|
||||||
# Crystal Da Eevee <rutmaria3333@hotmail.com>, 2019-2020
|
# Crystal Da Eevee <rutmaria3333@hotmail.com>, 2019-2020
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010
|
||||||
@@ -16,7 +16,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: SuperTuxKart\n"
|
"Project-Id-Version: SuperTuxKart\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-07-29 01:02+0800\n"
|
"POT-Creation-Date: 2020-07-29 01:02+0800\n"
|
||||||
"PO-Revision-Date: 2020-07-28 17:52+0000\n"
|
"PO-Revision-Date: 2020-08-27 17:31+0000\n"
|
||||||
"Last-Translator: Benau\n"
|
"Last-Translator: Benau\n"
|
||||||
"Language-Team: Portuguese (http://www.transifex.com/supertuxkart/supertuxkart/language/pt/)\n"
|
"Language-Team: Portuguese (http://www.transifex.com/supertuxkart/supertuxkart/language/pt/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@@ -5117,7 +5117,7 @@ msgstr "Assistir ao jogo"
|
|||||||
|
|
||||||
#: src/states_screens/online/networking_lobby.cpp:198
|
#: src/states_screens/online/networking_lobby.cpp:198
|
||||||
msgid "Install addon"
|
msgid "Install addon"
|
||||||
msgstr ""
|
msgstr "Instalar addon"
|
||||||
|
|
||||||
#: src/states_screens/online/networking_lobby.cpp:337
|
#: src/states_screens/online/networking_lobby.cpp:337
|
||||||
#, c-format
|
#, c-format
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: suzanne Suzanne
|
kart: suzanne Suzanne
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: suzanne Suzanne
|
kart: suzanne Suzanne
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: suzanne Suzanne
|
kart: suzanne Suzanne
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: suzanne Suzanne
|
kart: suzanne Suzanne
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: tux ☆★STK★☆
|
kart: tux ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: sara_the_wizard ☆★STK★☆
|
kart: sara_the_wizard ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: xue ☆★STK★☆
|
kart: xue ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: beastie ☆★STK★☆
|
kart: beastie ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: gavroche ☆★STK★☆
|
kart: gavroche ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: beastie ☆★STK★☆
|
kart: beastie ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: sara_the_racer ☆★STK★☆
|
kart: sara_the_racer ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: emule ☆★STK★☆
|
kart: emule ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: amanda ☆★STK★☆
|
kart: amanda ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: adiumy ☆★STK★☆
|
kart: adiumy ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: tux ☆★STK★☆
|
kart: tux ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: suzanne ☆★STK★☆
|
kart: suzanne ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: hexley ☆★STK★☆
|
kart: hexley ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: kiki ☆★STK★☆
|
kart: kiki ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: pidgin ☆★STK★☆
|
kart: pidgin ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: suzanne ☆★STK★☆
|
kart: suzanne ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: hexley ☆★STK★☆
|
kart: hexley ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: kiki ☆★STK★☆
|
kart: kiki ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: pidgin ☆★STK★☆
|
kart: pidgin ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: puffy ☆★STK★☆
|
kart: puffy ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: konqi ☆★STK★☆
|
kart: konqi ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: nolok ☆★STK★☆
|
kart: nolok ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: wilber ☆★STK★☆
|
kart: wilber ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: tux ☆★STK★☆
|
kart: tux ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
version: 4
|
version: 4
|
||||||
stk_version: 0.10.0
|
stk_version: 1.2
|
||||||
kart: gavroche ☆★STK★☆
|
kart: gavroche ☆★STK★☆
|
||||||
kart_color: 0.000000
|
kart_color: 0.000000
|
||||||
kart_list_end
|
kart_list_end
|
||||||
|
|||||||
@@ -2899,12 +2899,14 @@ void ServerLobby::computeNewRankings()
|
|||||||
if (!RaceManager::get()->modeHasLaps())
|
if (!RaceManager::get()->modeHasLaps())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::vector<double> scores_change;
|
std::vector<double> raw_scores_change;
|
||||||
std::vector<double> new_scores;
|
std::vector<double> new_raw_scores;
|
||||||
|
std::vector<double> prev_raw_scores;
|
||||||
std::vector<double> prev_scores;
|
std::vector<double> prev_scores;
|
||||||
std::vector<double> new_rating_deviations;
|
std::vector<double> new_rating_deviations;
|
||||||
std::vector<double> prev_rating_deviations;
|
std::vector<double> prev_rating_deviations;
|
||||||
std::vector<uint64_t> prev_disconnects;
|
std::vector<uint64_t> prev_disconnects; //bitflag
|
||||||
|
std::vector<int> disconnects;
|
||||||
|
|
||||||
World* w = World::getWorld();
|
World* w = World::getWorld();
|
||||||
assert(w);
|
assert(w);
|
||||||
@@ -2926,9 +2928,11 @@ void ServerLobby::computeNewRankings()
|
|||||||
for (unsigned i = 0; i < player_count; i++)
|
for (unsigned i = 0; i < player_count; i++)
|
||||||
{
|
{
|
||||||
const uint32_t id = RaceManager::get()->getKartInfo(i).getOnlineId();
|
const uint32_t id = RaceManager::get()->getKartInfo(i).getOnlineId();
|
||||||
double prev_score = m_scores.at(id);
|
double prev_raw_score = m_raw_scores.at(id);
|
||||||
new_scores.push_back(prev_score);
|
new_raw_scores.push_back(prev_raw_score);
|
||||||
prev_scores.push_back(prev_score);
|
prev_raw_scores.push_back(prev_raw_score);
|
||||||
|
|
||||||
|
prev_scores.push_back(m_scores.at(id));
|
||||||
|
|
||||||
double prev_deviation = m_rating_deviations.at(id);
|
double prev_deviation = m_rating_deviations.at(id);
|
||||||
new_rating_deviations.push_back(prev_deviation);
|
new_rating_deviations.push_back(prev_deviation);
|
||||||
@@ -2952,6 +2956,10 @@ void ServerLobby::computeNewRankings()
|
|||||||
|
|
||||||
if (w->getKart(i)->isEliminated())
|
if (w->getKart(i)->isEliminated())
|
||||||
m_num_ranked_disconnects.at(id)++;
|
m_num_ranked_disconnects.at(id)++;
|
||||||
|
|
||||||
|
// std::popcount is C++20 only
|
||||||
|
std::bitset<64> b(m_num_ranked_disconnects.at(id));
|
||||||
|
disconnects.push_back(b.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
// In this loop, considering the race as a set
|
// In this loop, considering the race as a set
|
||||||
@@ -2963,11 +2971,11 @@ void ServerLobby::computeNewRankings()
|
|||||||
// II - Rating deviation changes
|
// II - Rating deviation changes
|
||||||
for (unsigned i = 0; i < player_count; i++)
|
for (unsigned i = 0; i < player_count; i++)
|
||||||
{
|
{
|
||||||
scores_change.push_back(0.0);
|
raw_scores_change.push_back(0.0);
|
||||||
|
|
||||||
double player1_scores = new_scores[i];
|
double player1_raw_scores = new_raw_scores[i];
|
||||||
if (w->getKart(i)->getHandicap())
|
if (w->getKart(i)->getHandicap())
|
||||||
player1_scores -= HANDICAP_OFFSET;
|
player1_raw_scores -= HANDICAP_OFFSET;
|
||||||
|
|
||||||
// If the player has quitted before the race end,
|
// If the player has quitted before the race end,
|
||||||
// the time value will be incorrect, but it will not be used
|
// the time value will be incorrect, but it will not be used
|
||||||
@@ -2976,8 +2984,10 @@ void ServerLobby::computeNewRankings()
|
|||||||
|
|
||||||
// On a disconnect, increase RD once,
|
// On a disconnect, increase RD once,
|
||||||
// no matter how many opponents
|
// no matter how many opponents
|
||||||
if (w->getKart(i)->isEliminated())
|
if (w->getKart(i)->isEliminated() && disconnects[i] >= 3)
|
||||||
new_rating_deviations[i] = prev_rating_deviations[i] + 20.0;
|
new_rating_deviations[i] = prev_rating_deviations[i]
|
||||||
|
+ BASE_RD_PER_DISCONNECT
|
||||||
|
+ VAR_RD_PER_DISCONNECT * (disconnects[i] - 3);
|
||||||
|
|
||||||
// Loop over all opponents
|
// Loop over all opponents
|
||||||
for (unsigned j = 0; j < player_count; j++)
|
for (unsigned j = 0; j < player_count; j++)
|
||||||
@@ -2994,9 +3004,9 @@ void ServerLobby::computeNewRankings()
|
|||||||
double diff, result, expected_result, ranking_importance, max_time;
|
double diff, result, expected_result, ranking_importance, max_time;
|
||||||
diff = result = expected_result = ranking_importance = max_time = 0.0;
|
diff = result = expected_result = ranking_importance = max_time = 0.0;
|
||||||
|
|
||||||
double player2_scores = new_scores[j];
|
double player2_raw_scores = new_raw_scores[j];
|
||||||
if (w->getKart(j)->getHandicap())
|
if (w->getKart(j)->getHandicap())
|
||||||
player2_scores -= HANDICAP_OFFSET;
|
player2_raw_scores -= HANDICAP_OFFSET;
|
||||||
|
|
||||||
double player2_time = RaceManager::get()->getKartRaceTime(j);
|
double player2_time = RaceManager::get()->getKartRaceTime(j);
|
||||||
double player2_rd = prev_rating_deviations[j];
|
double player2_rd = prev_rating_deviations[j];
|
||||||
@@ -3006,7 +3016,7 @@ void ServerLobby::computeNewRankings()
|
|||||||
// compared to existing estimates.
|
// compared to existing estimates.
|
||||||
|
|
||||||
bool handicap_used = w->getKart(i)->getHandicap() || w->getKart(j)->getHandicap();
|
bool handicap_used = w->getKart(i)->getHandicap() || w->getKart(j)->getHandicap();
|
||||||
double accuracy = computeDataAccuracy(player1_rd, player2_rd, player1_scores, player2_scores, handicap_used);
|
double accuracy = computeDataAccuracy(player1_rd, player2_rd, player1_raw_scores, player2_raw_scores, player_count, handicap_used);
|
||||||
|
|
||||||
// Now that we've computed the reliability value,
|
// Now that we've computed the reliability value,
|
||||||
// we can proceed with computing the points gained or lost
|
// we can proceed with computing the points gained or lost
|
||||||
@@ -3017,32 +3027,28 @@ void ServerLobby::computeNewRankings()
|
|||||||
|
|
||||||
if (w->getKart(i)->isEliminated())
|
if (w->getKart(i)->isEliminated())
|
||||||
{
|
{
|
||||||
|
// Recurring disconnects are punished through
|
||||||
|
// increased RD and higher RD floor,
|
||||||
|
// not through higher raw score loss
|
||||||
result = 0.0;
|
result = 0.0;
|
||||||
player1_time = player2_time; // for getTimeSpread
|
player1_time = player2_time * 1.2; // for getTimeSpread
|
||||||
|
|
||||||
// Bigger penalty for recurring disconnects
|
|
||||||
double disconnect_penalty = computeDisconnectPenalty(j);
|
|
||||||
max_time = ((1 - disconnect_penalty) * player2_time * 1.2)
|
|
||||||
+ (disconnect_penalty * MAX_SCALING_TIME);
|
|
||||||
}
|
}
|
||||||
else if (w->getKart(j)->isEliminated())
|
else if (w->getKart(j)->isEliminated())
|
||||||
{
|
{
|
||||||
result = 1.0;
|
result = 1.0;
|
||||||
player2_time = player1_time;
|
player2_time = player1_time * 1.2;
|
||||||
double disconnect_penalty = computeDisconnectPenalty(j);
|
|
||||||
max_time = ((1 - disconnect_penalty) * player2_time * 1.2)
|
|
||||||
+ (disconnect_penalty * MAX_SCALING_TIME);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = computeH2HResult(player1_time, player2_time);
|
result = computeH2HResult(player1_time, player2_time);
|
||||||
max_time = std::min(std::max(player1_time, player2_time), MAX_SCALING_TIME);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
max_time = std::min(MAX_SCALING_TIME, std::max(player1_time, player2_time));
|
||||||
|
|
||||||
ranking_importance = accuracy * mode_factor * scalingValueForTime(max_time);
|
ranking_importance = accuracy * mode_factor * scalingValueForTime(max_time);
|
||||||
|
|
||||||
// Compute the expected result using an ELO-like function
|
// Compute the expected result using an ELO-like function
|
||||||
diff = player2_scores - player1_scores;
|
diff = player2_raw_scores - player1_raw_scores;
|
||||||
|
|
||||||
expected_result = 1.0/ (1.0 + std::pow(10.0,
|
expected_result = 1.0/ (1.0 + std::pow(10.0,
|
||||||
diff / ( BASE_RANKING_POINTS / 2.0
|
diff / ( BASE_RANKING_POINTS / 2.0
|
||||||
@@ -3050,7 +3056,7 @@ void ServerLobby::computeNewRankings()
|
|||||||
* getTimeSpread(std::min(player1_time, player2_time)))));
|
* getTimeSpread(std::min(player1_time, player2_time)))));
|
||||||
|
|
||||||
// Compute the ranking change
|
// Compute the ranking change
|
||||||
scores_change[i] += ranking_importance * (result - expected_result);
|
raw_scores_change[i] += ranking_importance * (result - expected_result);
|
||||||
|
|
||||||
// We now update the rating deviation. The change
|
// We now update the rating deviation. The change
|
||||||
// depends on the current RD, on the result's accuracy,
|
// depends on the current RD, on the result's accuracy,
|
||||||
@@ -3090,19 +3096,24 @@ void ServerLobby::computeNewRankings()
|
|||||||
// Don't merge it in the main loop as new_scores value are used there
|
// Don't merge it in the main loop as new_scores value are used there
|
||||||
for (unsigned i = 0; i < player_count; i++)
|
for (unsigned i = 0; i < player_count; i++)
|
||||||
{
|
{
|
||||||
new_scores[i] += scores_change[i];
|
new_raw_scores[i] += raw_scores_change[i];
|
||||||
const uint32_t id = RaceManager::get()->getKartInfo(i).getOnlineId();
|
const uint32_t id = RaceManager::get()->getKartInfo(i).getOnlineId();
|
||||||
m_scores.at(id) = new_scores[i];
|
m_raw_scores.at(id) = new_raw_scores[i];
|
||||||
|
|
||||||
// Ensure RD doesn't go below the RD floor.
|
// Ensure RD doesn't go below the RD floor.
|
||||||
new_rating_deviations[i] = std::max(new_rating_deviations[i], MIN_RATING_DEVIATION);
|
// The minimum RD is increased in case of repeated disconnects
|
||||||
|
double disconnects_floor = 0;
|
||||||
|
if (disconnects[i] >= 3)
|
||||||
|
{
|
||||||
|
int n = disconnects[i] - 3;
|
||||||
|
disconnects_floor = (disconnects[i]-2) * BASE_RD_PER_DISCONNECT
|
||||||
|
+ VAR_RD_PER_DISCONNECT * (n * (n+1)) / 2;
|
||||||
|
}
|
||||||
|
new_rating_deviations[i] = std::max(new_rating_deviations[i], MIN_RATING_DEVIATION + disconnects_floor);
|
||||||
m_rating_deviations.at(id) = new_rating_deviations[i];
|
m_rating_deviations.at(id) = new_rating_deviations[i];
|
||||||
|
|
||||||
// Update the maximum (reliable floor) score. At min RD, it is equal to the raw score.
|
// Update the main public rating. At min RD, it is equal to the raw score.
|
||||||
// TODO : make the public-facing score and rankings based on a reliable floor score ?
|
m_scores.at(id) = m_raw_scores.at(id) - 3*new_rating_deviations[i] + 3*MIN_RATING_DEVIATION;
|
||||||
double reliable_score = m_scores.at(id) - 3*new_rating_deviations[i] + 3*MIN_RATING_DEVIATION;
|
|
||||||
if (reliable_score > m_reliable_scores.at(id))
|
|
||||||
m_reliable_scores.at(id) = m_scores.at(id) - 3*new_rating_deviations[i] + 3*MIN_RATING_DEVIATION;
|
|
||||||
|
|
||||||
if (m_scores.at(id) > m_max_scores.at(id))
|
if (m_scores.at(id) > m_max_scores.at(id))
|
||||||
m_max_scores.at(id) = m_scores.at(id);
|
m_max_scores.at(id) = m_scores.at(id);
|
||||||
}
|
}
|
||||||
@@ -3184,23 +3195,6 @@ double ServerLobby::computeH2HResult(double player1_time, double player2_time)
|
|||||||
return result;
|
return result;
|
||||||
} // computeH2HResult
|
} // computeH2HResult
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
/** Computes the disconnect penalty
|
|
||||||
*/
|
|
||||||
double ServerLobby::computeDisconnectPenalty(int player_number)
|
|
||||||
{
|
|
||||||
const uint32_t id = RaceManager::get()->getKartInfo(player_number).getOnlineId();
|
|
||||||
// std::popcount is C++20 only
|
|
||||||
std::bitset<64> b(m_num_ranked_disconnects.at(id));
|
|
||||||
int disconnects = b.count();
|
|
||||||
double disconnect_penalty = (disconnects <= 2) ? 0.0 :
|
|
||||||
(disconnects >= 8) ? 1.0 :
|
|
||||||
(disconnects - 2) / 6.0;
|
|
||||||
|
|
||||||
return disconnect_penalty;
|
|
||||||
} // computeDisconnectPenalty
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Computes a relative factor indicating how much informative value
|
/** Computes a relative factor indicating how much informative value
|
||||||
* the new race result gives us.
|
* the new race result gives us.
|
||||||
@@ -3229,11 +3223,15 @@ double ServerLobby::computeDisconnectPenalty(int player_number)
|
|||||||
* of a race is roughly proportional to the likelihood of the weaker player winning.
|
* of a race is roughly proportional to the likelihood of the weaker player winning.
|
||||||
* We cap the effect so that losing to a much weaker player still costs rating points.
|
* We cap the effect so that losing to a much weaker player still costs rating points.
|
||||||
*
|
*
|
||||||
|
* In a race with many players, a single event can have a significant impact on the
|
||||||
|
* results of all the H2H. To avoid races with high players count having too strong
|
||||||
|
* rating swings, we apply a modifier scaling down accuracy.
|
||||||
|
*
|
||||||
* Finally, while handicap is allowed in ranked races and a rating offset is applied
|
* Finally, while handicap is allowed in ranked races and a rating offset is applied
|
||||||
* to keep expected results realistic (without incentivizing playing handicap-only),
|
* to keep expected results realistic (without incentivizing playing handicap-only),
|
||||||
* the results of such races are much less reliable.
|
* the results of such races are much less reliable.
|
||||||
*/
|
*/
|
||||||
double ServerLobby::computeDataAccuracy(double player1_rd, double player2_rd, double player1_scores, double player2_scores, bool handicap_used)
|
double ServerLobby::computeDataAccuracy(double player1_rd, double player2_rd, double player1_scores, double player2_scores, int player_count, bool handicap_used)
|
||||||
{
|
{
|
||||||
double accuracy = player1_rd / (sqrt(player2_rd) * sqrt(MIN_RATING_DEVIATION));
|
double accuracy = player1_rd / (sqrt(player2_rd) * sqrt(MIN_RATING_DEVIATION));
|
||||||
|
|
||||||
@@ -3255,9 +3253,14 @@ double ServerLobby::computeDataAccuracy(double player1_rd, double player2_rd, do
|
|||||||
accuracy *= expected_result;
|
accuracy *= expected_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reduce the importance of single h2h in a race with many players.
|
||||||
|
// The overall impact of a race with more players is still always bigger.
|
||||||
|
double player_count_modifier = 2.0 / sqrt((double) player_count);
|
||||||
|
accuracy *= player_count_modifier;
|
||||||
|
|
||||||
// Races with handicap are unreliable for ranking
|
// Races with handicap are unreliable for ranking
|
||||||
if (handicap_used)
|
if (handicap_used)
|
||||||
accuracy *= 0.3;
|
accuracy *= 0.25;
|
||||||
|
|
||||||
return accuracy;
|
return accuracy;
|
||||||
}
|
}
|
||||||
@@ -3313,7 +3316,7 @@ void ServerLobby::clearDisconnectedRankedPlayer()
|
|||||||
m_scores.erase(id);
|
m_scores.erase(id);
|
||||||
m_max_scores.erase(id);
|
m_max_scores.erase(id);
|
||||||
m_num_ranked_races.erase(id);
|
m_num_ranked_races.erase(id);
|
||||||
m_reliable_scores.erase(id);
|
m_raw_scores.erase(id);
|
||||||
m_rating_deviations.erase(id);
|
m_rating_deviations.erase(id);
|
||||||
m_num_ranked_disconnects.erase(id);
|
m_num_ranked_disconnects.erase(id);
|
||||||
it = m_ranked_players.erase(it);
|
it = m_ranked_players.erase(it);
|
||||||
@@ -4520,12 +4523,12 @@ void ServerLobby::getRankingForPlayer(std::shared_ptr<NetworkPlayerProfile> p)
|
|||||||
std::string rec_success;
|
std::string rec_success;
|
||||||
|
|
||||||
// Default result
|
// Default result
|
||||||
double score = 4000.0;
|
double raw_score = BASE_RANKING_POINTS;
|
||||||
double max_score = 4000.0;
|
double score = BASE_RANKING_POINTS - 3*BASE_RATING_DEVIATION + 3*MIN_RATING_DEVIATION;
|
||||||
|
double max_score = BASE_RANKING_POINTS - 3*BASE_RATING_DEVIATION + 3*MIN_RATING_DEVIATION;
|
||||||
unsigned num_races = 0;
|
unsigned num_races = 0;
|
||||||
double reliable_score = 1300.0;
|
double rating_deviation = BASE_RATING_DEVIATION;
|
||||||
double rating_deviation = 1000.0;
|
uint64_t disconnects = 0;
|
||||||
uint64_t disconnection = 0;
|
|
||||||
if (result->get("success", &rec_success))
|
if (result->get("success", &rec_success))
|
||||||
{
|
{
|
||||||
if (rec_success == "yes")
|
if (rec_success == "yes")
|
||||||
@@ -4533,9 +4536,9 @@ void ServerLobby::getRankingForPlayer(std::shared_ptr<NetworkPlayerProfile> p)
|
|||||||
result->get("scores", &score);
|
result->get("scores", &score);
|
||||||
result->get("max-scores", &max_score);
|
result->get("max-scores", &max_score);
|
||||||
result->get("num-races-done", &num_races);
|
result->get("num-races-done", &num_races);
|
||||||
result->get("reliable-scores", &reliable_score);
|
result->get("raw-scores", &raw_score);
|
||||||
result->get("rating-deviation", &rating_deviation);
|
result->get("rating-deviation", &rating_deviation);
|
||||||
result->get("disconnection", &disconnection);
|
result->get("disconnects", &disconnects);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -4566,9 +4569,9 @@ void ServerLobby::getRankingForPlayer(std::shared_ptr<NetworkPlayerProfile> p)
|
|||||||
m_scores[id] = score;
|
m_scores[id] = score;
|
||||||
m_max_scores[id] = max_score;
|
m_max_scores[id] = max_score;
|
||||||
m_num_ranked_races[id] = num_races;
|
m_num_ranked_races[id] = num_races;
|
||||||
m_reliable_scores[id] = reliable_score;
|
m_raw_scores[id] = raw_score;
|
||||||
m_rating_deviations[id] = rating_deviation;
|
m_rating_deviations[id] = rating_deviation;
|
||||||
m_num_ranked_disconnects[id] = disconnection;
|
m_num_ranked_disconnects[id] = disconnects;
|
||||||
} // getRankingForPlayer
|
} // getRankingForPlayer
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -4584,8 +4587,8 @@ void ServerLobby::submitRankingsToAddons()
|
|||||||
public:
|
public:
|
||||||
SubmitRankingRequest(uint32_t online_id, double scores,
|
SubmitRankingRequest(uint32_t online_id, double scores,
|
||||||
double max_scores, unsigned num_races,
|
double max_scores, unsigned num_races,
|
||||||
double reliable_scores, double rating_deviation,
|
double raw_scores, double rating_deviation,
|
||||||
uint64_t disconnection,
|
uint64_t disconnects,
|
||||||
const std::string& country_code)
|
const std::string& country_code)
|
||||||
: XMLRequest(Online::RequestManager::HTTP_MAX_PRIORITY)
|
: XMLRequest(Online::RequestManager::HTTP_MAX_PRIORITY)
|
||||||
{
|
{
|
||||||
@@ -4593,9 +4596,9 @@ void ServerLobby::submitRankingsToAddons()
|
|||||||
addParameter("scores", scores);
|
addParameter("scores", scores);
|
||||||
addParameter("max-scores", max_scores);
|
addParameter("max-scores", max_scores);
|
||||||
addParameter("num-races-done", num_races);
|
addParameter("num-races-done", num_races);
|
||||||
addParameter("reliable-scores", reliable_scores);
|
addParameter("raw-scores", raw_scores);
|
||||||
addParameter("rating-deviation", rating_deviation);
|
addParameter("rating-deviation", rating_deviation);
|
||||||
addParameter("disconnection", disconnection);
|
addParameter("disconnects", disconnects);
|
||||||
addParameter("country-code", country_code);
|
addParameter("country-code", country_code);
|
||||||
}
|
}
|
||||||
virtual void afterOperation()
|
virtual void afterOperation()
|
||||||
@@ -4617,7 +4620,7 @@ void ServerLobby::submitRankingsToAddons()
|
|||||||
const uint32_t id = RaceManager::get()->getKartInfo(i).getOnlineId();
|
const uint32_t id = RaceManager::get()->getKartInfo(i).getOnlineId();
|
||||||
auto request = std::make_shared<SubmitRankingRequest>
|
auto request = std::make_shared<SubmitRankingRequest>
|
||||||
(id, m_scores.at(id), m_max_scores.at(id),
|
(id, m_scores.at(id), m_max_scores.at(id),
|
||||||
m_num_ranked_races.at(id), m_reliable_scores.at(id),
|
m_num_ranked_races.at(id), m_raw_scores.at(id),
|
||||||
m_rating_deviations.at(id), m_num_ranked_disconnects.at(id),
|
m_rating_deviations.at(id), m_num_ranked_disconnects.at(id),
|
||||||
RaceManager::get()->getKartInfo(i).getCountryCode());
|
RaceManager::get()->getKartInfo(i).getCountryCode());
|
||||||
NetworkConfig::get()->setUserDetails(request, "submit-ranking");
|
NetworkConfig::get()->setUserDetails(request, "submit-ranking");
|
||||||
|
|||||||
@@ -186,6 +186,8 @@ private:
|
|||||||
const double BASE_RANKING_POINTS = 4000.0; // Given to a new player on 1st connection to a ranked server
|
const double BASE_RANKING_POINTS = 4000.0; // Given to a new player on 1st connection to a ranked server
|
||||||
const double BASE_RATING_DEVIATION = 1000.0; // Given to a new player on 1st connection to a ranked server
|
const double BASE_RATING_DEVIATION = 1000.0; // Given to a new player on 1st connection to a ranked server
|
||||||
const double MIN_RATING_DEVIATION = 100.0; // A server cron job makes RD go up if a player is inactive
|
const double MIN_RATING_DEVIATION = 100.0; // A server cron job makes RD go up if a player is inactive
|
||||||
|
const double BASE_RD_PER_DISCONNECT = 15.0;
|
||||||
|
const double VAR_RD_PER_DISCONNECT = 3.0;
|
||||||
const double MAX_SCALING_TIME = 360.0;
|
const double MAX_SCALING_TIME = 360.0;
|
||||||
const double BASE_POINTS_PER_SECOND = 0.18;
|
const double BASE_POINTS_PER_SECOND = 0.18;
|
||||||
const double HANDICAP_OFFSET = 2000.0;
|
const double HANDICAP_OFFSET = 2000.0;
|
||||||
@@ -193,22 +195,22 @@ private:
|
|||||||
/** Online id to profile map, handling disconnection in ranked server */
|
/** Online id to profile map, handling disconnection in ranked server */
|
||||||
std::map<uint32_t, std::weak_ptr<NetworkPlayerProfile> > m_ranked_players;
|
std::map<uint32_t, std::weak_ptr<NetworkPlayerProfile> > m_ranked_players;
|
||||||
|
|
||||||
/** Multi-session ranking scores for each current player */
|
/** Multi-session rating for each current player */
|
||||||
std::map<uint32_t, double> m_scores;
|
std::map<uint32_t, double> m_raw_scores;
|
||||||
|
|
||||||
/** The rating uncertainty for each current player */
|
/** The rating uncertainty for each current player */
|
||||||
std::map<uint32_t, double> m_rating_deviations;
|
std::map<uint32_t, double> m_rating_deviations;
|
||||||
|
|
||||||
/** The maximum scores obtained for each current player */
|
/** A single number compounding "raw score" and RD,
|
||||||
|
* for rating display to players and rankings */
|
||||||
|
std::map<uint32_t, double> m_scores;
|
||||||
|
|
||||||
|
/** The maximum rating obtained for each current player.
|
||||||
|
* This is based on m_scores, not m_raw_scores */
|
||||||
std::map<uint32_t, double> m_max_scores;
|
std::map<uint32_t, double> m_max_scores;
|
||||||
|
|
||||||
/** The maximum reliable ranking scores achieved for each current player.
|
|
||||||
This is not the same as the maximum raw ranking points,
|
|
||||||
because a very high rating with very high RD is most likely lucky. */
|
|
||||||
std::map<uint32_t, double> m_reliable_scores;
|
|
||||||
|
|
||||||
/** Number of disconnects in the previous 64 ranked races for each current players */
|
/** Number of disconnects in the previous 64 ranked races for each current players */
|
||||||
std::map<uint32_t, uint64_t> m_num_ranked_disconnects; // TODO Initialized to 0 for a new player on 1st connection to a ranked server
|
std::map<uint32_t, uint64_t> m_num_ranked_disconnects;
|
||||||
|
|
||||||
/** Number of ranked races done for each current players */
|
/** Number of ranked races done for each current players */
|
||||||
std::map<uint32_t, unsigned> m_num_ranked_races;
|
std::map<uint32_t, unsigned> m_num_ranked_races;
|
||||||
@@ -333,8 +335,9 @@ private:
|
|||||||
double getUncertaintySpread(uint32_t online_id);
|
double getUncertaintySpread(uint32_t online_id);
|
||||||
double scalingValueForTime(double time);
|
double scalingValueForTime(double time);
|
||||||
double computeH2HResult(double player1_time, double player2_time);
|
double computeH2HResult(double player1_time, double player2_time);
|
||||||
double computeDisconnectPenalty(int player_number);
|
double computeDataAccuracy(double player1_rd, double player2_rd,
|
||||||
double computeDataAccuracy(double player1_rd, double player2_rd, double player1_scores, double player2_scores, bool handicap_used);
|
double player1_scores, double player2_scores,
|
||||||
|
int player_count, bool handicap_used);
|
||||||
void checkRaceFinished();
|
void checkRaceFinished();
|
||||||
void getHitCaptureLimit();
|
void getHitCaptureLimit();
|
||||||
void configPeersStartTime();
|
void configPeersStartTime();
|
||||||
|
|||||||
Reference in New Issue
Block a user