From 118b1eb95a52172d7e40da6ec2bdc5fe98a5f094 Mon Sep 17 00:00:00 2001 From: Enorovan Date: Tue, 6 Oct 2026 19:31:13 +0200 Subject: [PATCH 1/3] achievement-system-fixes: not all trophies are hidden (sync with overlay/actual game) --- src/ui/widgets/chlcc/trophymenuentry.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ui/widgets/chlcc/trophymenuentry.cpp b/src/ui/widgets/chlcc/trophymenuentry.cpp index dfbbb9100..0423a4910 100644 --- a/src/ui/widgets/chlcc/trophymenuentry.cpp +++ b/src/ui/widgets/chlcc/trophymenuentry.cpp @@ -23,7 +23,8 @@ TrophyMenuEntry::TrophyMenuEntry(int achievementId) const auto* ach = GetAchievement(AchievementId); assert(ach != nullptr); const bool unlocked = IsAchievementUnlocked(AchievementId); - if (ach == nullptr || !unlocked) { + const bool revealed = unlocked || !ach->Hidden(); + if (!revealed) { NameLabel = Label(Vm::ScriptGetTextTableStrAddress(EntryDefaultNameTextTableId, EntryDefaultNameStringNum), @@ -39,7 +40,7 @@ TrophyMenuEntry::TrophyMenuEntry(int achievementId) DescriptionLabel = Label(ach->Description(), Bounds.GetPos() + EntryDescriptionOffset, EntryDescriptionFontSize, RendererOutlineMode::BottomRight, 0); - Icon = ach->Icon(); + Icon = unlocked ? ach->Icon() : DefaultTrophyIconSprite; } IconDest = RectF{Bounds.X, Bounds.Y, DefaultTrophyIconSprite.ScaledWidth(), DefaultTrophyIconSprite.ScaledHeight()} + From 50c6d2e71b76012d2033db9487158246539667f4 Mon Sep 17 00:00:00 2001 From: Enorovan Date: Tue, 6 Oct 2026 22:22:34 +0200 Subject: [PATCH 2/3] achievement-system-fixes: add rarity icon on top of the ach icon and render locked title/desc in locked lightgrey color --- profiles/chlcc/hud/trophymenu.lua | 2 + src/profile/games/chlcc/trophymenu.cpp | 3 ++ src/profile/games/chlcc/trophymenu.h | 2 + src/ui/widgets/chlcc/trophymenuentry.cpp | 50 ++++++++++++++++++++---- src/ui/widgets/chlcc/trophymenuentry.h | 4 ++ 5 files changed, 54 insertions(+), 7 deletions(-) diff --git a/profiles/chlcc/hud/trophymenu.lua b/profiles/chlcc/hud/trophymenu.lua index 11b6d0621..8227a7919 100644 --- a/profiles/chlcc/hud/trophymenu.lua +++ b/profiles/chlcc/hud/trophymenu.lua @@ -41,8 +41,10 @@ root.TrophyMenu = { EntryDescriptionOffset = { X = 218, Y = 42 }, EntryDescriptionFontSize = 18, EntryIconOffset = { X = 112, Y = 4 }, + EntryRarityIconOffset = { X = 161, Y = 42 }, EntryDefaultNameTextTableId = 0, EntryDefaultNameStringNum = 19, + EntryLockedTextColorIndex = 60, CurrentPageNumPos = { X = 1133, Y = 65 }, PageNumSeparatorSlashSprite = "PageNumSeparatorSlash", diff --git a/src/profile/games/chlcc/trophymenu.cpp b/src/profile/games/chlcc/trophymenu.cpp index d551bca3c..16b590c82 100644 --- a/src/profile/games/chlcc/trophymenu.cpp +++ b/src/profile/games/chlcc/trophymenu.cpp @@ -54,10 +54,13 @@ void Configure() { EntryDescriptionOffset = EnsureGetMember("EntryDescriptionOffset"); EntryDescriptionFontSize = EnsureGetMember("EntryDescriptionFontSize"); EntryIconOffset = EnsureGetMember("EntryIconOffset"); + EntryRarityIconOffset = EnsureGetMember("EntryRarityIconOffset"); EntryDefaultNameTextTableId = EnsureGetMember("EntryDefaultNameTextTableId"); EntryDefaultNameStringNum = EnsureGetMember("EntryDefaultNameStringNum"); + EntryLockedTextColorIndex = + EnsureGetMember("EntryLockedTextColorIndex"); CurrentPageNumPos = EnsureGetMember("CurrentPageNumPos"); PageNumSeparatorSlash = diff --git a/src/profile/games/chlcc/trophymenu.h b/src/profile/games/chlcc/trophymenu.h index 78c67a31c..d47bf42b7 100644 --- a/src/profile/games/chlcc/trophymenu.h +++ b/src/profile/games/chlcc/trophymenu.h @@ -47,8 +47,10 @@ inline float EntryNameFontSize; inline glm::vec2 EntryDescriptionOffset; inline float EntryDescriptionFontSize; inline glm::vec2 EntryIconOffset; +inline glm::vec2 EntryRarityIconOffset; inline uint32_t EntryDefaultNameTextTableId; inline uint32_t EntryDefaultNameStringNum; +inline size_t EntryLockedTextColorIndex; inline glm::vec2 CurrentPageNumPos; inline Sprite PageNumSeparatorSlash; diff --git a/src/ui/widgets/chlcc/trophymenuentry.cpp b/src/ui/widgets/chlcc/trophymenuentry.cpp index 0423a4910..58abaf6af 100644 --- a/src/ui/widgets/chlcc/trophymenuentry.cpp +++ b/src/ui/widgets/chlcc/trophymenuentry.cpp @@ -3,7 +3,9 @@ #include #include "../../../data/achievementsystem.h" +#include "../../../data/achievementsystemcommon.h" #include "../../../games/chlcc/trophymenu.h" +#include "../../../profile/data/achievementsystem.h" #include "../../../profile/games/chlcc/trophymenu.h" namespace Impacto { @@ -24,33 +26,66 @@ TrophyMenuEntry::TrophyMenuEntry(int achievementId) assert(ach != nullptr); const bool unlocked = IsAchievementUnlocked(AchievementId); const bool revealed = unlocked || !ach->Hidden(); + const size_t textColorIndex = unlocked ? 0 : EntryLockedTextColorIndex; if (!revealed) { NameLabel = Label(Vm::ScriptGetTextTableStrAddress(EntryDefaultNameTextTableId, EntryDefaultNameStringNum), Bounds.GetPos() + EntryNameOffset, EntryNameFontSize, - RendererOutlineMode::BottomRight, 0); - DescriptionLabel = - Label("", Bounds.GetPos() + EntryDescriptionOffset, - EntryDescriptionFontSize, RendererOutlineMode::BottomRight, 0); + RendererOutlineMode::BottomRight, textColorIndex); + DescriptionLabel = Label("", Bounds.GetPos() + EntryDescriptionOffset, + EntryDescriptionFontSize, + RendererOutlineMode::BottomRight, textColorIndex); Icon = DefaultTrophyIconSprite; } else { - NameLabel = Label(ach->Name(), Bounds.GetPos() + EntryNameOffset, - EntryNameFontSize, RendererOutlineMode::BottomRight, 0); + NameLabel = + Label(ach->Name(), Bounds.GetPos() + EntryNameOffset, EntryNameFontSize, + RendererOutlineMode::BottomRight, textColorIndex); DescriptionLabel = Label(ach->Description(), Bounds.GetPos() + EntryDescriptionOffset, - EntryDescriptionFontSize, RendererOutlineMode::BottomRight, 0); + EntryDescriptionFontSize, RendererOutlineMode::BottomRight, + textColorIndex); Icon = unlocked ? ach->Icon() : DefaultTrophyIconSprite; } IconDest = RectF{Bounds.X, Bounds.Y, DefaultTrophyIconSprite.ScaledWidth(), DefaultTrophyIconSprite.ScaledHeight()} + EntryIconOffset; + + AchievementRarity rarity = AchievementRarity::Bronze; + if (Profile::AchievementSystem::Type == AchievementDataType::Common) { + if (const CommonAchievement* commonAch = + static_cast(Implementation) + ->GetAchievement(AchievementId)) { + rarity = commonAch->GetRarity(); + } + } + switch (rarity) { + case AchievementRarity::Platinum: + RarityIcon = PlatinumTrophySprite; + break; + case AchievementRarity::Gold: + RarityIcon = GoldTrophySprite; + break; + case AchievementRarity::Silver: + RarityIcon = SilverTrophySprite; + break; + case AchievementRarity::Bronze: + default: + RarityIcon = BronzeTrophySprite; + break; + } + RarityIconDest = RectF{Bounds.X, Bounds.Y, RarityIcon.ScaledWidth(), + RarityIcon.ScaledHeight()} + + EntryRarityIconOffset; + RarityIconTint = revealed ? glm::vec4{1.0f, 1.0f, 1.0f, 1.0f} + : glm::vec4{0.0f, 0.0f, 0.0f, 1.0f}; }; void TrophyMenuEntry::Render() { Renderer->DrawSprite(TrophyEntryCardSprite, Bounds.GetPos() + EntryCardOffset); Renderer->DrawSprite(Icon, IconDest); + Renderer->DrawSprite(RarityIcon, RarityIconDest, RarityIconTint); NameLabel.Render(); DescriptionLabel.Render(); @@ -62,6 +97,7 @@ void TrophyMenuEntry::Move(glm::vec2 relativePosition) { NameLabel.Move(relativePosition); DescriptionLabel.Move(relativePosition); IconDest += relativePosition; + RarityIconDest += relativePosition; } } // namespace CHLCC diff --git a/src/ui/widgets/chlcc/trophymenuentry.h b/src/ui/widgets/chlcc/trophymenuentry.h index 2ea449fa8..9e7dfad13 100644 --- a/src/ui/widgets/chlcc/trophymenuentry.h +++ b/src/ui/widgets/chlcc/trophymenuentry.h @@ -27,6 +27,10 @@ class TrophyMenuEntry : public Widget { Sprite Icon; RectF IconDest; + + Sprite RarityIcon; + RectF RarityIconDest; + glm::vec4 RarityIconTint; }; } // namespace CHLCC From f9edcfcad39f7a3957f71b1fc8f1560a140aac70 Mon Sep 17 00:00:00 2001 From: Enorovan Date: Sun, 11 Oct 2026 13:48:42 +0200 Subject: [PATCH 3/3] achievement-system-fixes: WIP counter fixes --- profiles/chlcc/hud/trophymenu.lua | 12 ++++----- src/games/chlcc/trophymenu.cpp | 42 ++++++++++++++++++------------- src/games/chlcc/trophymenu.h | 1 + 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/profiles/chlcc/hud/trophymenu.lua b/profiles/chlcc/hud/trophymenu.lua index 8227a7919..d811c7fcf 100644 --- a/profiles/chlcc/hud/trophymenu.lua +++ b/profiles/chlcc/hud/trophymenu.lua @@ -23,8 +23,8 @@ root.TrophyMenu = { BronzeTrophySprite = "BronzeTrophy", BronzeTrophyPos = { X = 777, Y = 91 }, - RarityCountOffset = { X = 32, Y = 8 }, - RarityCountFontSize = 12, + RarityCountOffset = { X = 32, Y = 0 }, + RarityCountFontSize = 32, DefaultTrophyIconSprite = "DefaultTrophyIcon", TrophyEntryCardSprite = "TrophyEntryCard", @@ -37,9 +37,9 @@ root.TrophyMenu = { EntryHeight = 74, EntryCardOffset = { X = 91, Y = 1 }, EntryNameOffset = { X = 218, Y = 12 }, - EntryNameFontSize = 26, + EntryNameFontSize = 32, EntryDescriptionOffset = { X = 218, Y = 42 }, - EntryDescriptionFontSize = 18, + EntryDescriptionFontSize = 24, EntryIconOffset = { X = 112, Y = 4 }, EntryRarityIconOffset = { X = 161, Y = 42 }, EntryDefaultNameTextTableId = 0, @@ -55,8 +55,8 @@ root.TrophyMenu = { TrophyCountHintTextTableId = 0, TrophyCountHintStringNum = 20, - TrophyCountHintLabelPos = { X = 297, Y = 97 }, - TrophyCountFontSize = 20 + TrophyCountHintLabelPos = { X = 297, Y = 90 }, + TrophyCountFontSize = 30 }; root.Sprites["CircleTrophy"] = { diff --git a/src/games/chlcc/trophymenu.cpp b/src/games/chlcc/trophymenu.cpp index a56155739..650f1afe5 100644 --- a/src/games/chlcc/trophymenu.cpp +++ b/src/games/chlcc/trophymenu.cpp @@ -49,20 +49,19 @@ void TrophyMenu::UpdateRarityCounts() { using namespace Impacto::AchievementSystem; magic_enum::containers::array unlockedCounts{}; - magic_enum::containers::array totalCounts{}; + size_t totalUnlocked = 0; + const size_t totalCount = GetAchievementCount(); switch (Profile::AchievementSystem::Type) { case AchievementDataType::Common: { - auto* commonImpl = static_cast(Implementation); - const size_t count = GetAchievementCount(); - for (size_t id = 0; id < count; id++) { - const CommonAchievement* ach = - commonImpl->GetAchievement(static_cast(id)); + for (size_t id = 0; id < totalCount; id++) { + const Achievement* ach = GetAchievement(static_cast(id)); if (ach == nullptr) continue; - const AchievementRarity rarity = ach->GetRarity(); - totalCounts[rarity]++; - if (IsAchievementUnlocked(static_cast(id))) - unlockedCounts[rarity]++; + if (!IsAchievementUnlocked(static_cast(id))) continue; + totalUnlocked++; + const CommonAchievement* commonAch = + static_cast(ach); + unlockedCounts[commonAch->GetRarity()]++; } break; } @@ -70,18 +69,23 @@ void TrophyMenu::UpdateRarityCounts() { break; } - const auto setCount = [&unlockedCounts, &totalCounts]( - Label& label, AchievementRarity rarity) { - label.SetText( - fmt::format("{:d}/{:d}", unlockedCounts[rarity], totalCounts[rarity]), - label.Bounds.GetPos(), RarityCountFontSize, RendererOutlineMode::Full, - 0); + const auto setCount = [&unlockedCounts](Label& label, + AchievementRarity rarity) { + label.SetText(fmt::format("{:d}", unlockedCounts[rarity]), + label.Bounds.GetPos(), RarityCountFontSize, + RendererOutlineMode::Full, 0); }; setCount(BronzeCountLabel, AchievementRarity::Bronze); setCount(SilverCountLabel, AchievementRarity::Silver); setCount(GoldCountLabel, AchievementRarity::Gold); setCount(PlatinumCountLabel, AchievementRarity::Platinum); + + TrophyCountLabel.SetText( + fmt::format("{:d}/{:d}", totalUnlocked, totalCount), + TrophyCountHintLabelPos + + glm::vec2(TrophyCountHintLabel.Bounds.Width, 0.0f), + RarityCountFontSize, RendererOutlineMode::Full, 0); } void TrophyMenu::Show() { @@ -107,7 +111,6 @@ void TrophyMenu::Show() { } } MainItems[CurrentPage].Show(); - UpdateRarityCounts(); if (!TrophyCountHintLabel.Enabled) { TrophyCountHintLabel.Enabled = true; TrophyCountHintLabel.SetText( @@ -116,6 +119,7 @@ void TrophyMenu::Show() { TrophyCountHintLabelPos, TrophyCountFontSize, RendererOutlineMode::Full, 0); } + UpdateRarityCounts(); } } void TrophyMenu::Hide() { @@ -150,6 +154,10 @@ void TrophyMenu::Render() { TrophyCountHintLabel.Render(); TrophyCountHintLabel.Move(-offset); + TrophyCountLabel.Move(offset); + TrophyCountLabel.Render(); + TrophyCountLabel.Move(-offset); + Renderer->DrawSprite(PlatinumTrophySprite, offset + PlatinumTrophyPos); Renderer->DrawSprite(GoldTrophySprite, offset + GoldTrophyPos); Renderer->DrawSprite(SilverTrophySprite, offset + SilverTrophyPos); diff --git a/src/games/chlcc/trophymenu.h b/src/games/chlcc/trophymenu.h index e8c63c242..02b5dadb5 100644 --- a/src/games/chlcc/trophymenu.h +++ b/src/games/chlcc/trophymenu.h @@ -27,6 +27,7 @@ class TrophyMenu : public Menu, public CommonMenu { int CurrentPage = 0; Widgets::Label TrophyCountHintLabel; + Widgets::Label TrophyCountLabel; Widgets::Label PlatinumCountLabel; Widgets::Label GoldCountLabel;