Achievements: Add point count to unlock popup

pull/3594/head
Stenzek 3 weeks ago
parent b237604ac7
commit 5818a05be3
No known key found for this signature in database

@ -1263,16 +1263,16 @@ void Achievements::DisplayAchievementSummary()
FullscreenUI::AddNotification("AchievementsSummary",
IsHardcoreModeActive() ? ACHIEVEMENT_SUMMARY_NOTIFICATION_TIME_HC :
ACHIEVEMENT_SUMMARY_NOTIFICATION_TIME,
s_state.game_title, std::string(summary), s_state.game_icon);
s_state.game_icon, s_state.game_title, std::string(summary), {});
if (s_state.game_summary.num_unsupported_achievements > 0)
{
FullscreenUI::AddNotification(
"UnsupportedAchievements", ACHIEVEMENT_SUMMARY_UNSUPPORTED_TIME,
"UnsupportedAchievements", ACHIEVEMENT_SUMMARY_UNSUPPORTED_TIME, "images/warning.svg",
TRANSLATE_STR("Achievements", "Unsupported Achievements"),
TRANSLATE_PLURAL_STR("Achievements", "%n achievements are not supported by DuckStation.", "Achievement popup",
s_state.game_summary.num_unsupported_achievements),
"images/warning.svg");
{});
}
}
@ -1312,9 +1312,12 @@ void Achievements::HandleUnlockEvent(const rc_client_event_t* event)
else
title = cheevo->title;
std::string note = fmt::format(ICON_EMOJI_TROPHY " {}", cheevo->points);
FullscreenUI::AddNotification(fmt::format("achievement_unlock_{}", cheevo->id),
static_cast<float>(g_settings.achievements_notification_duration), std::move(title),
cheevo->description, GetAchievementBadgePath(cheevo, false));
static_cast<float>(g_settings.achievements_notification_duration),
GetAchievementBadgePath(cheevo, false), std::move(title),
std::string(cheevo->description), std::move(note));
}
if (g_settings.achievements_sound_effects)
@ -1333,9 +1336,10 @@ void Achievements::HandleGameCompleteEvent(const rc_client_event_t* event)
TRANSLATE_PLURAL_STR("Achievements", "%n achievements", "Mastery popup",
s_state.game_summary.num_unlocked_achievements),
TRANSLATE_PLURAL_STR("Achievements", "%n points", "Achievement points", s_state.game_summary.points_unlocked));
std::string note = fmt::format(ICON_EMOJI_TROPHY " {}", s_state.game_summary.points_unlocked);
FullscreenUI::AddNotification("achievement_mastery", GAME_COMPLETE_NOTIFICATION_TIME, s_state.game_title,
std::move(message), s_state.game_icon);
FullscreenUI::AddNotification("achievement_mastery", GAME_COMPLETE_NOTIFICATION_TIME, s_state.game_icon,
s_state.game_title, std::move(message), std::move(note));
}
}
@ -1364,8 +1368,8 @@ void Achievements::HandleSubsetCompleteEvent(const rc_client_event_t* event)
s_state.game_summary.num_unlocked_achievements),
TRANSLATE_PLURAL_STR("Achievements", "%n points", "Achievement points", s_state.game_summary.points_unlocked));
FullscreenUI::AddNotification("achievement_mastery", GAME_COMPLETE_NOTIFICATION_TIME, event->subset->title,
std::move(message), std::move(badge_path));
FullscreenUI::AddNotification("achievement_mastery", GAME_COMPLETE_NOTIFICATION_TIME, std::move(badge_path),
std::string(event->subset->title), std::move(message), {});
}
}
@ -1375,9 +1379,9 @@ void Achievements::HandleLeaderboardStartedEvent(const rc_client_event_t* event)
if (g_settings.achievements_leaderboard_notifications)
{
FullscreenUI::AddNotification(fmt::format("leaderboard_{}", event->leaderboard->id),
LEADERBOARD_STARTED_NOTIFICATION_TIME, event->leaderboard->title,
TRANSLATE_STR("Achievements", "Leaderboard attempt started."), s_state.game_icon);
FullscreenUI::AddNotification(
fmt::format("leaderboard_{}", event->leaderboard->id), LEADERBOARD_STARTED_NOTIFICATION_TIME, s_state.game_icon,
std::string(event->leaderboard->title), TRANSLATE_STR("Achievements", "Leaderboard attempt started."), {});
}
}
@ -1387,9 +1391,9 @@ void Achievements::HandleLeaderboardFailedEvent(const rc_client_event_t* event)
if (g_settings.achievements_leaderboard_notifications)
{
FullscreenUI::AddNotification(fmt::format("leaderboard_{}", event->leaderboard->id),
LEADERBOARD_FAILED_NOTIFICATION_TIME, event->leaderboard->title,
TRANSLATE_STR("Achievements", "Leaderboard attempt failed."), s_state.game_icon);
FullscreenUI::AddNotification(
fmt::format("leaderboard_{}", event->leaderboard->id), LEADERBOARD_FAILED_NOTIFICATION_TIME, s_state.game_icon,
std::string(event->leaderboard->title), TRANSLATE_STR("Achievements", "Leaderboard attempt failed."), {});
}
}
@ -1413,8 +1417,8 @@ void Achievements::HandleLeaderboardSubmittedEvent(const rc_client_event_t* even
g_settings.achievements_spectator_mode ? std::string_view() : TRANSLATE_SV("Achievements", " (Submitting)"));
FullscreenUI::AddNotification(fmt::format("leaderboard_{}", event->leaderboard->id),
static_cast<float>(g_settings.achievements_leaderboard_duration),
event->leaderboard->title, std::move(message), s_state.game_icon);
static_cast<float>(g_settings.achievements_leaderboard_duration), s_state.game_icon,
std::string(event->leaderboard->title), std::move(message), {});
}
if (g_settings.achievements_sound_effects)
@ -1444,8 +1448,8 @@ void Achievements::HandleLeaderboardScoreboardEvent(const rc_client_event_t* eve
event->leaderboard_scoreboard->new_rank, event->leaderboard_scoreboard->num_entries);
FullscreenUI::AddNotification(fmt::format("leaderboard_{}", event->leaderboard->id),
static_cast<float>(g_settings.achievements_leaderboard_duration), std::move(title),
std::move(message), s_state.game_icon);
static_cast<float>(g_settings.achievements_leaderboard_duration), s_state.game_icon,
std::move(title), std::move(message), {});
}
}
@ -1518,11 +1522,11 @@ void Achievements::HandleAchievementChallengeIndicatorShowEvent(const rc_client_
// we still track these even if the option is disabled, so that they can be displayed in the pause menu
if (g_settings.achievements_challenge_indicator_mode == AchievementChallengeIndicatorMode::Notification)
{
FullscreenUI::AddNotification(
fmt::format("AchievementChallenge{}", event->achievement->id), CHALLENGE_STARTED_NOTIFICATION_TIME,
fmt::format(TRANSLATE_FS("Achievements", "Challenge Started: {}"),
event->achievement->title ? event->achievement->title : ""),
event->achievement->description ? event->achievement->description : "", std::move(badge_path));
FullscreenUI::AddNotification(fmt::format("AchievementChallenge{}", event->achievement->id),
CHALLENGE_STARTED_NOTIFICATION_TIME, std::move(badge_path),
fmt::format(TRANSLATE_FS("Achievements", "Challenge Started: {}"),
event->achievement->title ? event->achievement->title : ""),
event->achievement->description, {});
}
s_state.active_challenge_indicators.push_back(
@ -1549,10 +1553,10 @@ void Achievements::HandleAchievementChallengeIndicatorHideEvent(const rc_client_
{
FullscreenUI::AddNotification(fmt::format("AchievementChallenge{}", event->achievement->id),
CHALLENGE_FAILED_NOTIFICATION_TIME,
GetAchievementBadgePath(event->achievement, false),
fmt::format(TRANSLATE_FS("Achievements", "Challenge Failed: {}"),
event->achievement->title ? event->achievement->title : ""),
event->achievement->description ? event->achievement->description : "",
GetAchievementBadgePath(event->achievement, false));
event->achievement->description, {});
}
if (g_settings.achievements_challenge_indicator_mode == AchievementChallengeIndicatorMode::Notification ||
g_settings.achievements_challenge_indicator_mode == AchievementChallengeIndicatorMode::Disabled)
@ -1946,12 +1950,12 @@ void Achievements::ClientLoginWithTokenCallback(int result, const char* error_me
if (System::IsValid())
{
FullscreenUI::AddNotification(
"AchievementsLoginFailed", Host::OSD_ERROR_DURATION,
"AchievementsLoginFailed", Host::OSD_ERROR_DURATION, "images/warning.svg",
TRANSLATE_STR("Achievements", "RetroAchievements Login Failed"),
fmt::format(
TRANSLATE_FS("Achievements", "Achievement unlocks will not be submitted for this session.\nError: {}"),
error_message),
"images/warning.svg");
{});
}
return;
@ -1990,8 +1994,8 @@ void Achievements::FinishLogin()
std::string summary = fmt::format(TRANSLATE_FS("Achievements", "Score: {} ({} softcore)\nUnread messages: {}"),
user->score, user->score_softcore, user->num_unread_messages);
FullscreenUI::AddNotification("achievements_login", LOGIN_NOTIFICATION_TIME, user->display_name, std::move(summary),
s_state.user_badge_path);
FullscreenUI::AddNotification("achievements_login", LOGIN_NOTIFICATION_TIME, s_state.user_badge_path,
user->display_name, std::move(summary), {});
}
}

