Achievements: Make leaderboard notifications a little nicer

This commit is contained in:
Stenzek
2026-01-15 22:16:48 +10:00
parent f222c5012a
commit 93a5663fc8
17 changed files with 234 additions and 212 deletions

View File

@@ -48,3 +48,6 @@
#define ICON_EMOJI_NOTEBOOK "\xf0\x9f\x93\x99"
#define ICON_EMOJI_GEAR "\xe2\x9a\x99"
#define ICON_EMOJI_NO_ENTRY_SIGN "\xe2\x9b\x94"
#define ICON_EMOJI_BAR_CHART "\xf0\x9f\x93\x8a"
#define ICON_EMOJI_CHART_UPWARDS_TREND "\xf0\x9f\x93\x88"
#define ICON_EMOJI_DIRECT_HIT "\xf0\x9f\x8e\xaf"

View File

@@ -74,6 +74,7 @@ static constexpr const char* UNLOCK_SOUND_NAME = "sounds/achievements/unlock.wav
static constexpr const char* LBSUBMIT_SOUND_NAME = "sounds/achievements/lbsubmit.wav";
static constexpr const char* CACHE_SUBDIRECTORY_NAME = "achievement_images";
constexpr const char* const RA_LOGO_ICON_NAME = "images/ra-icon.webp";
constexpr const std::string_view NOTIFICATION_SPINNER_NOTE = "__spinner__";
static constexpr float LOGIN_NOTIFICATION_TIME = 5.0f;
static constexpr float ACHIEVEMENT_SUMMARY_NOTIFICATION_TIME = 5.0f;
@@ -84,6 +85,7 @@ static constexpr float CHALLENGE_STARTED_NOTIFICATION_TIME = 5.0f;
static constexpr float CHALLENGE_FAILED_NOTIFICATION_TIME = 5.0f;
static constexpr float LEADERBOARD_STARTED_NOTIFICATION_TIME = 3.0f;
static constexpr float LEADERBOARD_FAILED_NOTIFICATION_TIME = 3.0f;
static constexpr float LEADERBOARD_NOTIFICATION_MIN_WIDTH = 380.0f;
// Some API calls are really slow. Set a longer timeout.
static constexpr float SERVER_CALL_TIMEOUT = 60.0f;
@@ -1444,23 +1446,26 @@ void Achievements::HandleLeaderboardSubmittedEvent(const rc_client_event_t* even
if (g_settings.achievements_leaderboard_notifications)
{
static const char* value_strings[NUM_RC_CLIENT_LEADERBOARD_FORMATS] = {
TRANSLATE_NOOP("Achievements", "Your Time: {}{}"),
TRANSLATE_NOOP("Achievements", "Your Score: {}{}"),
TRANSLATE_NOOP("Achievements", "Your Value: {}{}"),
static const char* value_strings[NUM_RC_CLIENT_LEADERBOARD_FORMATS][2] = {
{ICON_EMOJI_CLOCK_FIVE_OCLOCK, TRANSLATE_NOOP("Achievements", "Your Time: {}")},
{ICON_EMOJI_DIRECT_HIT, TRANSLATE_NOOP("Achievements", "Your Score: {}")},
{ICON_EMOJI_CLIPBOARD, TRANSLATE_NOOP("Achievements", "Your Value: {}")},
};
std::string message = fmt::format(
fmt::runtime(Host::TranslateToStringView(
"Achievements",
value_strings[std::min<u8>(event->leaderboard->format, NUM_RC_CLIENT_LEADERBOARD_FORMATS - 1)])),
event->leaderboard->tracker_value ? event->leaderboard->tracker_value : "Unknown",
g_settings.achievements_spectator_mode ? std::string_view() : TRANSLATE_SV("Achievements", " (Submitting)"));
"{} {}", value_strings[std::min<u8>(event->leaderboard->format, NUM_RC_CLIENT_LEADERBOARD_FORMATS - 1)][0],
TinyString::from_format(
fmt::runtime(Host::TranslateToStringView(
"Achievements",
value_strings[std::min<u8>(event->leaderboard->format, NUM_RC_CLIENT_LEADERBOARD_FORMATS - 1)][1])),
event->leaderboard->tracker_value ? event->leaderboard->tracker_value : "Unknown"));
FullscreenUI::AddAchievementNotification(fmt::format("leaderboard_{}", event->leaderboard->id),
static_cast<float>(g_settings.achievements_leaderboard_duration),
s_state.game_icon, std::string(event->leaderboard->title),
std::move(message), {});
FullscreenUI::AddAchievementNotification(
fmt::format("leaderboard_{}", event->leaderboard->id),
static_cast<float>(g_settings.achievements_leaderboard_duration), s_state.game_icon,
std::string(event->leaderboard->title), std::move(message),
std::string(g_settings.achievements_spectator_mode ? std::string_view() : NOTIFICATION_SPINNER_NOTE),
LEADERBOARD_NOTIFICATION_MIN_WIDTH);
}
if (g_settings.achievements_sound_effects)
@@ -1474,24 +1479,28 @@ void Achievements::HandleLeaderboardScoreboardEvent(const rc_client_event_t* eve
if (g_settings.achievements_leaderboard_notifications)
{
static const char* value_strings[NUM_RC_CLIENT_LEADERBOARD_FORMATS] = {
TRANSLATE_NOOP("Achievements", "Your Time: {} (Best: {})"),
TRANSLATE_NOOP("Achievements", "Your Score: {} (Best: {})"),
TRANSLATE_NOOP("Achievements", "Your Value: {} (Best: {})"),
static const char* value_strings[NUM_RC_CLIENT_LEADERBOARD_FORMATS][2] = {
{ICON_EMOJI_CLOCK_FIVE_OCLOCK, TRANSLATE_NOOP("Achievements", "Your Time: {0} (Best: {1})")},
{ICON_EMOJI_DIRECT_HIT, TRANSLATE_NOOP("Achievements", "Your Score: {0} (Best: {1})")},
{ICON_EMOJI_CLIPBOARD, TRANSLATE_NOOP("Achievements", "Your Value: {0} (Best: {1})")},
};
std::string title = event->leaderboard->title;
std::string message = fmt::format(
TRANSLATE_FS("Achievements", "{}\nLeaderboard Position: {} of {}"),
fmt::format(fmt::runtime(Host::TranslateToStringView(
"Achievements",
value_strings[std::min<u8>(event->leaderboard->format, NUM_RC_CLIENT_LEADERBOARD_FORMATS - 1)])),
event->leaderboard_scoreboard->submitted_score, event->leaderboard_scoreboard->best_score),
event->leaderboard_scoreboard->new_rank, event->leaderboard_scoreboard->num_entries);
"{} {}\n" ICON_EMOJI_BAR_CHART " {}",
value_strings[std::min<u8>(event->leaderboard->format, NUM_RC_CLIENT_LEADERBOARD_FORMATS - 1)][0],
TinyString::from_format(
fmt::runtime(Host::TranslateToStringView(
"Achievements",
value_strings[std::min<u8>(event->leaderboard->format, NUM_RC_CLIENT_LEADERBOARD_FORMATS - 1)][1])),
event->leaderboard_scoreboard->submitted_score, event->leaderboard_scoreboard->best_score),
TinyString::from_format(TRANSLATE_FS("Achievements", "Your Position: {0} of {1}"),
event->leaderboard_scoreboard->new_rank, event->leaderboard_scoreboard->num_entries));
FullscreenUI::AddAchievementNotification(fmt::format("leaderboard_{}", event->leaderboard->id),
static_cast<float>(g_settings.achievements_leaderboard_duration),
s_state.game_icon, std::move(title), std::move(message), {});
s_state.game_icon, std::string(event->leaderboard->title),
std::move(message), ICON_EMOJI_CHART_UPWARDS_TREND,
LEADERBOARD_NOTIFICATION_MIN_WIDTH);
}
}

