mirror of
https://github.com/stenzek/duckstation.git
synced 2026-02-10 16:34:36 +00:00
Achievements: Display warning for unsupported achievements
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user