@ -139,6 +139,7 @@ struct Notification
std::string key;
std::string title;
std::string text;
std::string note;
std::string badge_path;
Timer::Value start_time;
Timer::Value move_time;
@ -4695,8 +4696,8 @@ void FullscreenUI::UpdateNotificationsRunIdle()
[]() { GPUThread::SetRunIdleReason(GPUThread::RunIdleReason::NotificationsActive, AreAnyNotificationsActive()); });
}
void FullscreenUI::AddNotification(std::string key, float duration, std::string title, std::string text,
std::string image_path)
void FullscreenUI::AddNotification(std::string key, float duration, std::string image_path, std::string title,
std::string text, std::string note)
{
const std::unique_lock lock(s_state.shared_state_mutex);
if (!s_state.has_initialized)
@ -4714,6 +4715,7 @@ void FullscreenUI::AddNotification(std::string key, float duration, std::string
it->duration = duration;
it->title = std::move(title);
it->text = std::move(text);
it->note = std::move(note);
it->badge_path = std::move(image_path);
// Don't fade it in again
@ -4730,6 +4732,7 @@ void FullscreenUI::AddNotification(std::string key, float duration, std::string
notif.duration = duration;
notif.title = std::move(title);
notif.text = std::move(text);
notif.note = std::move(note);
notif.badge_path = std::move(image_path);
notif.start_time = current_time;
notif.move_time = current_time;
@ -4761,12 +4764,13 @@ void FullscreenUI::DrawNotifications(ImVec2& position, float spacing)
const float shadow_size = FullscreenUI::LayoutScale(2.0f);
const float rounding = FullscreenUI::LayoutScale(20.0f);
ImFont* const title_font = UIStyle.Font;
const float title_font_size = UIStyle.LargeFontSize;
const float title_font_weight = UIStyle.BoldFontWeight;
ImFont* const text_font = UIStyle.Font;
const float text_font_size = UIStyle.MediumFontSize;
const float text_font_weight = UIStyle.NormalFontWeight;
ImFont*& font = UIStyle.Font;
const float& title_font_size = UIStyle.LargeFontSize;
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;
for (u32 index = 0; index < static_cast<u32>(s_state.notifications.size());)
{
@ -4778,10 +4782,14 @@ void FullscreenUI::DrawNotifications(ImVec2& position, float spacing)
continue;
}
const ImVec2 title_size = title_font->CalcTextSizeA(title_font_size, title_font_weight, max_text_width,
max_text_width, IMSTR_START_END(notif.title));
const ImVec2 text_size = text_font->CalcTextSizeA(text_font_size, text_font_weight, max_text_width, max_text_width,
IMSTR_START_END(notif.text));
// 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 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,
IMSTR_START_END(notif.text));
float box_width = std::max((horizontal_padding * 2.0f) + badge_size + horizontal_spacing +
ImCeil(std::max(title_size.x, text_size.x)),
@ -4860,14 +4868,22 @@ void FullscreenUI::DrawNotifications(ImVec2& position, float spacing)
const ImVec2 title_pos = ImVec2(badge_max.x + horizontal_spacing, box_min.y + vertical_padding);
const ImRect title_bb = ImRect(title_pos, title_pos + title_size);
RenderShadowedTextClipped(dl, title_font, title_font_size, title_font_weight, title_bb.Min, title_bb.Max, title_col,
notif.title, &title_size, ImVec2(0.0f, 0.0f), max_text_width, &title_bb);
RenderShadowedTextClipped(dl, font, title_font_size, title_font_weight, title_bb.Min, title_bb.Max, title_col,
notif.title, &title_size, ImVec2(0.0f, 0.0f), max_text_width - note_size.x, &title_bb);
const ImVec2 text_pos = ImVec2(badge_max.x + horizontal_spacing, title_bb.Max.y + vertical_spacing);
const ImRect text_bb = ImRect(text_pos, text_pos + text_size);
RenderShadowedTextClipped(dl, text_font, text_font_size, text_font_weight, text_bb.Min, text_bb.Max, text_col,
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())
{
const ImVec2 note_pos = ImVec2(box_max.x - horizontal_padding - note_size.x, box_min.y + vertical_padding);
const ImRect note_bb = ImRect(note_pos, note_pos + note_size);
RenderShadowedTextClipped(dl, font, note_font_size, note_font_weight, note_bb.Min, note_bb.Max, title_col,
notif.note, &note_size, ImVec2(0.0f, 0.0f), max_text_width, &note_bb);
}
if (clip_box)
dl->PopClipRect();

@ -491,7 +491,8 @@ bool IsLoadingScreenOpen();
void CloseLoadingScreen();
/// Notification and toast support.
void AddNotification(std::string key, float duration, std::string title, std::string text, std::string image_path);
void AddNotification(std::string key, float duration, std::string image_path, std::string title, std::string text,
std::string note);
void ShowToast(std::string title, std::string message, float duration = 10.0f);
// Wrapper for an animated popup dialog.

Loading…
Cancel
Save