Achievements: Display warning for unsupported achievements

pull/3514/head
Stenzek 2 months ago
parent 95ccd7cea2
commit 414ddf78cc
No known key found for this signature in database

@ -7,6 +7,7 @@
// List to use: https://www.freecodecamp.org/news/all-emojis-emoji-list-for-copy-and-paste/
#define ICON_EMOJI_WARNING "\xe2\x9a\xa0"
#define ICON_EMOJI_CHECKMARK_BUTTON "\xe2\x9c\x85"
#define ICON_EMOJI_OPTICAL_DISK "\xf0\x9f\x92\xbf"
#define ICON_EMOJI_FLOPPY_DISK "\xf0\x9f\x92\xbe"
#define ICON_EMOJI_INFORMATION "\xe2\x84\xb9"

@ -77,6 +77,7 @@ static constexpr u32 LEADERBOARD_ALL_FETCH_SIZE = 20;
static constexpr float LOGIN_NOTIFICATION_TIME = 5.0f;
static constexpr float ACHIEVEMENT_SUMMARY_NOTIFICATION_TIME = 5.0f;
static constexpr float ACHIEVEMENT_SUMMARY_NOTIFICATION_TIME_HC = 10.0f;
static constexpr float ACHIEVEMENT_SUMMARY_UNSUPPORTED_TIME = 12.0f;
static constexpr float GAME_COMPLETE_NOTIFICATION_TIME = 20.0f;
static constexpr float LEADERBOARD_STARTED_NOTIFICATION_TIME = 3.0f;
static constexpr float LEADERBOARD_FAILED_NOTIFICATION_TIME = 3.0f;
@ -1385,9 +1386,24 @@ void Achievements::DisplayAchievementSummary()
if (!FullscreenUI::Initialize())
return;
ImGuiFullscreen::AddNotification("achievement_summary", time, std::move(title), std::move(summary),
ImGuiFullscreen::AddNotification("AchievementsSummary", time, std::move(title), std::move(summary),
std::move(icon));
});
if (s_state.game_summary.num_unsupported_achievements > 0)
{
GPUThread::RunOnThread([num_unsupported = s_state.game_summary.num_unsupported_achievements]() mutable {
if (!FullscreenUI::Initialize())
return;
ImGuiFullscreen::AddNotification("UnsupportedAchievements", ACHIEVEMENT_SUMMARY_UNSUPPORTED_TIME,
TRANSLATE_STR("Achievements", "Unsupported Achievements"),
TRANSLATE_PLURAL_STR("Achievements",
"%n achievements are not supported by DuckStation.",
"Achievement popup", num_unsupported),
"images/warning.svg");
});
}
}
// Technically not going through the resource API, but since we're passing this to something else, we can't.
@ -2770,7 +2786,8 @@ void Achievements::DrawAchievementsWindow()
static constexpr float alpha = 0.8f;
static constexpr float heading_alpha = 0.95f;
const float heading_height_unscaled =
(s_state.game_summary.beaten_time > 0 || s_state.game_summary.completed_time) ? 122.0f : 102.0f;
((s_state.game_summary.beaten_time > 0 || s_state.game_summary.completed_time) ? 122.0f : 102.0f) +
((s_state.game_summary.num_unsupported_achievements > 0) ? 20.0f : 0.0f);
const ImVec4 background = ImGuiFullscreen::ModAlpha(UIStyle.BackgroundColor, alpha);
const ImVec4 heading_background = ImGuiFullscreen::ModAlpha(UIStyle.BackgroundColor, heading_alpha);
@ -2821,14 +2838,15 @@ void Achievements::DrawAchievementsWindow()
const ImRect summary_bb(ImVec2(left, top), ImVec2(right, top + UIStyle.MediumFontSize));
if (s_state.game_summary.num_core_achievements > 0)
{
text.assign(ICON_EMOJI_UNLOCKED " ");
if (s_state.game_summary.num_unlocked_achievements == s_state.game_summary.num_core_achievements)
{
text = TRANSLATE_PLURAL_SSTR("Achievements", "You have unlocked all achievements and earned %n points!",
"Point count", s_state.game_summary.points_unlocked);
text.append(TRANSLATE_PLURAL_SSTR("Achievements", "You have unlocked all achievements and earned %n points!",
"Point count", s_state.game_summary.points_unlocked));
}
else
{
text.format(TRANSLATE_FS("Achievements",
text.append_format(TRANSLATE_FS("Achievements",
"You have unlocked {0} of {1} achievements, earning {2} of {3} possible points."),
s_state.game_summary.num_unlocked_achievements, s_state.game_summary.num_core_achievements,
s_state.game_summary.points_unlocked, s_state.game_summary.points_core);
@ -2836,7 +2854,7 @@ void Achievements::DrawAchievementsWindow()
}
else
{
text.assign(TRANSLATE_SV("Achievements", "This game has no achievements."));
text.format(ICON_FA_BAN " {}", TRANSLATE_SV("Achievements", "This game has no achievements."));
}
top += UIStyle.MediumFontSize + spacing;
@ -2846,9 +2864,26 @@ void Achievements::DrawAchievementsWindow()
ImGui::GetColorU32(ImGuiFullscreen::DarkerColor(ImGui::GetStyle().Colors[ImGuiCol_Text])),
text, nullptr, ImVec2(0.0f, 0.0f), 0.0f, &summary_bb);
if (s_state.game_summary.num_unsupported_achievements)
{
text.format("{} {}", ICON_EMOJI_WARNING,
TRANSLATE_PLURAL_SSTR(
"Achievements", "%n achievements are not supported by DuckStation and cannot be unlocked.",
"Unsupported achievement count", s_state.game_summary.num_unsupported_achievements));
const ImRect unsupported_bb(ImVec2(left, top), ImVec2(right, top + UIStyle.MediumFontSize));
RenderShadowedTextClipped(
UIStyle.Font, UIStyle.MediumFontSize, UIStyle.BoldFontWeight, unsupported_bb.Min, unsupported_bb.Max,
ImGui::GetColorU32(ImGuiFullscreen::DarkerColor(ImGui::GetStyle().Colors[ImGuiCol_Text])), text, nullptr,
ImVec2(0.0f, 0.0f), 0.0f, &unsupported_bb);
top += UIStyle.MediumFontSize + spacing;
}
if (s_state.game_summary.beaten_time > 0 || s_state.game_summary.completed_time > 0)
{
text.clear();
text.assign(ICON_EMOJI_CHECKMARK_BUTTON " ");
if (s_state.game_summary.beaten_time > 0)
{
const std::string beaten_time =
@ -2857,19 +2892,19 @@ void Achievements::DrawAchievementsWindow()
{
const std::string completion_time =
Host::FormatNumber(Host::NumberFormatType::ShortDate, static_cast<s64>(s_state.game_summary.beaten_time));
text.format(TRANSLATE_FS("Achievements", "Game was beaten on {0}, and completed on {1}."), beaten_time,
completion_time);
text.append_format(TRANSLATE_FS("Achievements", "Game was beaten on {0}, and completed on {1}."), beaten_time,
completion_time);
}
else
{
text.format(TRANSLATE_FS("Achievements", "Game was beaten on {0}."), beaten_time);
text.append_format(TRANSLATE_FS("Achievements", "Game was beaten on {0}."), beaten_time);
}
}
else
{
const std::string completion_time =
Host::FormatNumber(Host::NumberFormatType::ShortDate, static_cast<s64>(s_state.game_summary.completed_time));
text.format(TRANSLATE_FS("Achievements", "Game was completed on {0}."), completion_time);
text.append_format(TRANSLATE_FS("Achievements", "Game was completed on {0}."), completion_time);
}
const ImRect beaten_bb(ImVec2(left, top), ImVec2(right, top + UIStyle.MediumFontSize));

@ -4,8 +4,8 @@
<context>
<name>AchievementSettingsWidget</name>
<message numerus="yes">
<location filename="../achievementsettingswidget.cpp" line="160"/>
<location filename="../achievementsettingswidget.cpp" line="167"/>
<location filename="../achievementsettingswidget.cpp" line="198"/>
<location filename="../achievementsettingswidget.cpp" line="205"/>
<source>%n seconds</source>
<translation>
<numerusform>%n second</numerusform>
@ -16,7 +16,7 @@
<context>
<name>Achievements</name>
<message numerus="yes">
<location filename="../../core/achievements.cpp" line="1401"/>
<location filename="../../core/achievements.cpp" line="1360"/>
<source>You have unlocked {} of %n achievements</source>
<comment>Achievement popup</comment>
<translation>
@ -25,7 +25,7 @@
</translation>
</message>
<message numerus="yes">
<location filename="../../core/achievements.cpp" line="1404"/>
<location filename="../../core/achievements.cpp" line="1363"/>
<source>and earned {} of %n points</source>
<comment>Achievement popup</comment>
<translation>
@ -34,7 +34,17 @@
</translation>
</message>
<message numerus="yes">
<location filename="../../core/achievements.cpp" line="1504"/>
<location filename="../../core/achievements.cpp" line="1401"/>
<source>%n achievements are not supported by DuckStation.</source>
<comment>Achievement popup</comment>
<translation>
<numerusform>%n achievement is not supported by DuckStation.</numerusform>
<numerusform>%n achievements are not supported by DuckStation.</numerusform>
</translation>
</message>
<message numerus="yes">
<location filename="../../core/achievements.cpp" line="1476"/>
<location filename="../../core/achievements.cpp" line="1513"/>
<source>%n achievements</source>
<comment>Mastery popup</comment>
<translation>
@ -43,8 +53,9 @@
</translation>
</message>
<message numerus="yes">
<location filename="../../core/achievements.cpp" line="1506"/>
<location filename="../../core/achievements.cpp" line="3067"/>
<location filename="../../core/achievements.cpp" line="1478"/>
<location filename="../../core/achievements.cpp" line="1515"/>
<location filename="../../core/achievements.cpp" line="3083"/>
<source>%n points</source>
<comment>Achievement points</comment>
<translation>
@ -53,7 +64,7 @@
</translation>
</message>
<message numerus="yes">
<location filename="../../core/achievements.cpp" line="2711"/>
<location filename="../../core/achievements.cpp" line="2669"/>
<source>%n unlocks have not been confirmed by the server.</source>
<comment>Pause Menu</comment>
<translation>
@ -62,7 +73,7 @@
</translation>
</message>
<message numerus="yes">
<location filename="../../core/achievements.cpp" line="2876"/>
<location filename="../../core/achievements.cpp" line="2844"/>
<source>You have unlocked all achievements and earned %n points!</source>
<comment>Point count</comment>
<translation>
@ -71,7 +82,16 @@
</translation>
</message>
<message numerus="yes">
<location filename="../../core/achievements.cpp" line="3321"/>
<location filename="../../core/achievements.cpp" line="2870"/>
<source>%n achievements are not supported by DuckStation and cannot be unlocked.</source>
<comment>Unsupported achievement count</comment>
<translation>
<numerusform>%n achievement is not supported by DuckStation and cannot be unlocked.</numerusform>
<numerusform>%n achievements are not supported by DuckStation and cannot be unlocked.</numerusform>
</translation>
</message>
<message numerus="yes">
<location filename="../../core/achievements.cpp" line="3331"/>
<source>This game has %n leaderboards.</source>
<comment>Leaderboard count</comment>
<translation>
@ -83,7 +103,7 @@
<context>
<name>Cheats</name>
<message numerus="yes">
<location filename="../../core/cheats.cpp" line="1014"/>
<location filename="../../core/cheats.cpp" line="1020"/>
<source>%n game patches are active.</source>
<comment>OSD Message</comment>
<translation>
@ -92,7 +112,7 @@
</translation>
</message>
<message numerus="yes">
<location filename="../../core/cheats.cpp" line="1021"/>
<location filename="../../core/cheats.cpp" line="1027"/>
<source>%n cheats are enabled. This may crash games.</source>
<comment>OSD Message</comment>
<translation>
@ -101,7 +121,7 @@
</translation>
</message>
<message numerus="yes">
<location filename="../../core/cheats.cpp" line="1048"/>
<location filename="../../core/cheats.cpp" line="1054"/>
<source>%n cheats</source>
<comment>Cheats blocked by hardcore mode</comment>
<translation>
@ -110,7 +130,7 @@
</translation>
</message>
<message numerus="yes">
<location filename="../../core/cheats.cpp" line="1050"/>
<location filename="../../core/cheats.cpp" line="1056"/>
<source>%n patches</source>
<comment>Patches blocked by hardcore mode</comment>
<translation>
@ -122,7 +142,7 @@
<context>
<name>EmulationSettingsWidget</name>
<message numerus="yes">
<location filename="../emulationsettingswidget.cpp" line="252"/>
<location filename="../emulationsettingswidget.cpp" line="255"/>
<source>Rewind for %n frame(s), lasting %1 second(s) will require up to %2MB of RAM and %3MB of VRAM.</source>
<translation>
<numerusform>Rewind for %n frame, lasting %1 second(s) will require up to %2MB of RAM and %3MB of VRAM.</numerusform>
@ -133,7 +153,7 @@
<context>
<name>GPU_HW</name>
<message numerus="yes">
<location filename="../../core/gpu_hw_texture_cache.cpp" line="3636"/>
<location filename="../../core/gpu_hw_texture_cache.cpp" line="3706"/>
<source>%n replacement textures found.</source>
<comment>Replacement texture count</comment>
<translation>
@ -145,8 +165,17 @@
<context>
<name>GameList</name>
<message numerus="yes">
<location filename="../gamelistwidget.cpp" line="345"/>
<location filename="../../core/game_list.cpp" line="1551"/>
<location filename="../gamelistwidget.cpp" line="1699"/>
<location filename="../../core/game_list.cpp" line="1609"/>
<source>%n seconds</source>
<translation>
<numerusform>%n second</numerusform>
<numerusform>%n seconds</numerusform>
</translation>
</message>
<message numerus="yes">
<location filename="../gamelistwidget.cpp" line="1701"/>
<location filename="../../core/game_list.cpp" line="1605"/>
<source>%n hours</source>
<translation>
<numerusform>%n hour</numerusform>
@ -154,8 +183,8 @@
</translation>
</message>
<message numerus="yes">
<location filename="../gamelistwidget.cpp" line="347"/>
<location filename="../../core/game_list.cpp" line="1553"/>
<location filename="../gamelistwidget.cpp" line="1700"/>
<location filename="../../core/game_list.cpp" line="1607"/>
<source>%n minutes</source>
<translation>
<numerusform>%n minute</numerusform>
@ -166,7 +195,7 @@
<context>
<name>InputBindingWidget</name>
<message numerus="yes">
<location filename="../inputbindingwidgets.cpp" line="76"/>
<location filename="../inputbindingwidgets.cpp" line="77"/>
<source>%n bindings</source>
<translation>
<numerusform>%n binding</numerusform>
@ -177,7 +206,7 @@
<context>
<name>MemoryCardEditorWindow</name>
<message numerus="yes">
<location filename="../memorycardeditorwindow.cpp" line="317"/>
<location filename="../memorycardeditorwindow.cpp" line="318"/>
<source>%n block(s) free%1</source>
<translation>
<numerusform>%n block free%1</numerusform>

Loading…
Cancel
Save