View File

@@ -9,12 +9,14 @@
#include <span>
#include <string>
#include <string_view>
#include <vector>
namespace Achievements {
static constexpr float INDICATOR_FADE_IN_TIME = 0.2f;
static constexpr float INDICATOR_FADE_OUT_TIME = 0.4f;
inline constexpr float INDICATOR_FADE_IN_TIME = 0.2f;
inline constexpr float INDICATOR_FADE_OUT_TIME = 0.4f;
extern const std::string_view NOTIFICATION_SPINNER_NOTE;
struct LeaderboardTrackerIndicator
{

View File

@@ -59,6 +59,7 @@ struct Notification
float duration;
float target_y;
float last_y;
float min_width;
};
struct PauseMenuAchievementInfo
@@ -226,7 +227,7 @@ void FullscreenUI::DrawAchievementsOverlays()
}
void FullscreenUI::AddAchievementNotification(std::string key, float duration, std::string image_path,
std::string title, std::string text, std::string note)
std::string title, std::string text, std::string note, float min_width)
{
const bool prev_had_notifications = s_achievements_locals.notifications.empty();
const Timer::Value current_time = Timer::GetCurrentValue();
@@ -242,6 +243,7 @@ void FullscreenUI::AddAchievementNotification(std::string key, float duration, s
it->text = std::move(text);
it->note = std::move(note);
it->badge_path = std::move(image_path);
it->min_width = min_width;
// Don't fade it in again
const float time_passed = static_cast<float>(Timer::ConvertValueToSeconds(current_time - it->start_time));
@@ -263,6 +265,7 @@ void FullscreenUI::AddAchievementNotification(std::string key, float duration, s
notif.move_time = current_time;
notif.target_y = -1.0f;
notif.last_y = -1.0f;
notif.min_width = min_width;
s_achievements_locals.notifications.push_back(std::move(notif));
if (!prev_had_notifications)
@@ -288,6 +291,7 @@ void FullscreenUI::DrawNotifications(NotificationLayout& layout)
const float max_text_width = max_width - badge_size - (horizontal_padding * 2.0f) - horizontal_spacing;
const float min_height = (vertical_padding * 2.0f) + badge_size;
const float rounding = FullscreenUI::LayoutScale(20.0f);
const float spinner_size = FullscreenUI::LayoutScale(16.0f);
const float min_rounded_width = rounding * 2.0f;
ImFont*& font = UIStyle.Font;
@@ -295,8 +299,9 @@ void FullscreenUI::DrawNotifications(NotificationLayout& layout)
const float& title_font_weight = UIStyle.BoldFontWeight;
const float& text_font_size = UIStyle.MediumFontSize;
const float& text_font_weight = UIStyle.NormalFontWeight;
const float& note_font_size = UIStyle.MediumFontSize;
const float& note_font_weight = UIStyle.BoldFontWeight;
const float& note_text_size = UIStyle.MediumFontSize;
const float& note_text_weight = UIStyle.BoldFontWeight;
const float& note_icon_size = UIStyle.LargeFontSize;
const ImVec4 left_background_color = DarkerColor(UIStyle.ToastBackgroundColor, 1.3f);
const ImVec4 right_background_color = DarkerColor(UIStyle.ToastBackgroundColor, 0.8f);
@@ -313,9 +318,16 @@ void FullscreenUI::DrawNotifications(NotificationLayout& layout)
}
// place note to the right of the title
const ImVec2 note_size = notif.note.empty() ? ImVec2() :
font->CalcTextSizeA(note_font_size, note_font_weight, FLT_MAX, 0.0f,
IMSTR_START_END(notif.note));
const bool is_spinner = (notif.note == Achievements::NOTIFICATION_SPINNER_NOTE);
const bool is_icon_note =
(!is_spinner && !notif.note.empty() && (StringUtil::GetUTF8CharacterCount(notif.note) == 1));
const float note_font_size = is_spinner ? spinner_size : (is_icon_note ? note_icon_size : note_text_size);
const float note_font_weight = is_icon_note ? UIStyle.NormalFontWeight : note_text_weight;
const ImVec2 note_size = is_spinner ?
LayoutScale(note_font_size, note_font_size) :
(notif.note.empty() ? ImVec2() :
font->CalcTextSizeA(note_font_size, note_font_weight, FLT_MAX,
0.0f, IMSTR_START_END(notif.note)));
const ImVec2 title_size = font->CalcTextSizeA(title_font_size, title_font_weight, max_text_width - note_size.x,
max_text_width - note_size.x, IMSTR_START_END(notif.title));
const ImVec2 text_size = font->CalcTextSizeA(text_font_size, text_font_weight, max_text_width, max_text_width,
@@ -325,7 +337,7 @@ void FullscreenUI::DrawNotifications(NotificationLayout& layout)
std::max((horizontal_padding * 2.0f) + badge_size + horizontal_spacing +
ImCeil(std::max(title_size.x + (notif.note.empty() ? 0.0f : (larger_horizontal_spacing + note_size.x)),
text_size.x)),
min_width);
std::max(LayoutScale(notif.min_width), min_width));
const float box_height =
std::max((vertical_padding * 2.0f) + ImCeil(title_size.y) + vertical_spacing + ImCeil(text_size.y), min_height);
@@ -401,7 +413,27 @@ void FullscreenUI::DrawNotifications(NotificationLayout& layout)
RenderShadowedTextClipped(dl, font, text_font_size, text_font_weight, text_bb.Min, text_bb.Max, text_col,
notif.text, &text_size, ImVec2(0.0f, 0.0f), max_text_width, &text_bb);
if (!notif.note.empty())
if (notif.note == Achievements::NOTIFICATION_SPINNER_NOTE)
{
// based on https://github.com/ocornut/imgui/issues/1901
static constexpr u32 num_segments = 30;
const float radius = ImFloor(note_size.x * 0.5f);
const float thickness = LayoutScale(4.0f);
const ImVec2 pos = ImVec2((box_min.x + box_width) - horizontal_padding - note_size.x + radius,
box_min.y + vertical_padding + radius);
const float start =
std::abs(ImSin(static_cast<float>(GImGui->Time * 1.8f)) * static_cast<float>(num_segments - 5));
const float a_min = IM_PI * 2.0f * start / static_cast<float>(num_segments);
const float a_max = IM_PI * 2.0f * (static_cast<float>(num_segments - 3) / static_cast<float>(num_segments));
for (u32 i = 0; i < num_segments; i++)
{
const float a = a_min + ((float)i / (float)num_segments) * (a_max - a_min);
dl->PathLineTo(ImVec2(pos.x + ImCos(static_cast<float>(a + GImGui->Time * 8.0f)) * radius,
pos.y + ImSin(static_cast<float>(a + GImGui->Time * 8.0f)) * radius));
}
dl->PathStroke(title_col, false, thickness);
}
else if (!notif.note.empty())
{
const ImVec2 note_pos =
ImVec2((box_min.x + box_width) - horizontal_padding - note_size.x, box_min.y + vertical_padding);

View File

@@ -121,7 +121,7 @@ bool IsInputBindingDialogOpen();
/// Schedules an achievement notification to be shown.
void AddAchievementNotification(std::string key, float duration, std::string image_path, std::string title,
std::string text, std::string note);
std::string text, std::string note = {}, float min_width = 0.0f);
/// Draws ImGui overlays when ingame.
void DrawAchievementsOverlays();

View File

@@ -478,18 +478,18 @@ Fecha de creación del token de acceso: %2.</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1461"/>
<source>Your Time: {}{}</source>
<translation>Tu tiempo: {}{}</translation>
<source>Your Time: {}</source>
<translation>Tu tiempo: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1462"/>
<source>Your Score: {}{}</source>
<translation>Tu puntuación: {}{}</translation>
<source>Your Score: {}</source>
<translation>Tu puntuación: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1463"/>
<source>Your Value: {}{}</source>
<translation>Tu valor: {}{}</translation>
<source>Your Value: {}</source>
<translation>Tu valor: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1471"/>
@@ -498,25 +498,23 @@ Fecha de creación del token de acceso: %2.</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1490"/>
<source>Your Time: {} (Best: {})</source>
<translation>Tu tiempo: {} (Mejor: {})</translation>
<source>Your Time: {0} (Best: {1})</source>
<translation>Tu tiempo: {0} (Mejor: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1491"/>
<source>Your Score: {} (Best: {})</source>
<translation>Tu puntuación: {} (Mejor: {})</translation>
<source>Your Score: {0} (Best: {1})</source>
<translation>Tu puntuación: {0} (Mejor: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1492"/>
<source>Your Value: {} (Best: {})</source>
<translation>Tu valor: {} (Mejor: {})</translation>
<source>Your Value: {0} (Best: {1})</source>
<translation>Tu valor: {0} (Mejor: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1497"/>
<source>{}
Leaderboard Position: {} of {}</source>
<translation>{}
Posición en tabla: {} de {}</translation>
<source>Leaderboard Position: {0} of {1}</source>
<translation>Posición en tabla: {0} de {1}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1581"/>

View File

@@ -419,18 +419,18 @@ Token de inicio de sesión generado en %2.</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1508"/>
<source>Your Time: {}{}</source>
<translation>Tu tiempo: {}{}</translation>
<source>Your Time: {}</source>
<translation>Tu tiempo: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1509"/>
<source>Your Score: {}{}</source>
<translation>Tu puntuación: {}{}</translation>
<source>Your Score: {}</source>
<translation>Tu puntuación: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1510"/>
<source>Your Value: {}{}</source>
<translation>Tu valor: {}{}</translation>
<source>Your Value: {}</source>
<translation>Tu valor: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1519"/>
@@ -439,25 +439,23 @@ Token de inicio de sesión generado en %2.</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1543"/>
<source>Your Time: {} (Best: {})</source>
<translation>Tu tiempo: {} (Mejor: {})</translation>
<source>Your Time: {0} (Best: {1})</source>
<translation>Tu tiempo: {0} (Mejor: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1544"/>
<source>Your Score: {} (Best: {})</source>
<translation>Tu puntuación {} (Mejor: {})</translation>
<source>Your Score: {0} (Best: {1})</source>
<translation>Tu puntuación {0} (Mejor: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1545"/>
<source>Your Value: {} (Best: {})</source>
<translation>Tu valor: {} (Mejor: {})</translation>
<source>Your Value: {0} (Best: {1})</source>
<translation>Tu valor: {0} (Mejor: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1550"/>
<source>{}
Leaderboard Position: {} of {}</source>
<translation>{}
Posición en tabla: {} de {}</translation>
<source>Leaderboard Position: {0} of {1}</source>
<translation>Posición en tabla: {0} de {1}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1680"/>

View File

@@ -507,13 +507,13 @@ Pesan yang belum dibaca: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1678"/>
<source>Your Score: {}{}</source>
<translation>Skor Anda: {} {}</translation>
<source>Your Score: {}</source>
<translation>Skor Anda: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1679"/>
<source>Your Value: {}{}</source>
<translation>Nilai Anda: {} {}</translation>
<source>Your Value: {}</source>
<translation>Nilai Anda: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1688"/>
@@ -522,25 +522,23 @@ Pesan yang belum dibaca: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1712"/>
<source>Your Time: {} (Best: {})</source>
<translation>Waktu Anda: {} (Terbaik: {})</translation>
<source>Your Time: {0} (Best: {1})</source>
<translation>Waktu Anda: {0} (Terbaik: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1713"/>
<source>Your Score: {} (Best: {})</source>
<translation>Skor Anda: {} (Terbaik: {})</translation>
<source>Your Score: {0} (Best: {1})</source>
<translation>Skor Anda: {0} (Terbaik: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1714"/>
<source>Your Value: {} (Best: {})</source>
<translation>Nilai Anda: {} (Terbaik: {})</translation>
<source>Your Value: {0} (Best: {1})</source>
<translation>Nilai Anda: {0} (Terbaik: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1719"/>
<source>{}
Leaderboard Position: {} of {}</source>
<translation>{}
Posisi Papan Pencapaian: {} of {}</translation>
<source>Leaderboard Position: {0} of {1}</source>
<translation>Posisi Papan Pencapaian: {0} of {1}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1853"/>

View File

@@ -432,13 +432,13 @@ Token di accesso generato il %2.</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1140"/>
<source>Your Score: {}{}</source>
<translation>Il tuo Punteggio: {}{}</translation>
<source>Your Score: {}</source>
<translation>Il tuo Punteggio: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1141"/>
<source>Your Value: {}{}</source>
<translation>Il tuo Valore: {}{}</translation>
<source>Your Value: {}</source>
<translation>Il tuo Valore: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1150"/>
@@ -447,25 +447,23 @@ Token di accesso generato il %2.</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1169"/>
<source>Your Time: {} (Best: {})</source>
<translation>Il tuo Tempo: {} (Migliore: {})</translation>
<source>Your Time: {0} (Best: {1})</source>
<translation>Il tuo Tempo: {0} (Migliore: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1170"/>
<source>Your Score: {} (Best: {})</source>
<translation>Il tuo Punteggio: {} (Migliore: {})</translation>
<source>Your Score: {0} (Best: {1})</source>
<translation>Il tuo Punteggio: {0} (Migliore: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1171"/>
<source>Your Value: {} (Best: {})</source>
<translation>Il tuo Valore: {} (Migliore: {})</translation>
<source>Your Value: {0} (Best: {1})</source>
<translation>Il tuo Valore: {0} (Migliore: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1176"/>
<source>{}
Leaderboard Position: {} of {}</source>
<translation>{}
Posizione in Classifica: {} di {}</translation>
<source>Leaderboard Position: {0} of {1}</source>
<translation>Posizione in Classifica: {0} di {1}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1306"/>

View File

@@ -497,25 +497,23 @@ Login token generated on %2.</source>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1610"/>
<source>Your Time: {} (Best: {})</source>
<translation> : {}( : {})</translation>
<source>Your Time: {0} (Best: {1})</source>
<translation> : {0}( : {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1611"/>
<source>Your Score: {} (Best: {})</source>
<translation> : {}( : {})</translation>
<source>Your Score: {0} (Best: {1})</source>
<translation> : {0}( : {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1612"/>
<source>Your Value: {} (Best: {})</source>
<translation> : {}( : {})</translation>
<source>Your Value: {0} (Best: {1})</source>
<translation> : {0}( : {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1617"/>
<source>{}
Leaderboard Position: {} of {}</source>
<translation>{}
: {} {}</translation>
<source>Leaderboard Position: {0} of {1}</source>
<translation> : {0} {1}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1795"/>

View File

@@ -441,18 +441,18 @@ Token logowania wygenerowany %2.</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1338"/>
<source>Your Time: {}{}</source>
<translation>Twój czas: {}{}</translation>
<source>Your Time: {}</source>
<translation>Twój czas: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1339"/>
<source>Your Score: {}{}</source>
<translation>Twój wynik: {}{}</translation>
<source>Your Score: {}</source>
<translation>Twój wynik: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1340"/>
<source>Your Value: {}{}</source>
<translation>Twój wartość: {}{}</translation>
<source>Your Value: {}</source>
<translation>Twój wartość: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1349"/>
@@ -461,25 +461,23 @@ Token logowania wygenerowany %2.</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1368"/>
<source>Your Time: {} (Best: {})</source>
<translation>Twój czas: {} (Najlepszy: {})</translation>
<source>Your Time: {0} (Best: {1})</source>
<translation>Twój czas: {0} (Najlepszy: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1369"/>
<source>Your Score: {} (Best: {})</source>
<translation>Twój wynik: {} (Najlepszy: {})</translation>
<source>Your Score: {0} (Best: {1})</source>
<translation>Twój wynik: {0} (Najlepszy: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1370"/>
<source>Your Value: {} (Best: {})</source>
<translation>Twój watość: {} (Najlepszy: {})</translation>
<source>Your Value: {0} (Best: {1})</source>
<translation>Twój watość: {0} (Najlepszy: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1375"/>
<source>{}
Leaderboard Position: {} of {}</source>
<translation>{}
Pozycja w tabeli wyników: {} z {}</translation>
<source>Leaderboard Position: {0} of {1}</source>
<translation>Pozycja w tabeli wyników: {0} z {1}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1503"/>

View File

@@ -495,25 +495,23 @@ Token gerado %2.</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1494"/>
<source>Your Time: {} (Best: {})</source>
<translation>Seu tempo: {} (melhor: {})</translation>
<source>Your Time: {0} (Best: {1})</source>
<translation>Seu tempo: {0} (melhor: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1495"/>
<source>Your Score: {} (Best: {})</source>
<translation>Sua pontuação: {} (melhor: {})</translation>
<source>Your Score: {0} (Best: {1})</source>
<translation>Sua pontuação: {0} (melhor: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1496"/>
<source>Your Value: {} (Best: {})</source>
<translation>Sua pontuação: {} (melhor: {})</translation>
<source>Your Value: {0} (Best: {1})</source>
<translation>Sua pontuação: {0} (melhor: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1501"/>
<source>{}
Leaderboard Position: {} of {}</source>
<translation>{}
Posição na tabela de classificação: {} de {}</translation>
<source>Leaderboard Position: {0} of {1}</source>
<translation>Posição na tabela de classificação: {0} de {1}</translation>
</message>
<message>
<source>Server error in {}:
@@ -762,18 +760,18 @@ Mensagens não lidas: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1465"/>
<source>Your Time: {}{}</source>
<translation>Seu tempo: {}{}</translation>
<source>Your Time: {}</source>
<translation>Seu tempo: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1466"/>
<source>Your Score: {}{}</source>
<translation>Sua pontuação: {}{}</translation>
<source>Your Score: {}</source>
<translation>Sua pontuação: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1467"/>
<source>Your Value: {}{}</source>
<translation>Sua pontuação: {}{}</translation>
<source>Your Value: {}</source>
<translation>Sua pontuação: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1475"/>

View File

@@ -430,18 +430,18 @@ Código de auteticação gerado em %2.</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1128"/>
<source>Your Time: {}{}</source>
<translation>O teu tempo: {}{}</translation>
<source>Your Time: {}</source>
<translation>O teu tempo: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1129"/>
<source>Your Score: {}{}</source>
<translation>A tua pontuação: {}{}</translation>
<source>Your Score: {}</source>
<translation>A tua pontuação: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1130"/>
<source>Your Value: {}{}</source>
<translation>O teu valor: {}{}</translation>
<source>Your Value: {}</source>
<translation>O teu valor: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1139"/>
@@ -450,25 +450,23 @@ Código de auteticação gerado em %2.</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1158"/>
<source>Your Time: {} (Best: {})</source>
<translation>O teu tempo: {} (Melhor: {})</translation>
<source>Your Time: {0} (Best: {1})</source>
<translation>O teu tempo: {0} (Melhor: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1159"/>
<source>Your Score: {} (Best: {})</source>
<translation>A tua pontuação: {} (Melhor: {})</translation>
<source>Your Score: {0} (Best: {1})</source>
<translation>A tua pontuação: {0} (Melhor: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1160"/>
<source>Your Value: {} (Best: {})</source>
<translation>O teu valor: {} (Melhor: {})</translation>
<source>Your Value: {0} (Best: {1})</source>
<translation>O teu valor: {0} (Melhor: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1165"/>
<source>{}
Leaderboard Position: {} of {}</source>
<translation>{}
Posição na classificação: {} de {}</translation>
<source>Leaderboard Position: {0} of {1}</source>
<translation>Posição na classificação: {0} de {1}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1295"/>

View File

@@ -486,18 +486,18 @@ Login token generated on %2.</source>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1421"/>
<source>Your Time: {}{}</source>
<translation>Ваше время: {}{}</translation>
<source>Your Time: {}</source>
<translation>Ваше время: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1422"/>
<source>Your Score: {}{}</source>
<translation>Ваш результат: {}{}</translation>
<source>Your Score: {}</source>
<translation>Ваш результат: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1423"/>
<source>Your Value: {}{}</source>
<translation type="unfinished">Ваше значение: {}{}</translation>
<source>Your Value: {}</source>
<translation type="unfinished">Ваше значение: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1431"/>
@@ -506,25 +506,23 @@ Login token generated on %2.</source>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1450"/>
<source>Your Time: {} (Best: {})</source>
<translation>Ваше время: {} (Лучший результат: {})</translation>
<source>Your Time: {0} (Best: {1})</source>
<translation>Ваше время: {0} (Лучший результат: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1451"/>
<source>Your Score: {} (Best: {})</source>
<translation>Ваш результат: {} (Лучший: {})</translation>
<source>Your Score: {0} (Best: {1})</source>
<translation>Ваш результат: {0} (Лучший: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1452"/>
<source>Your Value: {} (Best: {})</source>
<translation>Ваше значение: {} (Лучший: {})</translation>
<source>Your Value: {0} (Best: {1})</source>
<translation>Ваше значение: {0} (Лучший: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1457"/>
<source>{}
Leaderboard Position: {} of {}</source>
<translation>{}
Позиция в списке лидеров: {} из {}</translation>
<source>Leaderboard Position: {0} of {1}</source>
<translation>Позиция в списке лидеров: {0} из {1}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1541"/>

View File

@@ -408,30 +408,28 @@ Inloggningstoken genererades %2.</translation>
<translation>Ledartavleförsök misslyckades.</translation>
</message>
<message>
<source>Your Score: {}{}</source>
<translation>Dina poäng: {}{}</translation>
<source>Your Score: {}</source>
<translation>Dina poäng: {}</translation>
</message>
<message>
<source> (Submitting)</source>
<translation> (Skickar in)</translation>
</message>
<message>
<source>Your Time: {} (Best: {})</source>
<translation>Din tid: {} (Bästa: {})</translation>
<source>Your Time: {0} (Best: {1})</source>
<translation>Din tid: {0} (Bästa: {1})</translation>
</message>
<message>
<source>Your Score: {} (Best: {})</source>
<translation>Dina poäng: {} (Bästa: {})</translation>
<source>Your Score: {0} (Best: {1})</source>
<translation>Dina poäng: {0} (Bästa: {1})</translation>
</message>
<message>
<source>Your Value: {} (Best: {})</source>
<translation>Ditt värde: {} (Bästa: {})</translation>
<source>Your Value: {0} (Best: {1})</source>
<translation>Ditt värde: {0} (Bästa: {1})</translation>
</message>
<message>
<source>{}
Leaderboard Position: {} of {}</source>
<translation>{}
Position ledartavlan: {} av {}</translation>
<source>Leaderboard Position: {0} of {1}</source>
<translation>Position ledartavlan: {0} av {1}</translation>
</message>
<message>
<source>Server error in {}:

View File

@@ -429,18 +429,18 @@ Tek kullanımlık giriş kodu (access token) oluşturulma tarihi: %2.</translati
</message>
<message>
<location filename="../../core/achievements.cpp" line="1677"/>
<source>Your Time: {}{}</source>
<translation>Süren: {}{}</translation>
<source>Your Time: {}</source>
<translation>Süren: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1678"/>
<source>Your Score: {}{}</source>
<translation>Skorun: {}{}</translation>
<source>Your Score: {}</source>
<translation>Skorun: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1679"/>
<source>Your Value: {}{}</source>
<translation>Puanın: {}{}</translation>
<source>Your Value: {}</source>
<translation>Puanın: {}}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1688"/>
@@ -449,25 +449,23 @@ Tek kullanımlık giriş kodu (access token) oluşturulma tarihi: %2.</translati
</message>
<message>
<location filename="../../core/achievements.cpp" line="1712"/>
<source>Your Time: {} (Best: {})</source>
<translation>Süren: {} (Rekorun: {})</translation>
<source>Your Time: {0} (Best: {1})</source>
<translation>Süren: {0} (Rekorun: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1713"/>
<source>Your Score: {} (Best: {})</source>
<translation>Skorun: {} (Rekorun: {})</translation>
<source>Your Score: {0} (Best: {1})</source>
<translation>Skorun: {0} (Rekorun: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1714"/>
<source>Your Value: {} (Best: {})</source>
<translation>Puanın: {} (Rekorun: {})</translation>
<source>Your Value: {0} (Best: {1})</source>
<translation>Puanın: {0} (Rekorun: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1719"/>
<source>{}
Leaderboard Position: {} of {}</source>
<translation>{}
Lider Tahtasındaki Yer : {} inci {}</translation>
<source>Leaderboard Position: {0} of {1}</source>
<translation>Lider Tahtasındaki Yer : {0} inci {1}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1853"/>

View File

@@ -527,13 +527,13 @@ Login token generated at:</source>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1422"/>
<source>Your Score: {}{}</source>
<translation>: {}{}</translation>
<source>Your Score: {}</source>
<translation>: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1423"/>
<source>Your Value: {}{}</source>
<translation>: {}{}</translation>
<source>Your Value: {}</source>
<translation>: {}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1431"/>
@@ -542,25 +542,23 @@ Login token generated at:</source>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1450"/>
<source>Your Time: {} (Best: {})</source>
<translation>: {} (: {})</translation>
<source>Your Time: {0} (Best: {1})</source>
<translation>: {0} (: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1451"/>
<source>Your Score: {} (Best: {})</source>
<translation>: {} (: {})</translation>
<source>Your Score: {0} (Best: {1})</source>
<translation>: {0} (: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1452"/>
<source>Your Value: {} (Best: {})</source>
<translation>: {} (: {})</translation>
<source>Your Value: {0} (Best: {1})</source>
<translation>: {0} (: {1})</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1457"/>
<source>{}
Leaderboard Position: {} of {}</source>
<translation>{}
: {}/{}</translation>
<source>Leaderboard Position: {0} of {1}</source>
<translation>: {0}/{1}</translation>
</message>
<message>
<location filename="../../core/achievements.cpp" line="1541"/>