From e77f1385145c6a1c157265e177c7a93e19c26759 Mon Sep 17 00:00:00 2001 From: Nik Date: Sun, 6 Aug 2023 21:33:15 +0200 Subject: [PATCH] feat: Added Achievements (#1230) This PR adds Achievements to ImHex that serve as both a guide and a fun way to learn more about ImHex and reverse engineering --- .github/workflows/build.yml | 2 +- lib/libimhex/CMakeLists.txt | 1 + .../include/hex/api/achievement_manager.hpp | 257 ++++++++++++ lib/libimhex/include/hex/api/event.hpp | 5 + .../source/api/achievement_manager.cpp | 223 +++++++++++ lib/libimhex/source/api/plugin_manager.cpp | 2 + lib/libimhex/source/helpers/tar.cpp | 8 +- .../source/ui/imgui_imhex_extensions.cpp | 4 +- main/source/init/tasks.cpp | 6 +- plugins/builtin/CMakeLists.txt | 2 + .../content/popups/popup_text_input.hpp | 2 + .../content/views/view_achievements.hpp | 43 ++ .../romfs/assets/achievements/abacus.png | Bin 0 -> 11415 bytes .../assets/achievements/adhesive-bandage.png | Bin 0 -> 9223 bytes .../black-question-mark-ornament.png | Bin 0 -> 5935 bytes .../assets/achievements/bookmark-tabs.png | Bin 0 -> 5770 bytes .../romfs/assets/achievements/bookmark.png | Bin 0 -> 6190 bytes .../romfs/assets/achievements/brain.png | Bin 0 -> 15460 bytes .../romfs/assets/achievements/briefcase.png | Bin 0 -> 4587 bytes .../achievements/card-index-dividers.png | Bin 0 -> 4807 bytes .../romfs/assets/achievements/clipboard.png | Bin 0 -> 5010 bytes .../romfs/assets/achievements/cloud.png | Bin 0 -> 6167 bytes .../assets/achievements/collision-symbol.png | Bin 0 -> 12823 bytes .../romfs/assets/achievements/copy.png | Bin 0 -> 5213 bytes .../achievements/eye-in-speech-bubble.png | Bin 0 -> 9436 bytes .../assets/achievements/fortune-cookie.png | Bin 0 -> 12950 bytes .../achievements/frame-with-picture.png | Bin 0 -> 7205 bytes .../assets/achievements/hammer-and-pick.png | Bin 0 -> 10049 bytes .../assets/achievements/hammer-and-wrench.png | Bin 0 -> 10471 bytes .../romfs/assets/achievements/hammer.png | Bin 0 -> 5846 bytes .../romfs/assets/achievements/hourglass.png | Bin 0 -> 6388 bytes .../assets/achievements/linked-paperclips.png | Bin 0 -> 19547 bytes .../romfs/assets/achievements/open-book.png | Bin 0 -> 6204 bytes .../romfs/assets/achievements/package.png | Bin 0 -> 10000 bytes .../assets/achievements/page-facing-up.png | Bin 0 -> 4503 bytes .../romfs/assets/achievements/pencil.png | Bin 0 -> 8058 bytes .../right-pointing-magnifying-glass.png | Bin 0 -> 9282 bytes .../romfs/assets/achievements/ring.png | Bin 0 -> 7445 bytes .../romfs/assets/achievements/water-wave.png | Bin 0 -> 7842 bytes .../romfs/assets/achievements/wrench.png | Bin 0 -> 5840 bytes plugins/builtin/romfs/lang/en_US.json | 66 ++- .../builtin/source/content/achievements.cpp | 348 ++++++++++++++++ .../source/content/data_formatters.cpp | 3 + .../source/content/data_processor_nodes.cpp | 8 +- plugins/builtin/source/content/project.cpp | 5 + .../content/providers/file_provider.cpp | 3 + plugins/builtin/source/content/views.cpp | 2 + .../source/content/views/view_about.cpp | 4 +- .../content/views/view_achievements.cpp | 378 ++++++++++++++++++ .../source/content/views/view_bookmarks.cpp | 5 +- .../content/views/view_data_inspector.cpp | 5 +- .../content/views/view_data_processor.cpp | 12 +- .../source/content/views/view_find.cpp | 12 + .../source/content/views/view_hashes.cpp | 6 +- .../source/content/views/view_hex_editor.cpp | 11 +- .../source/content/views/view_information.cpp | 3 + .../content/views/view_pattern_editor.cpp | 5 +- .../source/content/views/view_store.cpp | 2 + .../builtin/source/content/welcome_screen.cpp | 9 + plugins/builtin/source/plugin_builtin.cpp | 2 + plugins/builtin/source/ui/pattern_drawer.cpp | 5 +- 61 files changed, 1427 insertions(+), 22 deletions(-) create mode 100644 lib/libimhex/include/hex/api/achievement_manager.hpp create mode 100644 lib/libimhex/source/api/achievement_manager.cpp create mode 100644 plugins/builtin/include/content/views/view_achievements.hpp create mode 100644 plugins/builtin/romfs/assets/achievements/abacus.png create mode 100644 plugins/builtin/romfs/assets/achievements/adhesive-bandage.png create mode 100644 plugins/builtin/romfs/assets/achievements/black-question-mark-ornament.png create mode 100644 plugins/builtin/romfs/assets/achievements/bookmark-tabs.png create mode 100644 plugins/builtin/romfs/assets/achievements/bookmark.png create mode 100644 plugins/builtin/romfs/assets/achievements/brain.png create mode 100644 plugins/builtin/romfs/assets/achievements/briefcase.png create mode 100644 plugins/builtin/romfs/assets/achievements/card-index-dividers.png create mode 100644 plugins/builtin/romfs/assets/achievements/clipboard.png create mode 100644 plugins/builtin/romfs/assets/achievements/cloud.png create mode 100644 plugins/builtin/romfs/assets/achievements/collision-symbol.png create mode 100644 plugins/builtin/romfs/assets/achievements/copy.png create mode 100644 plugins/builtin/romfs/assets/achievements/eye-in-speech-bubble.png create mode 100644 plugins/builtin/romfs/assets/achievements/fortune-cookie.png create mode 100644 plugins/builtin/romfs/assets/achievements/frame-with-picture.png create mode 100644 plugins/builtin/romfs/assets/achievements/hammer-and-pick.png create mode 100644 plugins/builtin/romfs/assets/achievements/hammer-and-wrench.png create mode 100644 plugins/builtin/romfs/assets/achievements/hammer.png create mode 100644 plugins/builtin/romfs/assets/achievements/hourglass.png create mode 100644 plugins/builtin/romfs/assets/achievements/linked-paperclips.png create mode 100644 plugins/builtin/romfs/assets/achievements/open-book.png create mode 100644 plugins/builtin/romfs/assets/achievements/package.png create mode 100644 plugins/builtin/romfs/assets/achievements/page-facing-up.png create mode 100644 plugins/builtin/romfs/assets/achievements/pencil.png create mode 100644 plugins/builtin/romfs/assets/achievements/right-pointing-magnifying-glass.png create mode 100644 plugins/builtin/romfs/assets/achievements/ring.png create mode 100644 plugins/builtin/romfs/assets/achievements/water-wave.png create mode 100644 plugins/builtin/romfs/assets/achievements/wrench.png create mode 100644 plugins/builtin/source/content/achievements.cpp create mode 100644 plugins/builtin/source/content/views/view_achievements.cpp diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 96f8a5384..5210cef40 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -614,7 +614,7 @@ jobs: # Fedora cmake build (in imhex.spec) - name: 📦 Build RPM run: | - fedpkg --path $GITHUB_WORKSPACE --release ${{ matrix.mock_release }} mockbuild --enable-network -N --root $GITHUB_WORKSPACE/mock.cfg + fedpkg --path $GITHUB_WORKSPACE --release ${{ matrix.mock_release }} mockbuild --enable-network -N --root $GITHUB_WORKSPACE/mock.cfg extra_args -- -v - name: 🟩 Move and rename finished RPM run: | diff --git a/lib/libimhex/CMakeLists.txt b/lib/libimhex/CMakeLists.txt index 5a4a9ecbb..3b0f915f5 100644 --- a/lib/libimhex/CMakeLists.txt +++ b/lib/libimhex/CMakeLists.txt @@ -15,6 +15,7 @@ set(LIBIMHEX_SOURCES source/api/project_file_manager.cpp source/api/theme_manager.cpp source/api/layout_manager.cpp + source/api/achievement_manager.cpp source/data_processor/attribute.cpp source/data_processor/link.cpp diff --git a/lib/libimhex/include/hex/api/achievement_manager.hpp b/lib/libimhex/include/hex/api/achievement_manager.hpp new file mode 100644 index 000000000..ff32cda9c --- /dev/null +++ b/lib/libimhex/include/hex/api/achievement_manager.hpp @@ -0,0 +1,257 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace hex { + + class AchievementManager; + + class Achievement { + public: + explicit Achievement(std::string unlocalizedCategory, std::string unlocalizedName) : m_unlocalizedCategory(std::move(unlocalizedCategory)), m_unlocalizedName(std::move(unlocalizedName)) { } + + [[nodiscard]] const std::string &getUnlocalizedName() const { + return this->m_unlocalizedName; + } + + [[nodiscard]] const std::string &getUnlocalizedCategory() const { + return this->m_unlocalizedCategory; + } + + [[nodiscard]] bool isUnlocked() const { + return this->m_progress == this->m_maxProgress; + } + + Achievement& setDescription(std::string description) { + this->m_unlocalizedDescription = std::move(description); + + return *this; + } + + Achievement& addRequirement(std::string requirement) { + this->m_requirements.emplace_back(std::move(requirement)); + + return *this; + } + + Achievement& addVisibilityRequirement(std::string requirement) { + this->m_visibilityRequirements.emplace_back(std::move(requirement)); + + return *this; + } + + Achievement& setBlacked() { + this->m_blacked = true; + + return *this; + } + + Achievement& setInvisible() { + this->m_invisible = true; + + return *this; + } + + [[nodiscard]] bool isBlacked() const { + return this->m_blacked; + } + + [[nodiscard]] bool isInvisible() const { + return this->m_invisible; + } + + [[nodiscard]] const std::vector &getRequirements() const { + return this->m_requirements; + } + + [[nodiscard]] const std::vector &getVisibilityRequirements() const { + return this->m_visibilityRequirements; + } + + [[nodiscard]] const std::string &getUnlocalizedDescription() const { + return this->m_unlocalizedDescription; + } + + [[nodiscard]] const ImGui::Texture &getIcon() const { + if (this->m_iconData.empty()) + return this->m_icon; + + if (this->m_icon.isValid()) + return m_icon; + + this->m_icon = ImGui::Texture(reinterpret_cast(this->m_iconData.data()), this->m_iconData.size()); + + return this->m_icon; + } + + Achievement& setIcon(std::span data) { + this->m_iconData.reserve(data.size()); + for (auto &byte : data) + this->m_iconData.emplace_back(static_cast(byte)); + + return *this; + } + + Achievement& setIcon(std::span data) { + this->m_iconData.assign(data.begin(), data.end()); + + return *this; + } + + Achievement& setIcon(std::vector data) { + this->m_iconData = std::move(data); + + return *this; + } + + Achievement& setIcon(std::vector data) { + this->m_iconData.reserve(data.size()); + for (auto &byte : data) + this->m_iconData.emplace_back(static_cast(byte)); + + return *this; + } + + Achievement& setRequiredProgress(u32 progress) { + this->m_maxProgress = progress; + + return *this; + } + + [[nodiscard]] u32 getRequiredProgress() const { + return this->m_maxProgress; + } + + [[nodiscard]] u32 getProgress() const { + return this->m_progress; + } + + void setClickCallback(const std::function &callback) { + this->m_clickCallback = callback; + } + + [[nodiscard]] const std::function &getClickCallback() const { + return this->m_clickCallback; + } + + [[nodiscard]] bool isTemporary() const { + return this->m_temporary; + } + + void setUnlocked(bool unlocked) { + if (unlocked) { + if (this->m_progress < this->m_maxProgress) + this->m_progress++; + } else { + this->m_progress = 0; + } + } + + protected: + void setProgress(u32 progress) { + this->m_progress = progress; + } + + private: + std::string m_unlocalizedCategory, m_unlocalizedName; + std::string m_unlocalizedDescription; + + bool m_blacked = false; + bool m_invisible = false; + std::vector m_requirements, m_visibilityRequirements; + + std::function m_clickCallback; + + std::vector m_iconData; + mutable ImGui::Texture m_icon; + + u32 m_progress = 0; + u32 m_maxProgress = 1; + + bool m_temporary = false; + + friend class AchievementManager; + }; + + class AchievementManager { + public: + AchievementManager() = delete; + + struct AchievementNode { + Achievement *achievement; + std::vector children, parents; + std::vector visibilityParents; + ImVec2 position; + + [[nodiscard]] bool hasParents() const { + return !this->parents.empty(); + } + + [[nodiscard]] bool isUnlockable() const { + return std::all_of(this->parents.begin(), this->parents.end(), [](auto &parent) { return parent->achievement->isUnlocked(); }); + } + + [[nodiscard]] bool isVisible() const { + return std::all_of(this->visibilityParents.begin(), this->visibilityParents.end(), [](auto &parent) { return parent->achievement->isUnlocked(); }); + } + + [[nodiscard]] bool isUnlocked() const { + return this->achievement->isUnlocked(); + } + }; + + template T = Achievement> + static Achievement& addAchievement(auto && ... args) { + auto newAchievement = std::make_unique(std::forward(args)...); + + const auto &category = newAchievement->getUnlocalizedCategory(); + const auto &name = newAchievement->getUnlocalizedName(); + + auto [categoryIter, categoryInserted] = getAchievements().insert({ category, std::unordered_map>{} }); + auto &[categoryKey, achievements] = *categoryIter; + + auto [achievementIter, achievementInserted] = achievements.insert({ name, std::move(newAchievement) }); + auto &[achievementKey, achievement] = *achievementIter; + + achievementAdded(); + + return *achievement; + } + + template T = Achievement> + static Achievement& addTemporaryAchievement(auto && ... args) { + auto &achievement = addAchievement(std::forward(args)...); + + achievement.m_temporary = true; + + return achievement; + } + + static void unlockAchievement(const std::string &unlocalizedCategory, const std::string &unlocalizedName); + + static std::unordered_map>>& getAchievements(); + + static std::unordered_map>& getAchievementStartNodes(bool rebuild = true); + static std::unordered_map>& getAchievementNodes(bool rebuild = true); + + static void loadProgress(); + static void storeProgress(); + + static void clear(); + static void clearTemporary(); + + private: + static void achievementAdded(); + }; + +} \ No newline at end of file diff --git a/lib/libimhex/include/hex/api/event.hpp b/lib/libimhex/include/hex/api/event.hpp index decee0cc6..24237c815 100644 --- a/lib/libimhex/include/hex/api/event.hpp +++ b/lib/libimhex/include/hex/api/event.hpp @@ -23,7 +23,11 @@ #define EVENT_DEF(event_name, ...) EVENT_DEF_IMPL(event_name, #event_name, true, __VA_ARGS__) #define EVENT_DEF_NO_LOG(event_name, ...) EVENT_DEF_IMPL(event_name, #event_name, false, __VA_ARGS__) + +/* Forward declarations */ struct GLFWwindow; +namespace hex { class Achievement; } + namespace hex { @@ -202,6 +206,7 @@ namespace hex { EVENT_DEF(EventStoreContentDownloaded, const std::fs::path&); EVENT_DEF(EventStoreContentRemoved, const std::fs::path&); EVENT_DEF(EventImHexClosing); + EVENT_DEF(EventAchievementUnlocked, const Achievement&); /** * @brief Called when a project has been loaded diff --git a/lib/libimhex/source/api/achievement_manager.cpp b/lib/libimhex/source/api/achievement_manager.cpp new file mode 100644 index 000000000..92b179d95 --- /dev/null +++ b/lib/libimhex/source/api/achievement_manager.cpp @@ -0,0 +1,223 @@ +#include + +#include + +namespace hex { + + std::unordered_map>> &AchievementManager::getAchievements() { + static std::unordered_map>> achievements; + + return achievements; + } + + std::unordered_map>& AchievementManager::getAchievementNodes(bool rebuild) { + static std::unordered_map> nodeCategoryStorage; + + if (!nodeCategoryStorage.empty() || !rebuild) + return nodeCategoryStorage; + + nodeCategoryStorage.clear(); + + // Add all achievements to the node storage + for (auto &[categoryName, achievements] : getAchievements()) { + auto &nodes = nodeCategoryStorage[categoryName]; + + for (auto &[achievementName, achievement] : achievements) { + nodes.emplace_back(achievement.get()); + } + } + + return nodeCategoryStorage; + } + + std::unordered_map>& AchievementManager::getAchievementStartNodes(bool rebuild) { + static std::unordered_map> startNodes; + + if (!startNodes.empty() || !rebuild) + return startNodes; + + auto &nodeCategoryStorage = getAchievementNodes(); + + startNodes.clear(); + + // Add all parents and children to the nodes + for (auto &[categoryName, achievements] : nodeCategoryStorage) { + for (auto &achievementNode : achievements) { + for (auto &requirement : achievementNode.achievement->getRequirements()) { + for (auto &[requirementCategoryName, requirementAchievements] : nodeCategoryStorage) { + auto iter = std::find_if(requirementAchievements.begin(), requirementAchievements.end(), [&requirement](auto &node) { + return node.achievement->getUnlocalizedName() == requirement; + }); + + if (iter != requirementAchievements.end()) { + achievementNode.parents.emplace_back(&*iter); + iter->children.emplace_back(&achievementNode); + } + } + } + + for (auto &requirement : achievementNode.achievement->getVisibilityRequirements()) { + for (auto &[requirementCategoryName, requirementAchievements] : nodeCategoryStorage) { + auto iter = std::find_if(requirementAchievements.begin(), requirementAchievements.end(), [&requirement](auto &node) { + return node.achievement->getUnlocalizedName() == requirement; + }); + + if (iter != requirementAchievements.end()) { + achievementNode.visibilityParents.emplace_back(&*iter); + } + } + } + } + } + + for (auto &[categoryName, achievements] : nodeCategoryStorage) { + for (auto &achievementNode : achievements) { + if (!achievementNode.hasParents()) { + startNodes[categoryName].emplace_back(&achievementNode); + } + + for (const auto &parent : achievementNode.parents) { + if (parent->achievement->getUnlocalizedCategory() != achievementNode.achievement->getUnlocalizedCategory()) + startNodes[categoryName].emplace_back(&achievementNode); + } + } + } + + return startNodes; + } + + void AchievementManager::unlockAchievement(const std::string &unlocalizedCategory, const std::string &unlocalizedName) { + auto &categories = getAchievements(); + + auto categoryIter = categories.find(unlocalizedCategory); + if (categoryIter == categories.end()) { + return; + } + + auto &[categoryName, achievements] = *categoryIter; + + auto achievementIter = achievements.find(unlocalizedName); + + if (achievementIter == achievements.end()) { + return; + } + + auto &nodes = getAchievementNodes()[categoryName]; + + for (const auto &node : nodes) { + auto &achievement = node.achievement; + + if (achievement->getUnlocalizedCategory() != unlocalizedCategory) { + continue; + } + if (achievement->getUnlocalizedName() != unlocalizedName) { + continue; + } + + if (node.achievement->isUnlocked()) { + return; + } + + for (const auto &requirement : node.parents) { + if (!requirement->achievement->isUnlocked()) { + return; + } + } + + achievement->setUnlocked(true); + + if (achievement->isUnlocked()) + EventManager::post(*achievement); + } + } + + void AchievementManager::clear() { + getAchievements().clear(); + getAchievementStartNodes(false).clear(); + getAchievementNodes(false).clear(); + } + + void AchievementManager::clearTemporary() { + auto &categories = getAchievements(); + for (auto &[categoryName, achievements] : categories) { + std::erase_if(achievements, [](auto &data) { + auto &[achievementName, achievement] = data; + return achievement->isTemporary(); + }); + } + + std::erase_if(categories, [](auto &data) { + auto &[categoryName, achievements] = data; + return achievements.empty(); + }); + + getAchievementStartNodes(false).clear(); + getAchievementNodes(false).clear(); + } + + void AchievementManager::achievementAdded() { + getAchievementStartNodes(false).clear(); + getAchievementNodes(false).clear(); + } + + constexpr static auto AchievementsFile = "achievements.json"; + + void AchievementManager::loadProgress() { + for (const auto &directory : fs::getDefaultPaths(fs::ImHexPath::Config)) { + auto path = directory / AchievementsFile; + + if (!wolv::io::fs::exists(path)) { + continue; + } + + wolv::io::File file(path, wolv::io::File::Mode::Read); + + if (!file.isValid()) { + continue; + } + + try { + auto json = nlohmann::json::parse(file.readString()); + + for (const auto &[categoryName, achievements] : getAchievements()) { + for (const auto &[achievementName, achievement] : achievements) { + try { + achievement->setProgress(json[categoryName][achievementName]); + } catch (const std::exception &e) { + log::warn("Failed to load achievement progress for '{}::{}': {}", categoryName, achievementName, e.what()); + } + } + } + } catch (const std::exception &e) { + log::error("Failed to load achievements: {}", e.what()); + } + + } + } + + void AchievementManager::storeProgress() { + for (const auto &directory : fs::getDefaultPaths(fs::ImHexPath::Config)) { + auto path = directory / AchievementsFile; + + wolv::io::File file(path, wolv::io::File::Mode::Create); + + if (!file.isValid()) { + continue; + } + + nlohmann::json json; + + for (const auto &[categoryName, achievements] : getAchievements()) { + json[categoryName] = nlohmann::json::object(); + + for (const auto &[achievementName, achievement] : achievements) { + json[categoryName][achievementName] = achievement->getProgress(); + } + } + + file.writeString(json.dump(4)); + break; + } + } + +} \ No newline at end of file diff --git a/lib/libimhex/source/api/plugin_manager.cpp b/lib/libimhex/source/api/plugin_manager.cpp index e5be30a0a..47a438cdb 100644 --- a/lib/libimhex/source/api/plugin_manager.cpp +++ b/lib/libimhex/source/api/plugin_manager.cpp @@ -93,8 +93,10 @@ namespace hex { this->m_initializePluginFunction(); } catch (const std::exception &e) { log::error("Plugin '{}' threw an exception on init: {}", pluginName, e.what()); + return false; } catch (...) { log::error("Plugin '{}' threw an exception on init", pluginName); + return false; } } else { return false; diff --git a/lib/libimhex/source/helpers/tar.cpp b/lib/libimhex/source/helpers/tar.cpp index e0c1e0212..75d75563b 100644 --- a/lib/libimhex/source/helpers/tar.cpp +++ b/lib/libimhex/source/helpers/tar.cpp @@ -88,7 +88,13 @@ namespace hex { bool Tar::contains(const std::fs::path &path) { mtar_header_t header; - return mtar_find(&this->m_ctx, path.string().c_str(), &header) == MTAR_ESUCCESS; + + auto fixedPath = path.string(); + #if defined(OS_WINDOWS) + std::replace(fixedPath.begin(), fixedPath.end(), '\\', '/'); + #endif + + return mtar_find(&this->m_ctx, fixedPath.c_str(), &header) == MTAR_ESUCCESS; } std::string Tar::getOpenErrorString(){ diff --git a/lib/libimhex/source/ui/imgui_imhex_extensions.cpp b/lib/libimhex/source/ui/imgui_imhex_extensions.cpp index 8939d280b..a7a414525 100644 --- a/lib/libimhex/source/ui/imgui_imhex_extensions.cpp +++ b/lib/libimhex/source/ui/imgui_imhex_extensions.cpp @@ -35,8 +35,8 @@ namespace ImGui { glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); #if defined(GL_UNPACK_ROW_LENGTH) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); diff --git a/main/source/init/tasks.cpp b/main/source/init/tasks.cpp index 8f67142e2..9bf3b9335 100644 --- a/main/source/init/tasks.cpp +++ b/main/source/init/tasks.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -402,6 +403,8 @@ namespace hex::init { ThemeManager::reset(); + AchievementManager::getAchievements().clear(); + ProjectFile::getHandlers().clear(); ProjectFile::getProviderHandlers().clear(); ProjectFile::setProjectFunctions(nullptr, nullptr); @@ -454,13 +457,14 @@ namespace hex::init { } // Make sure there's only one built-in plugin - builtinPlugins++; if (builtinPlugins > 1) continue; // Initialize the plugin if (!plugin.initializePlugin()) { log::error("Failed to initialize plugin {}", wolv::util::toUTF8String(plugin.getPath().filename())); loadErrors++; + } else { + builtinPlugins++; } } diff --git a/plugins/builtin/CMakeLists.txt b/plugins/builtin/CMakeLists.txt index 3c83b513f..03cfdab89 100644 --- a/plugins/builtin/CMakeLists.txt +++ b/plugins/builtin/CMakeLists.txt @@ -34,6 +34,7 @@ add_imhex_plugin( source/content/recent.cpp source/content/file_handlers.cpp source/content/project.cpp + source/content/achievements.cpp source/content/providers/file_provider.cpp source/content/providers/gdb_provider.cpp @@ -64,6 +65,7 @@ add_imhex_plugin( source/content/views/view_find.cpp source/content/views/view_theme_manager.cpp source/content/views/view_logs.cpp + source/content/views/view_achievements.cpp source/content/helpers/math_evaluator.cpp source/content/helpers/notification.cpp diff --git a/plugins/builtin/include/content/popups/popup_text_input.hpp b/plugins/builtin/include/content/popups/popup_text_input.hpp index 41f5543c1..e4ccb5809 100644 --- a/plugins/builtin/include/content/popups/popup_text_input.hpp +++ b/plugins/builtin/include/content/popups/popup_text_input.hpp @@ -5,6 +5,8 @@ #include #include +#include + namespace hex::plugin::builtin { class PopupTextInput : public Popup { diff --git a/plugins/builtin/include/content/views/view_achievements.hpp b/plugins/builtin/include/content/views/view_achievements.hpp new file mode 100644 index 000000000..db744f75e --- /dev/null +++ b/plugins/builtin/include/content/views/view_achievements.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include +#include +#include + +namespace hex::plugin::builtin { + + class ViewAchievements : public View { + public: + ViewAchievements(); + ~ViewAchievements() override; + + void drawContent() override; + void drawAlwaysVisible() override; + + [[nodiscard]] bool isAvailable() const override { return true; } + [[nodiscard]] bool hasViewMenuItemEntry() const override { return false; } + + [[nodiscard]] ImVec2 getMinSize() const override { + return scaled({ 800, 600 }); + } + + [[nodiscard]] ImVec2 getMaxSize() const override { + return scaled({ 1600, 1200 }); + } + + private: + ImVec2 drawAchievementTree(ImDrawList *drawList, const AchievementManager::AchievementNode * prevNode, const std::vector &nodes, ImVec2 position); + + private: + bool m_viewOpen = false; + + std::list m_achievementUnlockQueue; + const Achievement *m_currAchievement = nullptr; + const Achievement *m_achievementToGoto = nullptr; + float m_achievementUnlockQueueTimer = -1; + bool m_showPopup = true; + + ImVec2 m_offset; + }; + +} \ No newline at end of file diff --git a/plugins/builtin/romfs/assets/achievements/abacus.png b/plugins/builtin/romfs/assets/achievements/abacus.png new file mode 100644 index 0000000000000000000000000000000000000000..c53423d7a9dc490b5ee2d71b2fb94776382a3dd0 GIT binary patch literal 11415 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 Q5|scjGqQwzG;oRhe}$U+U;qFB literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/black-question-mark-ornament.png b/plugins/builtin/romfs/assets/achievements/black-question-mark-ornament.png new file mode 100644 index 0000000000000000000000000000000000000000..05e22b4c3fea48f0577aaf22e9a6e71b7061e0c7 GIT binary patch literal 5935 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 R+5Wu)*4EHhuT!;;{2$}r_6Ps~ literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/bookmark.png b/plugins/builtin/romfs/assets/achievements/bookmark.png new file mode 100644 index 0000000000000000000000000000000000000000..de6161860d2a59af7fca6208104da72fa3617993 GIT binary patch literal 6190 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 literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/brain.png b/plugins/builtin/romfs/assets/achievements/brain.png new file mode 100644 index 0000000000000000000000000000000000000000..c4cf6a6f024382958fb5681342731e723657b471 GIT binary patch literal 15460 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 X`u{uZbc>CBIsl|V@?y0jhQa>_WPOQf literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/briefcase.png b/plugins/builtin/romfs/assets/achievements/briefcase.png new file mode 100644 index 0000000000000000000000000000000000000000..8e22dc79ececbb6dbe5a168013d51b2bbec482d9 GIT binary patch literal 4587 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 H$guwarztIV literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/card-index-dividers.png b/plugins/builtin/romfs/assets/achievements/card-index-dividers.png new file mode 100644 index 0000000000000000000000000000000000000000..ec1a4ce3b89046d2ae7b36987e8ae508af65a69a GIT binary patch literal 4807 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 UIP`|E(+B`UL+@V29otv`0V`3*d;kCd literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/clipboard.png b/plugins/builtin/romfs/assets/achievements/clipboard.png new file mode 100644 index 0000000000000000000000000000000000000000..85aa0d11a9da9f5c255aab5926a98e0291290269 GIT binary patch literal 5010 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 literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/cloud.png b/plugins/builtin/romfs/assets/achievements/cloud.png new file mode 100644 index 0000000000000000000000000000000000000000..9c4b193551a8be8cc0e5e2dd78cab00d6e745388 GIT binary patch literal 6167 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 Z+{6F>0>p;}YX57Qev!5x;@} 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 X_|FDHZ7!w^0|3m((y&V3BmTbt^pBGY literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/eye-in-speech-bubble.png b/plugins/builtin/romfs/assets/achievements/eye-in-speech-bubble.png new file mode 100644 index 0000000000000000000000000000000000000000..5f40ed4c7a6c06f98809073fff1b4c6bbee9b449 GIT binary patch literal 9436 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 literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/frame-with-picture.png b/plugins/builtin/romfs/assets/achievements/frame-with-picture.png new file mode 100644 index 0000000000000000000000000000000000000000..7e11ffe16d604658c3173436dfc4471bdf116eea GIT binary patch literal 7205 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 WzX_f^+zurX0J@q+8dYkJQU3#Kuy42k literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/hammer-and-pick.png b/plugins/builtin/romfs/assets/achievements/hammer-and-pick.png new file mode 100644 index 0000000000000000000000000000000000000000..e143aa8b7b34f51b93e9582138f63ae1ce9853bc GIT binary patch literal 10049 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 literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/hammer-and-wrench.png b/plugins/builtin/romfs/assets/achievements/hammer-and-wrench.png new file mode 100644 index 0000000000000000000000000000000000000000..4ee0673d64f1d9cc23f55f95719ea905d6fa3dbc GIT binary patch literal 10471 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 literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/hammer.png b/plugins/builtin/romfs/assets/achievements/hammer.png new file mode 100644 index 0000000000000000000000000000000000000000..36adfb7d489a3514f1beab4a03440e46940ce8a2 GIT binary patch literal 5846 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 E2eTr`d;kCd literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/hourglass.png b/plugins/builtin/romfs/assets/achievements/hourglass.png new file mode 100644 index 0000000000000000000000000000000000000000..106bd091739e0df5ee889733a0df0404d85d724e GIT binary patch literal 6388 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 Q@d*G86&>Zur&baF0rgLh6#xJL literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/linked-paperclips.png b/plugins/builtin/romfs/assets/achievements/linked-paperclips.png new file mode 100644 index 0000000000000000000000000000000000000000..43791695feefdd28e9b7c7c356d72c0d4188f200 GIT binary patch literal 19547 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 KMNUMnLSTZNeLqVV$8xwV>ueR?+ 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 literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/package.png b/plugins/builtin/romfs/assets/achievements/package.png new file mode 100644 index 0000000000000000000000000000000000000000..0b2662bd353b20d907bcc88f4e1b71264b32b6fe GIT binary patch literal 10000 zcmZ{KcQjnz`}JUSfy|>?d z|9t;=?^<`AJNKS5Yo2}fv-dOS+z7auA|W0%9smF!RD#KAqS^rf01beHg}S2B)f_=J zKr5&!6ac7<#eXovM12N-fN81%0A4HrKtKopaEH1Tumb?N@&W*RrT~Cw3IIUinBJ%% zj(ULYqNFO1y@`oNK#N0DzY&YNg=MayD2HlM$E|FWKLEf&rX&Z|_E1Q-;g(sRTq1cq|BapAOFW>dZ88v%=pI+t{TY480%-v z>!8T_^S0Bim(8ut25;T@gjIJmoxmV^UJe4Y#(s?67OEw;>z6dOAvw>dclvU@jf8x zp9P0lcplm`tSYHNV=FNAFgctu@?QD@b8)DC-Gd4}=8nX;zcW936H6-vhPQJY%;QUW znd}E2JRv=>X~Tp#@J8L0pFM*E;^$uesY892O|TOW4Ffs#&INOQ_^dl^ci{UCHsT_` zX>8|X&ZzFMv~Xz@QITLmrOeSj@*`|S0i>T9&#G$Jx#G( z+9zV5nUi%+zcTZjo0QXP9nX4|$Et$-J-M#yq7&xCzdH{ITj%JRJ;Q7*WWQPH+`)~% zc!_{oYkwKfR>Q^zzp`!9)t`u`Gyl)^qDHBa`4>Jh;SR%;YOx8B0j&1;QV3fL_+-v< z9hFaWsz@)GDwVAgx7xK;42agsR}k0e)t`v-SAHpt)E$H09VuT(#+y*LtH zM?zM1iJr;v{*5P6!h)NDB{4BE*n#!0&qt~ATla5PlHrYBVkzg>81=5Wfoo@}`tPij zRQ%GpSb^R8c8^MyiMJB(KdAUl&POF{bo?ab-tN#Y!T2;Qir#g3II9#Tek<{CC*a%` zq+O!A1peZC9$r^CxoU{pmpG_K9#f5eJ+FY?RckC~6vnEOpBSbFOitJzqOTUt9PFM% zI$H%8{uH)*r5|$u{B)0p`bx+E7r~CdViGw-(@aqQJxwY;@6!nm!tJ`Wl4_WmImO*i z#ewk{P#JVCg z^HRSovETaFpCQB9nqN;-e?EJmD=PlB6UE$mv~juLq)sT;sDC#RA8u-@?xY;hpck9^ z`wHV~lA@g^pr*-W#HvHvFraAAHmIwX2IV&ewo%bb3Z&rK3V=Gq=&Bnb= zEeqT34_!kGO*^9r%+#<{b;qyeLn7;n@(f$^hN-`n@1(xnq|N&e|6yDl1v{hJ7rx_t zwXB-$(&}OzAtVt|bs<9%JmY9pJCGWA+V>`D`-B;McuThBH?J<^Fpe9PJ2~GSV~5O{ zy6mrJOWa$WmS5=F+zL~v+xp^%wz0QZe%_u))81^yoyjo(>=UYvD5y<;dsoFQ5m6TL z$esG|;AiWwTOOsXJW^2TW%{mTzGK1#>%dP`wQP9e{Tuw0*aLL@Wxqf0-8PaqgBu2Z z1lO#3ZvRNjZ+ISk0efj3we5a8ZUkw?dcE`#e_^ueN zDqaaoJoGA1zbB*69_Ars4pr_~Xf}FZB(!IRWFLQ?`?Nn(8qNeb>d{o4Bcx>}Z%{S*&13I+yzQPD<^KFWN61g<^@C#CFFP*&g#m z=AQTLYNsXM)AbF~PX0NqxeM?Q_pO}LWmC>kuNn#`$NFW{HD||g439qH?T8r=209Hc zczK%p3nVV1^piBwv9`p~$I0OG$5H#ZM(KW9$0C(S>{9vUc86v<5iPlrTh*ucseJ?a z>ZkHkpuUqDT;xfrf%(demTi6KzM@=eOM0}HR=aY1=Sf81&( zX>!%Y^7mYsk>H+!-nT~N?gKOdBDE8dui=waZNZ&Wwv}k^E)!~S3@BbWqp{-<%=>;S5ZdCC5d}EsZ}KojT}Rk z{^)0U_tSu_-pS@Azv=&K18(JnGdRjF>0kbE5$fdcj!U9#%x1&a_UBX9}t~oIt+bE;b{(yiVc4&|M zEKbx%C@#_a?8?EpC-;ac_zpWzOuW zzS*|r7M8O0oYWK}M*R|w4j*ZSdXuv00Qv@=wBUkN%H`7i(+iJ?W&b84IwlifVpc)0 zS{_NleNRcmZ`Qw}@7x{_{pPuZdFiEK5*%gIF>XSmaWDUk7z%qjQ??>-Z-PXMyr&a& z58t8%zeB?cOlKPv3AGa+QIYI%QZ+P`hBwTd7nhE6zoJD1I6CiU+@R~$9W|T~5Eso@ z{0f?ArXABU0Ak<`6-@~W%3{z@cT*PW6ZW)Q`n@%6pc8chUgCOZ6PzkYRr1_L#hMW~ zQ$DXHd)*;N-X}{_MQII2Tj#q5Ik)KxRX%@idoAL%tNP}L>3r4Ke>)YOG4V>MC0vh|xmsr{s4p_muoV?djZMMk9Edf(@5ujnOb5Iv17tR2|LqO|$L=j%2 z9>yvCZR-b=dzko4#|XhoGy_@}IMTCM438UFw)!4LiC$*l4L51w5X_b`)U9D(!mHs5 zW&GyfSMC>)vFEK`r?rcEGB!_UV>+oo*ZXNv7bGpufMQf7y7lUZBF=*ZkKAT+C6(5Q z;~UxT${Sghkq-Yky;i@|Er%gmr^wc3W$B1M&aw#4or3!Ly$&BADWNZaj=bzE`s1bk zIV?y#{oDVIA|xZ&&A-guZA0tI2hS_R8196}+4SFkbtj-ALBTAnvK^q~4^G?{6!j+Q zTsB%6;(SYcXe}-jj<$PhXP}}AW3TFgCDGH& zc1PEH*G`Uj$>5y8&&xcJQ?CbTY=w)n}=J;&bf0tT!WhpUSiMM;TBo+v8)lR zf_6a$KisgCMCza7qQ!*cL&bHVcVd#ytET{pu@=!Kw_xyBiqSK6@^JnfZ4-`Pw&p5% zOe&wZQDX+p8akgLx52+a{BS>UFYep0LJPRR2z z&%IK#)?8Y|=>C|%s7hCSDP5xwOPuPabEKy#A!Xpz*V;Fz`R~dh-#4~Qh(ZO zVi?&JR3H=TewYyYEc;Onb)?s3dTAS8j5Cq8RS(49e{HzPr{Tr&6i6}Ts<*uM7Ov@K zm*KGDtN*yW@8R4=8>JC@l+#l@%Tda;`?tj7SO%7mbAc>1@K;8qh@KOQdK}!}VyHU4 ziBI`X3khQsi7KN#PJ4yv{HfNE;&WKkkliEXbufBC9)2C5Yx>A;zZ3GaGBj(xyJ$2} z=RIHxMS{yn@#b$Vb)?>0CB2G3^W6a zKTbYGBK(*(227V)=v?GOO^Yk>h8~>_N$=Z!ltyqXSRTz*{z7Ek_7o_6V_fdj;u&XE z08Ld~{aaT=;pbGUc3tW!)VaaVPJ+ZaU7{X?$L_P$}d2ks_M=^_ALbaeEx*md* zf4bZ79iz2XGiL6*`UyLrwk|lZBW-1=f;2ksdhvFOdS*tyv`$sU&UNxGp_%Eeo(5-l!ag z5kbZ5$cjOz0-l}rC`& zU0g$iA*q1$U|b(`?Y`?(K#gpt;96@S;-*jWUw4obFfvV~K==!JFS{ZpMUhBJ#D3Z> zm1xHq`?NyE0nWiLSE2fL;8WMQ9-1>b($#g<&LAs zuuTL|p7luYa?~|ji@hCOQRTfo%p(~IIkXp&`-#;c!5;Lw<-gDAM4M5dZ0obHYG_XQ z5$kfE|J?NNl3Bt2#57%}WUFV`z;FkmJ40GS1Dhr zAMlhN_6&K4V_iL4_DNyscWcLVA-?e@*pnYiZugpFGke&@a=PIR;@3mw*ea7$#=5do zLbU<%yC``Ovim4AaG)U(lsAju&A8iXL69t_sxz=H^{}T&zt`jtf#0OxPPbQGG|KQE zo{oHcowO=YmV%zT`}qP7VJzF}G9l|OJ9uK%QDG|zU3+c1l!z``tLcatH)>~Y+(>62 zSug|K3Vz?53Fa~p%o%zJUj;iQRYN51*~nnbWMfU|-}uz{Xos*e+RxYz1=?;(SU!nk zE`851rV=$;6tJMBoVPVV~Yuijjaw@w;AO-=R66*aA7V90KQB34I?Q@Lq6KdPpj6>IsA@L~Z3 zZ8V9QCKfj${SpS^^{@N6c$D~kQ>vNR{{|COc>KKgdXD!DlkL`n18q&=Ta#u-wq`)t z0t%86dsPR4wg;*1MO*$iOFZhrIMq+FXFZhuZ*QB_0jE@`T#|AWWf>M#t zZ+sl%xMfm3d@h|c?^K7exoEA>hK^hvPW#Y{-@O?rIwI#mh%5vj)8k~dKA~GDt20~= z8A)39iH?=xNt;-btO)U?-A;G^9p-sil;Tzvd?vr1V|`}lhtXY*sL5n=Z$G05?>xmk zO;F#>m9Dy&V;IxH;mMk4gf{dXZ*pB0jmpkf(!%rhkJP0fUPLgd{rMb_cf{%4E2a(J ztvj-_v6C!#>tT5vV`rXJaIGa7iq=_zUPCRxM)8-x5B5&r;`eMfmD9L3c)o`+Z%`sl zx>Nwi&by*Ib#7+koZRhzI+grGRaQ|?yiV;qYHCDH7ypeg%=6NK&EOPm5d&)KvT)ge zUc-@ia;LSh#1lo7`iFM%;Plv1K4mnk;5RP=L@5U|;>*fxT$}jOS1s$QlKU&u$4Yx% zZEgIj)H#dm72B_ON%%2)8=PpkHn4QexbvqI&N-<~!jk(vMm4iX_FqRT)|*_vX+p*y zMW@B!b3!O}rMG+q!1aWsi$4BmJ|}wj8K_JV6-N8WPMz^jEn&tESvX^h%@<4sb@Bp6_0$HhcA|r>eH=&F+~cvm<^n<3Msr9rjY-AuXwuZgTK_Jusvuk( z+v2jk$)@mG#}1Phok~@p$;nI&o+c=R?G4T$J-D7PBS)<@L6Lz~BAa71^{9V6`+nSk zc+pxH1*ocZAxzChm^RjkUT<3HO~Bd4F(V9>+aHX>Qq^(E+;7R&t!&`A(|G(@oycg; zAp`2gGx{SWQBZ!9(;z~O_Dclk%m@qH($#o5sRezDfEwTYds1iZpwJzpp-!DH+-O+ig5c(}@>DS${bh zphoUi^>fJ1Y*vHZe#M*YtTyq+4j7^Cde-GGw%1xL)e|r2#a;f$PJmcvR_O1SM5DQ; zb+gtrX4vsM`OFCO`se3xbAO&~^5$EBAJo4hrcD@S7+<3VL|I%TA_e%rNA(FUZRKOj&5cZs-!Z6b zjqmP45jbxRBtu7-3l&~p+tm?bdS(lxdeQr9J3GQO&~36@32~r|DI%M7SB?KG#Ao|! zX$R*d@6Jk$d*}`N@E9D*tx%JIUJA*)nrlH&Q4mhkNHVf5T@+~_tfG6#USAin5lma3 zV18OB3W5L<2z%dO?^UD7iRL?9Mwrb#NEMjJ_HE{>I7kjl^Q6GK+3U;#ZAA!!`KKJ#SweK+4#zz7=l(3PfxdzaxIS;cLe3D zm@#!}agG`?9SZa*2go3R`hgpr+y3~Cu|*SrpM1EqN9rEJS=sC<)v{%CHqJz3JbK7Njg%oJFQ}g2G?iL>5`v^_|9%+Muar(+r*Ik z-}gIOCikQ}G7U#jiKp6JzVwk&l=Gj!-n!hus!i3npb2^k!pcUT%Us+XieglqVL1R| zOLw_^f(C_voeZvf?zCctJ$YPGt7iUUJ}MpudLc_^DRH1O2$$B_r!{DWuYJOLs)+vQ zwz>ThV~JOSlcKBsui0SArP8;jK0$JDR}-QYw0%CcajrC4p8$KckU`7%#w95>2rLp` zC|h47159EpX$jzZI$zI*DdS|`tWU;f+nWU`-v12+MzCD7v2AygKxC#d{eALlV@#Qcz7f`uNl!f;huH3UxM(f+`_>GjQ8paFOQ87m}^V===9SNG`o zfI)%>VJ=XBml++nOXI}R9jTk0w-S^VV#A+;d+6hHtd*~?v+&VCZjsi`F9MwhX@E-L zT~M?Z9)&8I4}FX0x;UE&+wRORgCMNt9R?XhbrX{~C_h>B`A7H~PA_}VuX~y65@F2s z*xL^zh!i>+oK-}{8?(Ww&1N(iga?C~8AkJbGY>=Ja`ohI+e;U=9}*>ftY3-2<2nY? z%+F-nEk1<62mnWff&X9;lS#l?ZFQr~Smqzw^tTJYfo7X$N-=kwy4iE@G1l-w4hH1K z7W+`4OKxLSwlyzhRqfoa27R0-BNDjKEXU|Uzo?SOZIP7l2n7baIOJd@a8jH&FRLJK zpjJdJL@}duhpQr?J@h}nbOfA+58@YLn;<~!qw>5*`#qm^c1ivk)Gtkj+lqOvjMpHi2E&u zi7c`|koS6TQYSn0!o33p!A*{|^L&)L=+*c=I^xU%mrRvzO$+0c8Dfv2H(n_Y=T1c{ zxi%q%fPoQNS4G1<56K8AsZlXk6Az9byem!@{x@s3Qxph$S(yIkujtF1)7YQQX)hy9 zQ2;!Meo9PSmLgi%)bbLSkLx-vHRQuwE}eb+2wn-Zm@KpJAD$z;-IsbPND0J^HHyW5 z+BSo8)2>!a9F`V&YOlQ3h6x|f5&ihdju7)spZ&as69=9Q)>_@0r{xlte{cY=1VMc7 z>E@aksm_X8N#UrJ14fvDzYht3y*sqoh<6UjQQ2^zT&>I1DT0K@qRpqWgntnD0A)Y< zmkwrtdHtG?m^3{f#aIqu!k*y2hRzH!dw4|?=!@Whg1VVT(w^w@59hXT52uf4=NK2U zu;V`lnj^mkV27XvH)?N&=#5)0Ao(Ca_Wx@ie}jv5XiNeDD%D@McfLW%YOYG1)unTP z*43vm)XbsmX+L71T(-COTLyZSeCw;Kg2`aUryXG2Nt8tcP)X0rXK%4W!15c@>i48d ziV1-#)5R?pkreSJ!kCn7pxh5)UrjRBn6daZ5G1pQwTmQ4gYrvsa5L30CNtTrZ9*pM zC&6$*K_NBCi0-JadIYLpenv6G7C+cRi0U;|W`P}2I=+lY0}WF_AR2XRAs<87Uh_Z9 z-u!E2TxW*C%Evz^tmo2O9?dKlQ}Y`Kg@@iDv zNB%}W7B~7n0owy#QQEfSpR1+;Grx-{OAv8tpj zH1bBcL1!-|hXsnI5E`TqhTN=DP;OGBc%p}soD{)^iTp@c_#F|yeGnw2dXLNIYe4rp zu5)~`Sf_b{zSE7VPcgp6`yH0He*p=4bjvJS4 zGn6Q2A}1o*Noj%TrwKyyZJX;qS!Loau-E`9{lfrF=fC|*my<-$B)_3b#q`3CJ1jaH zW>-p$+Q$RqHs8pC5=$dvz21^64v?4s2MoSL+wmLe2scu%HvuXI>{w2n7w?yG2%Q$d zx*z?6iU#*@+G{N?fJy*siC%C#9y8w>qyM0_)AK$_LeWVMJxdoW4ESqv&`Dz)Pia_{ zQ4+{tb_ZxQp*dMIVFciS0xyFPH(Ce7nHv#mve@VU?A2Q58!h7D{Y7p;>O@P zDzzw1t_6$-j35nPCZ(Wi1rj3Bp(v@!Q^H&3)HOc)$_BR(>}9V+o>X`^byEuBaR#EE z!v7+7PZ?yK>&=^qNJAu}H9kqhGoja|2qalh_x`I8+;O435VJ1r_1sULlyYQaAl4(P zVu!603Lq{NiTOyBN!y3Qfaq(GQg39}*dt!nqVA{+D$69MzbGqdN1}vCgBMT68Nbo^ zb8b?Yvt%fEx6+w1U0sHd6tlWJ@_v<)f=ZYy@J$fb`74x2cx11l$S!nq$y{qOr!JoZ zKDfeXh>(61B*X9u%J&ZVH{b-PqW3K~_ZfE0g~y9Hb-Nay?)c5i*sM@Mkxp0XM#rz^ zTcBivosD$kk9T&479k+Qo%blGHkFUy28jRR^g$`HTicOr-aC5x zO)lU-Y?L$Hz48cJb+y7wKkt$>U~O20Vsg+1;~pa_?iP#96{ohjv4}NmQyriZ954}b zr1J|E^56c(mVGayaOmUlc>fEaSCV8m1H1h79 z0OO_{+$MW?^-tk;VUc3y!JzC(#Mt3Z@@^837BB>o&ECxUt_piY!wPkqN+<0^f1GK86~ z>j-)s#ZA))L*Oty2OjB^*cx8^lfg|)#$i@4gFb%qC~1yV&}Y2}ko?MEhIYq3Bk>gh zd~yr}t4T^mAL;Q?ulwVG+LG({r{c{1ekaE>gm{!hqgWhUG^mjCq7PpN)~d-OcdQBN z7B8e!FH!_E(|_)3_oJpR$N-=I%v8AMFkp@V<$25B#sc0-J`os|C!^GXGnA|dh>w~e zAu#wD3^ucH2=u*oU7qW&@Ft-Qg`crQ0R!%oDapCsmo+FUCA6^Yi1&DSvu7(f@x>>L z1MS5Cg@>2DW-sQhqe!F{<0tuRJ6c=vtRm$Ana(ozL!5qlaf#w)NdIzq+Nqo;Zs5SS zU9<*3<_x2kzMz;1k6C+#j$=SkIAb%XE(4_(vt3j%s9nGJ)T6|yv)vd-#;)zW`%57x z5_!eJaJPz*=XW6+6sRqGE|Al+AI=bt;EJ-p&=*VqWHoPrIF2v!luwX0CjU{}6N}Iz zOR5ltM+>U+J`u?T^PnQ1RDp?NU6QoPF&T&6l@o_R{h3}z&RE{ko=7uiEX zRCAdB%mHJ#eJMnt9?LrKh_&|&-u-zmL>znv5j;AFVh!l+7#DE#_7UV4y+smIM5|i; z_=@$300gr~rIVsydSLgWUN=|P8DpbK%WJDOlDK1?IBUX2-SV7?BO=hT3Kva1HPsbw zXWV?+m1!pUww#~gj(87VYoRaYl?st0Rod6o7IrcJsJeYxDiY_1x9S&|;3BS8d>Ev`kS7dPZLW5hX&q<#Z*A zJMlfA{!f?INh*`0RKiGj0~_}AQ~B${FItLA8cf1)CX&&gAV~o9M@Z42XC}k#y9{C> z8g+yidESS+iFgK*chM6(YP46hSeFX!haHkZA+AK38Z2^c0Y~I0T!Dvvml5RQQj|O~ zbKj(Wc3ELh1qpJS?CW`SIrDlDG$xPK2Xv$IP>1R6WM3dI&8Xwc^;q?>mdJef49Gu- z?$Yx%&R|n9i-~klS>h|BU#GSM6^pyeEV%k+haHqtQc;f98Hj@)yy&Q9(Pi`ym3Wz3 zWQ3FqV?>FZ^wZnJS_qWkIO6`ghcfgq-%7Umx%Mhi%DC+9k4bLWaN1U|-wNfnb2aPqUUeCzAJA4a5hx*D{JU!e9 z88%+Lj|D3w8<#v;cyaX7$?hyO;ZpGpk$#54gu%e%#()jb{g;EklT8XBXY)j*V+9=D z?95#t@zp-(TvncY6hx5WJL^?te}4TtOQpYHg3>nznj|HezLw9ccl$T@H`_bQNcAUr z?N1XA7H;p8x*={si)ar~v>ac{RB*8PlNu1N$%P5C8xG literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/page-facing-up.png b/plugins/builtin/romfs/assets/achievements/page-facing-up.png new file mode 100644 index 0000000000000000000000000000000000000000..18f21e4702d45a922af4e0b938cf6ceb992d6bf5 GIT binary patch literal 4503 zcmai22UHW^(qB4AF@z>TrAd(lLkWVEAYBPfq=X_RRHZ4scaW}hsS@cDzy(2yR3SZb-&S z0H6TqY02EkZd?T!sGU@FRR92d!1&XahTP_}yJn~h0D-~)5FQNx$7E6X3IO;>0Kl3J z0LVWA0Is|FEjJX&9dzE;bv5V~X(*T}>8uh7`(zO<4x^<`M)Gx})*1!?ki6^aDn|Y@ zn+0aBmJ{6JA{Qzvj6`Efo?pe_iv)~S#l@~|Vyv|TYRwrMRO5}tU$>76WVRnv8meKm z<2L1Z?s2}J-aha2GU@fep#MvIM^`7}7sNxko_m>%2GE#yzdH&UBIK-yeqRf6c5kh+ z`QGLHxEqFE{&k@In}OQ$<>$(cV`r&){#+epR*c?>4mwmYtN*7Onm6OY>ll4%st;od zitcN<@Zb}H! zxVcKFUbu|w8?2Ige>n1#orvwz6qAruTxYVE7UdF*pP3+9!RP2Pf}uDoh&=ngql*f(ph9F zV00a(w4gcG16PIUO?p}wr()&>rrrr~alaBO?N2c38x-a)In7|yV;*a{RoJ0;Ai9JQ zpYU)9ucN+*6ZbO{9kFb^<~(=nsZVo`cIj~jp9XDoQT@VbipVkJ(Y3egclbqb z&?Dx&1YNu4OmcdvZqkz*s7Why%|>8StfybuYZKaBSck^**H6H>ABsgnK}!f6IrU*T zd-*(QPI&VZx-Ixe2!%f$eRd$^shAmJP*|-8eHgb`hdqiWvaFM!m6Mw3t5XgVHLMTg zjH$t$f$or4#$utyBcW|V7IPvO*pI1V$yOUocJ zG@cbxD%;ODPA|)#*|T$%5Ug5UXDy(`w#sD>(WF=J*)c#Y3Z_X*K{42=6P7ivCSW)b!UY&@SFmSj)%bzMpbsBJ{}sYhC?!#Jx$bE^Lg zdG=?C_Up8r`8aWz5!e?8;y?Aw6utP#t$1uevoEPGCXR-@l9sK**?}KbdsGQhY;dHh z@pTatgc0mFApE>2vX$YgN(Dlybb1ZZeQvv9FG)~XTnyF$VG?SFz3Iuo{6~vx-6SeE z?XMl9o3$G5maNmB@cuVGH?>DS-tgl_$fAc2ZAu1sm#yGmo@vNIXEaj z2^(jO$1N_-EMfjyi|i$9e%M#UN02){{aGz@j^A!0e@%17`BdGVs*k3{@n;F)=4VD0 z`=q(ZyarkS*lBE0i~~H@63LHv9ux7-2{NGkOIisz6`R10iCVY+9Vfj#u{Y%S1260{ zy7i)6++M!8d}v`6g$o$@?TJk7FwTgMwZ_G05r=gfm(}v=V zFth|R(2?U(RpoiaKZ$QVZ*Lx+Wxxam>o}80GX`0>y<|N(I&hoUH35Grq*qQ<3h7AY&V~wULfox8E;mTPFI`fu-l33=I(`+HvKb%d-Da6~4 zm8cS)TtNM5Cq!#rbmh6xb*w3@BU)HT8*;-+2X6v5F%C(ux6~?AIP}x2x&MB}S@NVf zed%t{RzmOF#Q-~f>Qv4pyO1S$Wv{)lR$&yRs&4Ecwk5r&=-^JBWx?@+ntIC*>8aV~ z9g&_o=39=u>l?^Jj?Qfo3MzhSYM&-MCeHW>74w9~!ODf@g9w4rdlQDKJ@sTW;L7s#3tc<#L2L-)nqB*fZ{_6Wy$__-%S~wt_hv z)=E1>YR1rebCn^7Qs^HDW@$W+{Ze)(a~||wdfPJm{xBma@NqPea*jPT4tsgXJpTFg zO&j04_+MvpiM+axrJaWB6<-#3an-tCx(Gi1shM~WUZC>exDgp`GTz#(yF5=Usy`|B zu%BbiZ(AxtNbbw}87tm556VAQ+O*heu+I%d zmdu1)nGbHD*3OQf3G8x&wF=C)Crogk^P-(57WBxwtav_cuYMi<`MUmAt2=>!mr)&) zd;eDYYaX^-pcwVlsLQjrW*&?#Z+)Tf%}kI_rC{_bY7QFY0=%K`%AvH0=zZb!d%&6y0ZKcLd}E=tp;%k& znp)@e6yw6|oPxkn`JU%zxWg5uy`H@C0tK2q%jaL~NzpDMINN5q^v!-`;y1aqAGHwq zMl2V_ve2lh^R}zt_I{F{we{$Fm)|iu)hIYe80j5$n(D4dOT(+*YuVCeSJ=hsQN8Y)t-$dmep%ZF+@%;rMj^ph*wqRRr*t{QpRJ zvbDE*?!0V4swCUlvoxY-+!o6~(n0KvkG*e)LT0R0@-$8A)i_LAZ$HOR#0w=~RF+LS z7Rz$?9H-6vZUh|AxZJ~G>;}a^@2I&?jgZ+^d_{;liYS0aFov*UUib=f`15D`=GCbZ z=tF3_)W~~HUefd%ZdJ`eT=%d`5H@EnRCbkuFRHH+CIiSmj{!R%lzCdO9IE)K(ekxv|`gc?yq z0{r${)xQ09+hJSEZ0l1ayjQBgMN`R|EsZ8~_a}RnZlCzQib@Br^rfTo##s0$IDPZ zT>p%lU{twJv0Z+0%7Q%XCd>k6HyJ+xJ1?am2cbxq*w^{jaybiAq0;du+@rseVhaG1 z%Nr%Vs8JjY1VA|=UFVEl@OOxW5>t{29ZR7Xw^Dmrv0+59VWL65(a5I{2KJR}ZVGd= z0oN6!z6O7hF|rOHaMro)dOOL?EV}A+rY^ps(q&Cu;;u%;2^3>KzUkBbgw&Y45)U!= zeaoTb78z9x&=gCKD{Oc;DE#=xIdWO>FE7ci{`L0Xu-_O_t_#f0qwa3Xw_!2kJAG(U7w3b=@Bpn^9ZJfLZ$7TGaf+DKwGyc5b z#Kh)_U3ytH(jBI^pBp7Uub0f#sXg|7?95y2+ebL%$z`e7bYVq#if1_5;H>!M6d;Z! z91D=|zep~g{$XhT!Nn^xMxcjx_i8J%fhbHZ6t#l50)7|v*3{2qE1+7kad|QALpWDt zgNj9Ep~`-;51N9sBpweIjiIk!M238iUqoS?5x2>qWj?%+U5i_l9Uit7UDEqJx&81K zF6RF00y|TBKva0*zC}K^UXwsB3~0|Qs@M&k0=*d<(9TjT3p6knE05W7KZViObL0T8 zf4y~=TtO8ZpYh&aJHwlN1)j!5{`8Yu(Q0n|L3NQ`Zyr@X6`5zzK$9$R1i0_ad62Y) zVm@apcB!a>g(85<@|1t`i%k9-{%0p~Slf+IFm{9QYFC9q1NiOxtB6_T zQLkx?nLFgFinHU%g#YE%eJ@<^(z~xpb9~{ED+xm7g-pTU63Xjbiu=B=@6b#&T?gQw zb6bj8XgFI)VTz*G<6X&=Sk{m=JsS|7_U7dU>qAyqMw@{8OnEl!TAEX}%ucWIoJ6?8 z!#A$ULQL1F1wpJY(a&<>BH6>1TV6N2Jkjiz zYt5fpc>Xz3rmb4{^UC)O(O|d}gr$&Gj1;oSqo}={b*=6jpJ-)a2o<|FvqMlGB09;T z@356Uz5bv%i9b?Bh%xgmcIwe-e;BY@1g5$a|D<{xCtPlo5w`tUFn-XYPVd}cA2EqG^qxlCG7i-I{QUqVjq5M& zmXmgqzg2FS%icOvF3g=nCidpVlmAu-d23+3?QOjszNQa@+K z#Q8;9K+Z9C;?6c=ecp z<$Xyfo|H&Q9ed}*OFsz6Xi-a1arq>S&O53oCK0>iLS4Z~0B|=()@)CLk|{WusS8mN zhN7}b#wn~0i@3+a#7_Us_+f+vbrC>$^-N}6k@?bGY08FP@(n|5ZPRlB86;KOmaUn( z^6)(=L0%1xXeqR{r~eC}E-|u>)C!zxne_B{J{chuu2CWZ9F^a(%+q4W&29{;;X8Jg zgj26iEkbbrFea_tPL~ILO<}zrJd@D>h;`=c?T7KV+fy&f!2og2`eb`n;AwWc=d8p? z$ZY0=!?P-Hmsf^1dbr-fIA^S&xP&h0&;1*9f!1u=)tTz*px5t5lT{DbU3Xne+usMP z&w&GR2Y2;85jOJiy^q`od4%8Sl+ucxpOKEzM?c9T3erH&PrcBj z`5B(NiN1ec`QDxtzYJwgALBsLsM6gBw)(GFv!&xmQYTKzDeo*Pg?$^o@v{DAVdo>v zC=k}f;-WJsYc3LhnskX4?6*r>T7b6#YA`WGBT*gm69_xaP6iJD5X?@NE?SF~{FDCm zXPEHpA!V!nkCI6h2fWCWzvqbM&7lcseqzVPb2C4FSy$^_Fb|!ty}O-v8OqHI@t&Z& z)>L^L7p>K8(C3~RNnf&~PI`t+pKtutx>EJs?Yv9o*5KW3&@|7VNZ`T{yLuTtvF)VY z`IVCFECbQ2CRu4_WP z6_EReAW63%FNa<5OoepjgD*w9m|K(RUG`V`;$smBbyU%U+=nZaM-7uEN=Udcbit9; z)qD7APweDmucK7enk#GhQ$MLRw`9qY4KO4ohIpktcXLy7N-CtpCG&WFYR>R8ruyZGQX8Ck}~ z$Qq8ox3om>!xb)8A;yg2dai5u6 zU^5{gL@(dQ>tHp{z(W=ngFy*)S^6V=G9>RC{rFMCF2yY}y}fE9|3SCkp`&xwv18V5 zGm(sW9==nK5EsGSi$;{O@<+PH=}hcVLyD_gk7B?N>w>lUYnQZ^X*+YfoWVaQhW07$ zy9|BD15}F=>q~cwpU<%sc9cJae`k0k^h|2cxBMog*N;-LFYAl7Ica8jkRV~A&J01? zGM)K8kk#Ow@F0syT>K~TwD2Mrcx9u2<1|PpUeqF4e5IxqgQ5~Rf$c9Qj_xj+&z^I2 z^~RpVMmrg;N&ybP|9Dnbg%SgdcSTk$zc=7|VhPb(it7?>HWg`Gu}&Sa0Z!PMpCvcB z9S+0KYk@>meoSfA>Z;$Cb65rqJzt$U%9j3 zdYlsMbd>Vqo2(pRU3B#NvO#O9jTfvM!5uQA=D%-g)7YBY7%WfOlD+=4(fk@-*UAU4 zdqIJ+^r3h%UpGO`cyQY)+S@y@nWMp5CQMIs?S1xhGRs-Jp)?_59i!%Y4N(-kb)TLy zw31JcC|rCx7ysQUG%EC2pnww>4v56Awtwv{Pyd> z4KugGp*I~PW*WF=Q#V@ySQkL0Ijv0}emvUWpSk}2{?JO@eU+WNH>oAY%tL5s&e;as zS9x4%r4hwdPMhMY2nO0&mDkhx$D>H6x_2TsU-uA->@>wYZ^+duaUImc6|{~FJ*4}} zO84s%lQ3$*EUUs;-U)2qnRvyoHg`(bn11>v)-Q#a4?)xRBFR6hgwpQr(rxdA*LB9? zoqf8q2ph-aBxfTv5S^C5*=nwO+b9NQ$W_5_YnBvydYC>l$rj$R4R>KJ0?~rdMt&J9 zaJ|tt&3$BcO+NugCBzrnwUIn-JsW03osJqUZGB(r6$K3J9Gu$pKHMWjCE&Rg-^MB? z$AuQlXCHYz=Be@~Ql)rvwg7*->zrjG4IJP7w?rCqV=IMj9JTl#P ziGAMu(B0@@JNI_KFOEV+7I@2X%R_gAIG?_RzT}JPwx^0?(@3!|{7A8i1(`BfqaQOz zmfWMXxq`>@`lIMnQL^2*>7nE_PPWMfoALhBlC+8H229<0a;ePDex4_X9mt^q(+B^ zpOCnPljel$CKgDkjzszOt^5g?J0?u~y#aFGWKay_n)H7;m6V*=5w5C(y>cOhE$Px) zdj^YdIcmzF$XQKbb>;)QvC7vUo+Ry4 zHiC9S;0oSZi}6+ht2K{ayTFFl(KFs)E3cK+<>9Op1`d`R)H5hozt$~%y^MDb>hAyE z`(X3N;-9TEy5XAPD%FSRX@d>n{n=;jIaMg_{>Po8p4#2O>mIjv-P*W>&&OU5`MQyfT!0fzdv$JZO2w2wONxGa|<)eun;X2VV2@?D83IWOk z!nBEAN5>&+A#ZF7mGD|)hA?}6j{Wx0qd$$ygRAcYCLkijP5}xm)U269?gf<5og!)V zQBBj1V;WSbGn<`jRGNjbjYyZ6oQS!@qOx;N`gCZfBYMe(R zzBDwY(!?c8Qi8ZhHeN#E9I5P}GAbdaHC{Ya?{D6qZsW z1X}1lXrZ!Eh&p1yV%(&hINmg-c7#&&vKdqNZJVtfeLdc4Zr{lCz90kKc@U3veJP)5dmEq5QE_hJAdp| zYttmp`>GfdqiGPA$gkdK;@u~9{DMRi`pL*Y0svuV$@%W}LzB*}MaerW_a)G>Da^U| z7kzB`XIOn{%)^7Av41qp z{Ymp|(^A@5ZRfsZUuIk_1=mb`qa9;*Tja%{a3uyUWW1bz9T!mYBf0b`Mvbr`rMUHQ z;!f$xw@OyKE~l<{DxB^QeNw|^9dSi}VD9Q?wP%b6afE5nad0c~+Yv)bQFN6d=u(ub zU?}P$H~8lZFL*y_s#sjD0kb93vM}~|n0x*=Ox+Q;r+pZ-Ot%S`lRRvvI(~Mg@p&th z+2BWNA7kns^~9>ZkfBH}kdZoYNV!tj5nHat<23@Jyc<`JQI3DyP;?)O!gqkKUMuGu z-pC`PNY6RC&#mAJc#f)qRW^lhyB@+WC?DlJA-HdBy3TpInrZdr1-UViF&ci-a=OTnQyn?UujZ~tFWdK!tR_v$rnGrX>&2cFrOtosL+?#yyc z4c9(7V379baO+l>_a&!(a(zF8!grG4(S8?0OD|ZH*Wo*wSW6CzNhWj3eZipX>z1k; z+9lhl1UT_uG9BY!AOpH=&%Y> z)dN4VSW@gQ5y@U5SrE_6gLA^OyN1X6Ppq`5rcPiVt~I&d5Txxyr==+aGV zZJG$j(01F7mzs5}wJ!f)3V101>zVFb0_Ll%moi6=8CINtGd#}J%mi&Wyu7fImtK1+ zTUL@sMu!iho><(~4i*;KCAlSI%CDX|zppP%CBAvM;rL><=L1~MryJJ>#(Ea>@Vlq? zQ0;OIic5eiA!ix>DqZzfo>(s6T(0BTom^KbSE~Wh z?c)DU!(%d9Lo_LJihC07=z^_LNo!_OJY_zVsJ-S;bdtT_C1lk@1WHi-92ovFn z#wvj+NGrAkc)$%ghbREks0muIXsyZHn8JRT#XocR6zUty9MMw0inZtP;x~S{)?#A$ z&=|bI+DUS5YTP{0Wr?dlps^)}GCPpg{%r4H4OcFSj z!Z-w{nvV>4*`B%5tg^NL=9efR_zUn}=+*Ovcuds<+18QF*CNDGt_1JX%?xYI!lD)Z z`>(_Qqp-Lc?iax3Wdk(yKNjGd@qJbxu#mHS=+6J<9ePCX8l2Ck8-;n;d9cIsp{$tu z+vFqVdjwxVIv`qyLbhe_H_aPB|3b{NLp_B9^}FvyoNxVqJc%Wph->64|03;<@0(2i zn}Sq`ANVp(ffWc+JFyScK?w&k#B(JXQnK19WLxGQ8>c+%)Wd#Gsp;PQD;)SM9MxeN zb~+m?d8?@2lpCX&=(<6s@8dRaIg=y_7lGmn0iW*HWIpZ)1l*@vjAy|>=Pth~u9C;* z$DMRNCmW(<3VDqn{8tiphx)=zugLbi0`0wY4xUA8)i7P3!tYB1riNg{zWQb0mF%K}!PHfKTyI&&b-~8@u>*U8Q3)NE^`@1R z!S62mhJjF}zcOuwc+0wbTDBc_&f%cgc*#lJ0=awoD)a)YSI``~naQ7J@fY)nlV&M3 zr2me~_gBd<(3b7ozx$j(0u%c?BSV3O;R~=dxy$m2mVZfSCaeTk8zb1@U8aUWg@}Py zg^#vg8a~}^x{yC{7Ek`3?877~Dfr!bpUCjqsb`=LGB?qDRFm`ZjX4P&Vmv^(5;6@8 z$)Ic7nJ~B{C;nllf)=NsBxlzcEQw4v<2D~@@cs)jvHm+&F0x`1b1?Fn)Xl%16r0ow zy5$wwr(>k^&%wVc!aFRHQUf$fVg}i4&qtP|{xDah(7^A&?vJqEvab-deB$o~o&_VF zyEP=-NXeeNjO~FJ9JrAo2r2n@0>5~uBB!aX%>4trvg(zCuBq;R{X0*dT!sip>@&6X z;-1v&qCnyspVTafiXXX7P(SonVWg2$+9HmEVO6-DnWhHw8#rwbd23KrO+bY9%ImyT zi`HNyG!z&#_zDN;N)n?BGKf*n6?_!-Li8Z`Soxg~T>00I7;md7VH35Zo2ILJb7A0> z3S3s$!KfFjS5ABH&Z<4gW;tK`bMW+ajs+PGa-gQ#cL56rT8It z)V^5e4AWpHH$UV*31bb~;oQy=9ao>2JXxLYhM# zXE2rD^so4L8&(E&dLjzmy-lt&DU(eHXPX3?rY|iE0#6G%|HASthu$*tFfH$coloPZ z%cR9qI0eK){~kJJ)0oPgYowUZxuyrTWcpyCr$a8rFgzKg*hztZS%#4X88o2=1#U~7 z#4$lhCk;w_Zm>hg^n6CftAnQ%l*O}yp-bvgXO$_z+|MCl(K)grj(kVe!Pq?e8H-(H zcwG9okpE<*7mDXE89dP8hsj*2nU7K$d+In&wQp9hbpW6)LN6Eky@&Q-dhtPrhW5fDA~Nt%wSb8`XB#XQ%H`>KS@)=fM! z4R+belaotzU*$kZV>t+}vLMJaTQ4_q$&snuMZ)7Bq3wNo`-FL6U9c`y9ThFM#Ly6Z z&E&LvxN5a9cP@{OKoL3Y=nUcOV!2=^?TQ4FduTuGJ*@YaF8p=39OZ=+gZBx}M$U-? zhkJ-J?oh{=wJAh&^-#IuE+ zVn#aSRS(V>{3}k&vyt2;8iCCqldCXSlaoRVc&z)#*t8sbH30T9a!Tl&42cu@uv9=x zo+25EwNXNfJ91Y(J_7$nt}meyG%&?{QwEhN)QJ}yr&9SRLsbR$ zIe0^7HtNqxQVFMKxCC;-6{-)MP3Pg8_U*1o9PLl=d8^F5%Xwh%=+s!{KPX!zqyvLo zzcWM72o=;Z^0&7$orY8w2^<-}&s)QjCF;F8!iD7EGCUfX{CA#@cYQ)C;4h)T=jferx5QLf9Nm9DwbcP>peaUGd2>XtdA- zyisN6leb1D*y9}4Nc=&%cNuE@4EkC2)v0&)FWHp(YANp@I7A*83e_1uy$^qXu5n(* z-|8RxQrTJo4lP3oF>57cQGxZoc%DJ1r|v%S*ZMh+n{-afPLux_3s@*ZT%-m0!V35% zW#!4I_EB(EZ$2qBL|D8cbPLyb_RS{H^_hzXY7wp;Tf$6Af~rwl(DyE`v!`$#cfF9d zJco~jKJKbp)#p`yn1Fq9$Y}eI)gDJfFXg6h6IHBa#WkRs(GlJMIifqLJ0Cpnhg@V0g9$s9`&Tay30 zKW;(Yfg2ub+x=KTMER$SVf`<{O}iSx#;(DtS!iv3Oviyp+fu{%oLK1;iJR3x7y5Gc zePoh3Y|T*JHz(YA#L;CGiL>2Uy8J047mWkuj#zH0`XDqn<8R|HfW;^p-c^ zS45#=x7hu;A_*h+r(T}48ay1wU9k^>%i=eEr5UcD!RH|pt|Um5DdGMxmT&F7mAP;lb7mm#oh9ct$jyh9`4Nfo)JrXEE`$8QMQ zat!dnfU5cmv6h+zq{p~n1_s}S5e-M zRfvMe>kS`!j+X6={F~mu_`ii;)G-f03-=MH#eKmpxv|J{9J5+rmlbg@?o{qu%h7V57{#^8*J!1F4~Y0;zRE6X}4|)z{Y4N9r9%BK48Ts5V~Z g|FhvL`f{Lu%>TauHsADM@13`mnVo5^iPz2l0f@L)0ssI2 literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/right-pointing-magnifying-glass.png b/plugins/builtin/romfs/assets/achievements/right-pointing-magnifying-glass.png new file mode 100644 index 0000000000000000000000000000000000000000..8c11b507aa656c7b703dba1bfda2c742522806fc GIT binary patch literal 9282 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 B@QDBb literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/ring.png b/plugins/builtin/romfs/assets/achievements/ring.png new file mode 100644 index 0000000000000000000000000000000000000000..34adc5468ea71a8ba8399331ee6cec61a79e4b38 GIT binary patch literal 7445 zcmZ{JbyyTm(ErgA2h!aQ(hX7q(jj?B%K_3|M;wB*(j~}&fP!$q(Ip|>Cv|j6ryz$k zFW=wqulJ94|CycHXLk0P`8>NbJMjj3>OcZI0ssI2)YMQle54fs00!U*?&EA!H74Sb zU^^-6DgyvD$%MCdIFCGwy@sJK007|v03zN40N0PAh+P1{Ul;(`w*>%Xa{vHpug|To zouk)(vO?5CxxqAoizV^0=B`QdN47zEW8dZ$ z=k{_4ei2P=Dz=4%D^3R0es}I>bXSNJOWJwh3L{0z`)4Q1pF&PPA$LMC%~$eec0!!S zM?cG?XOw7Y3dIwR!sFbme^h<%+dJz$_$cr@(myF%^L5xIY4Q3whoDWycTUHL4+*=5 zG}kOW$ux#o6z0A?HzjY~!bvq4av=La>j?A$?2 zsL|owBf^R?l4Z>DMO)5K2B0SNJA+GN{V3TAw-d_0sFzY*U1LNQ3qCfl?$k+W*Il3E z@1IZZ&TgCLW_m9b;G=KAWy_3Ud?3VAZdy{V24_yAC zUb6!!`8VQAhcB5Wf+3$|Lc>kcj~zAIv0dS@VG@=XzY_Yj*Lt|xa8V!5-mW^Kayz37 z7P=9wgV2VodLOO>;N23Is~Wh!+vTsAP{ckbNVA`MT0$Sy{dakzG^zi6`2>F<1ZXO< zzJT}OUps|mEchC~ZFAHmK6lSO&@C3cg-S~PI_GsqZliQhS%WDg+&8nk@ z5lp05H&s6O{I}D}pD0tekSOu6VT33=R_!h0=aOjPWwpyW!bp2mftGSRJ?Cmxtc>VD z#PkUp$@}ia@Kzsv=)8i<@RHVFN1d|!o)l4dC6+~}dm73MFLdsB(l+0MR^C25v*i

>^*b?CA24sZigK_q?)`wG^#NY7@A@PzjMX0!uN}j5OK*& zJKf7KJ=@Ly&tQP?dm>j%eVXY&8RwS}P4M(1W;~yNc>{8vTfd%Vf7v6De_`a5_0myC zXqjHqrmiXa>z$}OdL@gug3er)CAkyT{7^GXNA0%&Wz4gYqN#ndd9u;ec_)e^&z~%O zlpQ^@z0#7oT>yK{xVJFerB6WLAu0*__v8a2QyC2UEs#TU)Po(4nkExd5UD07poe@Q zM6KYcz@2DlQ9=0IDs6!M9xs`Y0sl(MV?abDJ&yU9k|^98;C~0N-F-Wn2;l-#6UJyT z8PPCdd);0BW5P|hJ1To_F;#!^iBC-0{i6(9dvDBPR3N3~XK_i8T>2d-roo>4`?uYt zgk3VCn~QCV2*io$K^ zE(9L@ux_Vr3arU>(;;tDxUB6X(W`)ZIwCZ0&m+9H3nY;h;;XsVjw_eb`x-)=N%jvV z2-e_G=pkO(}M%aE3GqMMdew^TE zc8sbqWL1ou4w^|ui^6kGs|Qr~srNXETjqcs7*{p3UC9D5rx#-Il|T9-spUgu!kvkB ziULELTUFgL8QwVlJ!@3po(MczQ!{N}N40t%y-&fs4tw6<@(cWE;AT$%Gd(;Xi#=v< zNxEmhl}SRh?%B0y=rqi4)jVyAFyaV@mZWK|!1|AUJAfZ}Ls&kRjInoEYN~$C(ek}3 z`A9+%^Z*s!&hz+Zzf4^5M}IZniir{Lq24o%egyl>KB|Gbrw~KxrbaNfA=tyAUbL7E zA`x@Pr0F5#g|8R;s=x`9&mB=8z&q?T&&vvoq)D>LsFB=z(9u=QIMVfpCTC(4NsUS6BDY{J{QV=uy&-GewD zdv;dXu77_tY`-48^emkk*R)h1kzycLnZoT>h%t$$g^ny~`OZwa7OjG1lkwf|oKuKO z)jebwQIAl4_kqCI9HMz{`K=b+Fjo>n(B0mT<2ul_OP{|_B~62Jyew@K9WFNdmYoy! zEh~q}K`y(=gM!Mp-yB@>NGLj#F`O_JZ29@n>b#{PgZbH6Q zxgON0^y40c<2<3GL8)SEN!ngyYczOQ@9o^{)PY!&pTxA;v2y5ITx)pk33_(0EM-M~ z*I>5pBk$L$vO=QdEVyt3l^PcXr%Y!Wo}10Q?KD1lcjz8m#f7P%n~>x3GP!kYNMakf z$4OSLzjLNG^xFFKweh`T$4%WW)E&YGwI3PnS`_fbk`PG5+!8?Uv^%%ma)Bn((ED_Y zTY+C11ccz1t|Oji9gAlNQcd;G1m_nJL47fK8j3pcn`w-{t}p+dAF%8_9V>8h8D+7NqFYj!SMCec_&*<(XtQ0;`ytf^u-9onA<) z+$h&NWfF{MJPz~rQjQi(DLPY6| zMeTj*RpS?B7>wcN$FZUPEc0w7PRvUfD@wa-XU0-cC3=#rBXFD><$`fb`Zw~rAV;g%VdwW8uA9DQ_PVpNF0U#ieb&o6=2Voe3zel0ipf^bN2#8poax44$l zbD&#<-C>#DEv8fweKcmhgXSIn{5m5sL-{?Z7&?w9W9df@G3hu|AolMH%d%-HI5!rnJIjHQX($mMtwGuUcs}^`rxc#3qW39`<6u6ESTsY7Dz8lJcefcQ2@hK(3Rx6#1NClwErk>np7)TRw|_=CL9yT0`?X4z3EWuy9;3iAqtoh({R7 zeAIV0-+Ytb{-zR@d4!z-txE-VzHY@rZd_mujp)vC`;g~Xx6a;i4w_P1YB~? zNAKOf+13Bj=R`_3=v0*#^9#PR4B($v zgWpiTSZ|3E+eb{?wFSXHK_+Jp9iqAtjZSSAI0V?G!sktWQ$f8FzXD{6+gV=Eks`bXzwhJ|*m2 z+ZACKtUmc3HT^=N`=5gJ>)o4;o%4{7_*Kbn^W2BwFe5IbJ655V!)s=x@9lUj*5_N! zgr_H`8&y&Ktl26ZI9IqGffExiR;d+BSKB79B!*zbb7d2Aeq zY(h7bYvdYL8~5c5elilb{aGj1cp^&PzVrYV5HjV{h}u^{7hT6g!Z#3v$^lQQwW6tu z4B1&dWxxUr^G>w+F-y!FW6T7arc3Qw-ypBiA7^gJOLt#;i5QZqx!9;UoaL{Tb`NsJ z%(_99+UU><^Uki3rYtD|qB8{x%17RVX{HL^Y$n0;7)PqcVB*b)jh?VdWNSw#jjqe* zj%@cMA{Xa+Rh|Wtislfd&{0-v@I|@eSw+}K*-H101c)^rR@<3}p$l~b(!~khUcOKi zACy|eVWXr-O&O%WF4clN98A-(0`SDHr^kX{>_d%$N{Soys~7Gh|DC6wlzvNRjscs; zJ_YJ8XT%bh&~Lg-+#_nlf$%zW{&%#nt02IM$;M!eoE2pmeY(Rc?Obj$j5yZ zoN=rFcv+)DioHL3+GW@WnZe3=`vb^65#WgA5CoUPM8cGW5?XM2$LOX{ZpV)?8+|XB z_YHQ(W&WK(954+ifd(r3idzxQ|vJ?t}w5C0@q-?6f<(bYpw0aaENiAiw zfd1M_Yg1+=h~cO}P(ct|6`2V9d?5BgS>VAKNHMX39L7_f^s1g%I@ViFE^>LbD~QL7?*btWpr$jErqa+I=Xh zDx07y%bsmc9)?IV17CCkRR*M|xua_i$Pm0KnhDPo4K?;ie$ODLFyaV;?-k$wN}7)U zU}1Tv<;_?Q@5>@}I?d6%fAP+NWSCNx5V*nc&l~3VlX1|1h5OiJ1D<$LUSm-%F(e3J zd@=IEUeE3aSuNZ@VGg#;9bBx$z9K89V-T6(9eyP?koNiZX>~CdA|+fCnRfJJd83m2 z-JhV}dOge!uY9l+UTz^BKD(XTAsfyGW>%ma$Fj!WsTVtPY5X>X1ukswo$fC#tNk_t zifoS4s7^2PiE&u3u&(h_bcR9(kUwMB@51Q`_wvpKB?@89SWrf9j9uaxwCJ5N6c&(b z)^iJ{^tRk)`*hFmt$yp@1)Uhse*Vx&NRT&5_)u$#CoXHMIA0r8uN!&FxM#ka5yY^i zZ$6S3jI?>fdY8@!j*cXQ9);EIo{5{Qhf4jvVyC6%gv_OqRdY(j_gtKplV~kr=bWI7 z%81Wxc!Qif>Qy<`5RCWbjvD2*?TSd6?i`+m3t3f;_;hdXZ0{dc4|$h;4;l*|dD;_7 zAL0xV-#`JWqLUsN$=MBCm^!Hxwz{9rf=abCZSAjEC5Q2?Cz+g&1hlZ=LfRTCDnm|A zYggRDbXpfx+#piVM&DD~pimLl;M44=!!V4y(A)0U_?}NWk&JyHo*$wqrBHgwYo&f( z%+;DVD!;bwL59z|w6(28a7D@XscMro+CAG=30ly*Rj|hSZ<=w=@Zx1MKlG2v@(V6y zQ7*Y;ttZ`h$qPcsPw0E0xCz>XhvB|1e-24MM6rj?l4iBLIf3^`htO;3mMn&t^Z8&D zG7pfnzyad2BfJ3W)Q`)B2EU=$Tn%Ugl=ZrQcvqZN6aLIDeQi};r|Yy}kz>gMZ5P1e z$H%_*`NaiU>4zihg&(@c5yx*POSPM?JaGmpWXCBB<52|o;RhLWlxmlFYOyz*hj$7; zw*!m#3*}icOgH}WQ;>Mk@%?Fi4?~klwzJ#aWxY>2^54jSpz2ui+^PUp9V0E}3?QGg zL_La&x^(J|zt1Ak&u^kCC0doEv*DlT>n;$7PM*R6hu_?F5LLCyI8SyHui_fS5~XX~ z=R6$aj3WIbv130Ga|GB=$@x?^Z!%r)&>~F+XH?#rf?t|lS$aK5c6YWWJ+dXcnHxQ4ptZHy8f(K zc)ASGgW3KJXOsALV3(iG`0KKt5|6r;d47TrAvj9B8#ce0bYe~&f`OuD4L#2dGqnb; zbyr{z@l$i!RyNY2%!2VoP7#yDS<51o6`Z}eZ|PZj<~E7{+cJyMig~ao414|Av+)@J z_YUfdSmyQIN8`PZ31t zWBkeA|HYLiN5Qi0+@k%ty|qY~iFlh7=c#PiH+4Yvv%vY!y~&r;xalOKfYr-7>`pZC zW6Z-)avTiH5Ar37x`vw*jp%7%jzX(u~&Ji z7@w97+)*>vZNTt~Jof1D{-Zfr+e6@~sZFBnpLZ{KRXS7M_H3YL8&BlEvL|-!T*56( zz*klED{>hVsT-xl4T=)K?3Az8k}eOFq9s~+<u}lI?yB>3(wuWo%~LAy@Vsv>@?xh@r~l3>Eu^h zp{(-h9h{48%|^k$R8O?b9A0vm!VIUuwm}>3Y2q30NuuMz`6f`k^BH=JbX~*)c<@wd zevbJl+~-NHh=<&qb;YsC>JIgyk9h*)AJ(lx4$jVX;t$*l@SIhSU)W2F@^=(|dktxj zFS{N&I9Pi|44f3~#dFVC%84o)ut;&;6&JKeq0<_EhfwtbN%uh#+7JnAn1szYZe#e?u_#pgg$F|#ev5{ zDRcEjnaFJ?yG#RGqW(pHUh*#IG9i$in}1R|t^81F_r-L)7-_(0jC^66D<^IlL-Ah` zF77wb>3@nhuZ0yGv@SY)!kYF%b!35qNiKV8F`ZziSnm!Y_|1wsvmFTc|Fv3ec#*UwN}o z6=L}6E5m|P5PgT6to1W98#kS!;sC=C%G_HfZCFM#M^U=mQ^RRSY4O99WaF6DmDbHn zO6R9$I$dRq(@c+vs(!tZgWUT#>Ur0oY;6TgR4QD^HMFJw->H9!QDA4U;55rbl24z1 z_$BMF5fiU{qfpbFd39ogr7x;pek>kr`7s)EMSgE29bU#ks5LY)Q07;0mvI(_S_~@z zt)~t#n^BI8#QQNnly`o!*1Ip-Ou*_DXY@b+hN}3a_^CTINmPsI8MtZ-6&4UgckBWJ z*FeWVxl(ygyzAE^;ah!%Ar=sYnW%mC{RT}#pL)TV`#mV2jGJH9I69_V%KSvhmc)Je znDk4EC#d2{zlnB~8u!L3Z;HqL56Yp_*KJ>sUy#L*wMgmCufM(Ud*G{Nc>?#;0P&ap z@~4H(o|JSk2`FibIaCr}CvF@}SxDJg##taebU+Ma);Yz9H4I}VJ{CO0-}gQCp&(o^ zJb5D$S<>00Fwi`Ey)@THW|zI2s8q>H%phVBt#TJOC`Wumx!@Z=7of$)9kXjW$W|}+ zS2*}~@L>vR-)Y8i@6mS2(6qPBGM|5Vk~2d^DknpC)9Zqq*uK`xhrwTep785|pc<(M+G!$MpTNp5&q9LG>8UEl_3a zwf^9V)pOPfP)mkTAi_kn8Gdh=VCui)bG!?jY&aJD*d%UP=>WWA7JMCx&h16L>O0G5 z)2Eucrgtz=j#{<1WyIePnSb}oOMlBvDJu5T2c5mkB@@#{`aySI3zfX ztydv&H5sF%Ovp&nwkPRadsqmx<6As-XtN)rb+C#lv}6M|5$?6+oa+bJ(k-5hzyu9f z-QL8xkxu&J?&a?tSPCtYt4vgOX9L9y@CgM;l#op+9iLjO&Swez*j)tRTr%GW&TiVjQn*5r_RLF;5abLxh@5`De?&zH;9KRYbLzBiL`4OZ;Pmoz~nM9$e) z@XRQ_xS@#t_vZ#%byehFqr*C$sb;2;KifYd+@(%DmxTs^0&;@1ir+q{PU7uF?->N5 zBWgbpb;j77v{g+*nBrTB$~Wrc;QYeTgDmx8+|*x51o|5k83>ACo? P9jU3Nr&{&GHu8S}1SxT| literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/water-wave.png b/plugins/builtin/romfs/assets/achievements/water-wave.png new file mode 100644 index 0000000000000000000000000000000000000000..257eeb0c522fb3d39022a6e851240451146892a3 GIT binary patch literal 7842 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 literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/assets/achievements/wrench.png b/plugins/builtin/romfs/assets/achievements/wrench.png new file mode 100644 index 0000000000000000000000000000000000000000..dd2571ce0d5aa5ce58a22514ec4c3d90a5ec1424 GIT binary patch literal 5840 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 literal 0 HcmV?d00001 diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index 489c0a5fd..c4d0a7874 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -4,6 +4,61 @@ "country": "United States", "fallback": true, "translations": { + "hex.builtin.achievement.starting_out": "Starting out", + "hex.builtin.achievement.starting_out.docs.name": "RTFM", + "hex.builtin.achievement.starting_out.docs.desc": "Open the documentation by selecting Help -> Documentation from the menu bar.", + "hex.builtin.achievement.starting_out.open_file.name": "The inner workings", + "hex.builtin.achievement.starting_out.open_file.desc": "Open a file by dragging it onto ImHex or by selecting File -> Open from the menu bar.", + "hex.builtin.achievement.starting_out.save_project.name": "Keeping this", + "hex.builtin.achievement.starting_out.save_project.desc": "Save a project by selecting File -> Save Project from the menu bar.", + "hex.builtin.achievement.hex_editor": "Hex Editor", + "hex.builtin.achievement.hex_editor.select_byte.name": "You and you and you", + "hex.builtin.achievement.hex_editor.select_byte.desc": "Select multiple bytes in the Hex Editor by clicking and dragging over them.", + "hex.builtin.achievement.hex_editor.create_bookmark.name": "Building a library", + "hex.builtin.achievement.hex_editor.create_bookmark.desc": "Create a bookmark by right-clicking on a byte and selecting Bookmark from the context menu.", + "hex.builtin.achievement.hex_editor.open_new_view.name": "Seeing double", + "hex.builtin.achievement.hex_editor.open_new_view.desc": "Open a new view by clicking on the 'Open new view' button in a bookmark.", + "hex.builtin.achievement.hex_editor.modify_byte.name": "Edit the hex", + "hex.builtin.achievement.hex_editor.modify_byte.desc": "Modify a byte by double-clicking on it and then entering the new value.", + "hex.builtin.achievement.hex_editor.copy_as.name": "Copy that", + "hex.builtin.achievement.hex_editor.copy_as.desc": "Copy bytes as a C++ array by selecting Copy As -> C++ Array from the context menu.", + "hex.builtin.achievement.hex_editor.create_patch.name": "ROM Hacks", + "hex.builtin.achievement.hex_editor.create_patch.desc": "Create a IPS patch for the use in other tools by selecting the Export option in the File menu.", + "hex.builtin.achievement.hex_editor.fill.name": "Flood fill", + "hex.builtin.achievement.hex_editor.fill.desc": "Fill a region with a byte by selecting Fill from the context menu.", + "hex.builtin.achievement.patterns": "Patterns", + "hex.builtin.achievement.patterns.place_menu.name": "Easy Patterns", + "hex.builtin.achievement.patterns.place_menu.desc": "Place a pattern of any built-in type in your data by right-clicking on a byte and using the 'Place pattern' option.", + "hex.builtin.achievement.patterns.load_existing.name": "Hey, I know this one", + "hex.builtin.achievement.patterns.load_existing.desc": "Load a pattern that has been created by someone else by using the 'File -> Import' menu.", + "hex.builtin.achievement.patterns.modify_data.name": "Edit the pattern", + "hex.builtin.achievement.patterns.modify_data.desc": "Modify the underlying bytes of a pattern by double-clicking its value in the pattern data view and entering a new value.", + "hex.builtin.achievement.patterns.data_inspector.name": "Inspector Gadget", + "hex.builtin.achievement.patterns.data_inspector.desc": "Create a custom data inspector entry using the pattern language. You can find how to do that in the documentation.", + "hex.builtin.achievement.find": "Finding", + "hex.builtin.achievement.find.find_strings.name": "One Ring to find them", + "hex.builtin.achievement.find.find_strings.desc": "Locate all strings in your file by using the Find view in 'Strings' mode.", + "hex.builtin.achievement.find.find_specific_string.name": "Too Many Items", + "hex.builtin.achievement.find.find_specific_string.desc": "Refine your search by searching for occurrences of a specific string by using the 'Sequences' mode.", + "hex.builtin.achievement.find.find_numeric.name": "About ... that much", + "hex.builtin.achievement.find.find_numeric.desc": "Search for numeric values between 250 and 1000 by using the 'Numeric Value' mode.", + "hex.builtin.achievement.data_processor": "Data Processor", + "hex.builtin.achievement.data_processor.place_node.name": "Look at all these nodes", + "hex.builtin.achievement.data_processor.place_node.desc": "Place any built-in node in the data processor by right-clicking on the workspace and selecting a node from the context menu.", + "hex.builtin.achievement.data_processor.create_connection.name": "I feel a connection here", + "hex.builtin.achievement.data_processor.create_connection.desc": "Connect two nodes by dragging a connection from one node to another.", + "hex.builtin.achievement.data_processor.modify_data.name": "Decode this", + "hex.builtin.achievement.data_processor.modify_data.desc": "Preprocess the displayed bytes by using the built-in Read and Write Data Access nodes.", + "hex.builtin.achievement.data_processor.custom_node.name": "Building my own!", + "hex.builtin.achievement.data_processor.custom_node.desc": "Create a custom node by selecting 'Custom -> New Node' from the context menu and simplify your existing pattern by moving nodes into it.", + "hex.builtin.achievement.misc": "Miscellaneous", + "hex.builtin.achievement.misc.analyze_file.name": "owo wat dis?", + "hex.builtin.achievement.misc.analyze_file.desc": "Analyze the bytes of your data by using the 'Analyze' option in the Data Information view.", + "hex.builtin.achievement.misc.download_from_store.name": "There's an app for that", + "hex.builtin.achievement.misc.download_from_store.desc": "Download any item from the Content Store", + "hex.builtin.achievement.misc.create_hash.name": "Hash browns", + "hex.builtin.achievement.misc.create_hash.desc": "Create a new hash function in the Hash view by selecting the type, giving it a name and clicking on the Plus button next to it.", + "hex.builtin.command.calc.desc": "Calculator", "hex.builtin.command.cmd.desc": "Command", "hex.builtin.command.cmd.result": "Run command '{0}'", @@ -603,6 +658,10 @@ "hex.builtin.tools.wiki_explain.invalid_response": "Invalid response from Wikipedia!", "hex.builtin.tools.wiki_explain.results": "Results", "hex.builtin.tools.wiki_explain.search": "Search", + "hex.builtin.view.achievements.name": "Achievements", + "hex.builtin.view.achievements.unlocked": "Achievement Unlocked!", + "hex.builtin.view.achievements.unlocked_count": "Unlocked", + "hex.builtin.view.achievements.click": "Click here", "hex.builtin.view.bookmarks.address": "0x{0:02X} - 0x{1:02X}", "hex.builtin.view.bookmarks.button.jump": "Jump to", "hex.builtin.view.bookmarks.button.remove": "Remove", @@ -961,9 +1020,12 @@ "hex.builtin.welcome.learn.latest.desc": "Read ImHex's current changelog", "hex.builtin.welcome.learn.latest.link": "https://github.com/WerWolv/ImHex/releases/latest", "hex.builtin.welcome.learn.latest.title": "Latest Release", - "hex.builtin.welcome.learn.pattern.desc": "Learn how to write ImHex patterns with our extensive documentation", - "hex.builtin.welcome.learn.pattern.link": "https://imhex.werwolv.net/docs", + "hex.builtin.welcome.learn.pattern.desc": "Learn how to write ImHex patterns", + "hex.builtin.welcome.learn.pattern.link": "https://docs.werwolv.net/pattern-language/", "hex.builtin.welcome.learn.pattern.title": "Pattern Language Documentation", + "hex.builtin.welcome.learn.imhex.desc": "Learn the basics of ImHex with our extensive documentation", + "hex.builtin.welcome.learn.imhex.link": "https://docs.werwolv.net/imhex/", + "hex.builtin.welcome.learn.imhex.title": "ImHex Documentation", "hex.builtin.welcome.learn.plugins.desc": "Extend ImHex with additional features using plugins", "hex.builtin.welcome.learn.plugins.link": "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide", "hex.builtin.welcome.learn.plugins.title": "Plugins API", diff --git a/plugins/builtin/source/content/achievements.cpp b/plugins/builtin/source/content/achievements.cpp new file mode 100644 index 000000000..508b14cf7 --- /dev/null +++ b/plugins/builtin/source/content/achievements.cpp @@ -0,0 +1,348 @@ +#include +#include + +#include + +#include +#include + +#include +#include + +namespace hex::plugin::builtin { + + namespace { + + class AchievementStartingOut : public Achievement { + public: + explicit AchievementStartingOut(std::string unlocalizedName) : Achievement("hex.builtin.achievement.starting_out", std::move(unlocalizedName)) { } + }; + + class AchievementHexEditor : public Achievement { + public: + explicit AchievementHexEditor(std::string unlocalizedName) : Achievement("hex.builtin.achievement.hex_editor", std::move(unlocalizedName)) { } + }; + + class AchievementPatterns : public Achievement { + public: + explicit AchievementPatterns(std::string unlocalizedName) : Achievement("hex.builtin.achievement.patterns", std::move(unlocalizedName)) { } + }; + + class AchievementDataProcessor : public Achievement { + public: + explicit AchievementDataProcessor(std::string unlocalizedName) : Achievement("hex.builtin.achievement.data_processor", std::move(unlocalizedName)) { } + }; + + class AchievementFind : public Achievement { + public: + explicit AchievementFind(std::string unlocalizedName) : Achievement("hex.builtin.achievement.find", std::move(unlocalizedName)) { } + }; + + class AchievementMisc : public Achievement { + public: + explicit AchievementMisc(std::string unlocalizedName) : Achievement("hex.builtin.achievement.misc", std::move(unlocalizedName)) { } + }; + + void registerGettingStartedAchievements() { + AchievementManager::addAchievement("hex.builtin.achievement.starting_out.docs.name") + .setDescription("hex.builtin.achievement.starting_out.docs.desc") + .setIcon(romfs::get("assets/achievements/open-book.png").span()); + + AchievementManager::addAchievement("hex.builtin.achievement.starting_out.open_file.name") + .setDescription("hex.builtin.achievement.starting_out.open_file.desc") + .setIcon(romfs::get("assets/achievements/page-facing-up.png").span()); + + AchievementManager::addAchievement("hex.builtin.achievement.starting_out.save_project.name") + .setDescription("hex.builtin.achievement.starting_out.save_project.desc") + .setIcon(romfs::get("assets/achievements/card-index-dividers.png").span()) + .addRequirement("hex.builtin.achievement.starting_out.open_file.name"); + + + AchievementManager::addAchievement("hex.builtin.achievement.starting_out.crash.name") + .setDescription("hex.builtin.achievement.starting_out.crash.desc") + .setIcon(romfs::get("assets/achievements/collision-symbol.png").span()) + .setInvisible(); + } + + void registerHexEditorAchievements() { + AchievementManager::addAchievement("hex.builtin.achievement.hex_editor.select_byte.name") + .setDescription("hex.builtin.achievement.hex_editor.select_byte.desc") + .setIcon(romfs::get("assets/achievements/bookmark-tabs.png").span()) + .addRequirement("hex.builtin.achievement.starting_out.open_file.name"); + + AchievementManager::addAchievement("hex.builtin.achievement.hex_editor.open_new_view.name") + .setDescription("hex.builtin.achievement.hex_editor.open_new_view.desc") + .setIcon(romfs::get("assets/achievements/frame-with-picture.png").span()) + .addRequirement("hex.builtin.achievement.hex_editor.create_bookmark.name"); + + AchievementManager::addAchievement("hex.builtin.achievement.hex_editor.modify_byte.name") + .setDescription("hex.builtin.achievement.hex_editor.modify_byte.desc") + .setIcon(romfs::get("assets/achievements/pencil.png").span()) + .addRequirement("hex.builtin.achievement.hex_editor.select_byte.name") + .addVisibilityRequirement("hex.builtin.achievement.hex_editor.select_byte.name"); + + AchievementManager::addAchievement("hex.builtin.achievement.hex_editor.copy_as.name") + .setDescription("hex.builtin.achievement.hex_editor.copy_as.desc") + .setIcon(romfs::get("assets/achievements/copy.png").span()) + .addRequirement("hex.builtin.achievement.hex_editor.modify_byte.name"); + + AchievementManager::addAchievement("hex.builtin.achievement.hex_editor.create_patch.name") + .setDescription("hex.builtin.achievement.hex_editor.create_patch.desc") + .setIcon(romfs::get("assets/achievements/adhesive-bandage.png").span()) + .addRequirement("hex.builtin.achievement.hex_editor.modify_byte.name"); + + AchievementManager::addAchievement("hex.builtin.achievement.hex_editor.fill.name") + .setDescription("hex.builtin.achievement.hex_editor.fill.desc") + .setIcon(romfs::get("assets/achievements/water-wave.png").span()) + .addRequirement("hex.builtin.achievement.hex_editor.select_byte.name") + .addVisibilityRequirement("hex.builtin.achievement.hex_editor.select_byte.name"); + + AchievementManager::addAchievement("hex.builtin.achievement.hex_editor.create_bookmark.name") + .setDescription("hex.builtin.achievement.hex_editor.create_bookmark.desc") + .setIcon(romfs::get("assets/achievements/bookmark.png").span()) + .addRequirement("hex.builtin.achievement.hex_editor.select_byte.name") + .addVisibilityRequirement("hex.builtin.achievement.hex_editor.select_byte.name"); + } + + void registerPatternsAchievements() { + AchievementManager::addAchievement("hex.builtin.achievement.patterns.place_menu.name") + .setDescription("hex.builtin.achievement.patterns.place_menu.desc") + .setIcon(romfs::get("assets/achievements/clipboard.png").span()) + .addRequirement("hex.builtin.achievement.hex_editor.select_byte.name"); + + AchievementManager::addAchievement("hex.builtin.achievement.patterns.load_existing.name") + .setDescription("hex.builtin.achievement.patterns.load_existing.desc") + .setIcon(romfs::get("assets/achievements/hourglass.png").span()) + .addRequirement("hex.builtin.achievement.patterns.place_menu.name"); + + AchievementManager::addAchievement("hex.builtin.achievement.patterns.modify_data.name") + .setDescription("hex.builtin.achievement.patterns.modify_data.desc") + .setIcon(romfs::get("assets/achievements/hammer.png").span()) + .addRequirement("hex.builtin.achievement.patterns.place_menu.name"); + + + AchievementManager::addAchievement("hex.builtin.achievement.patterns.data_inspector.name") + .setDescription("hex.builtin.achievement.patterns.data_inspector.desc") + .setIcon(romfs::get("assets/achievements/eye-in-speech-bubble.png").span()) + .addRequirement("hex.builtin.achievement.hex_editor.select_byte.name"); + } + + + void registerFindAchievements() { + AchievementManager::addAchievement("hex.builtin.achievement.find.find_strings.name") + .setDescription("hex.builtin.achievement.find.find_strings.desc") + .setIcon(romfs::get("assets/achievements/ring.png").span()) + .addRequirement("hex.builtin.achievement.starting_out.open_file.name"); + + AchievementManager::addAchievement("hex.builtin.achievement.find.find_specific_string.name") + .setDescription("hex.builtin.achievement.find.find_specific_string.desc") + .setIcon(romfs::get("assets/achievements/right-pointing-magnifying-glass.png").span()) + .addRequirement("hex.builtin.achievement.find.find_strings.name"); + + AchievementManager::addAchievement("hex.builtin.achievement.find.find_numeric.name") + .setDescription("hex.builtin.achievement.find.find_numeric.desc") + .setIcon(romfs::get("assets/achievements/abacus.png").span()) + .addRequirement("hex.builtin.achievement.find.find_strings.name"); + } + + void registerDataProcessorAchievements() { + AchievementManager::addAchievement("hex.builtin.achievement.data_processor.place_node.name") + .setDescription("hex.builtin.achievement.data_processor.place_node.desc") + .setIcon(romfs::get("assets/achievements/cloud.png").span()) + .addRequirement("hex.builtin.achievement.starting_out.open_file.name"); + + AchievementManager::addAchievement("hex.builtin.achievement.data_processor.create_connection.name") + .setDescription("hex.builtin.achievement.data_processor.create_connection.desc") + .setIcon(romfs::get("assets/achievements/linked-paperclips.png").span()) + .addRequirement("hex.builtin.achievement.data_processor.place_node.name"); + + AchievementManager::addAchievement("hex.builtin.achievement.data_processor.modify_data.name") + .setDescription("hex.builtin.achievement.data_processor.modify_data.desc") + .setIcon(romfs::get("assets/achievements/hammer-and-pick.png").span()) + .addRequirement("hex.builtin.achievement.data_processor.create_connection.name"); + + AchievementManager::addAchievement("hex.builtin.achievement.data_processor.custom_node.name") + .setDescription("hex.builtin.achievement.data_processor.custom_node.desc") + .setIcon(romfs::get("assets/achievements/wrench.png").span()) + .addRequirement("hex.builtin.achievement.data_processor.create_connection.name"); + } + + void registerMiscAchievements() { + AchievementManager::addAchievement("hex.builtin.achievement.misc.analyze_file.name") + .setDescription("hex.builtin.achievement.misc.analyze_file.desc") + .setIcon(romfs::get("assets/achievements/brain.png").span()) + .addRequirement("hex.builtin.achievement.starting_out.open_file.name"); + + AchievementManager::addAchievement("hex.builtin.achievement.misc.download_from_store.name") + .setDescription("hex.builtin.achievement.misc.download_from_store.desc") + .setIcon(romfs::get("assets/achievements/package.png").span()) + .addRequirement("hex.builtin.achievement.starting_out.open_file.name"); + + AchievementManager::addAchievement("hex.builtin.achievement.misc.create_hash.name") + .setDescription("hex.builtin.achievement.misc.create_hash.desc") + .setIcon(romfs::get("assets/achievements/fortune-cookie.png").span()) + .addRequirement("hex.builtin.achievement.starting_out.open_file.name"); + } + + + void registerEvents() { + EventManager::subscribe([](const auto ®ion) { + if (region.getSize() > 1) + AchievementManager::unlockAchievement("hex.builtin.achievement.hex_editor", "hex.builtin.achievement.hex_editor.select_byte.name"); + }); + + EventManager::subscribe([](const auto&) { + AchievementManager::unlockAchievement("hex.builtin.achievement.hex_editor", "hex.builtin.achievement.hex_editor.create_bookmark.name"); + }); + + EventManager::subscribe([](u64, u8, u8) { + AchievementManager::unlockAchievement("hex.builtin.achievement.hex_editor", "hex.builtin.achievement.hex_editor.modify_byte.name"); + }); + + + EventManager::subscribe(AchievementManager::loadProgress); + EventManager::subscribe(AchievementManager::storeProgress); + + // Clear temporary achievements when last provider is closed + EventManager::subscribe([](hex::prv::Provider *oldProvider, hex::prv::Provider *newProvider) { + hex::unused(oldProvider); + if (newProvider == nullptr) { + AchievementManager::clearTemporary(); + } + }); + } + + void registerChallengeAchievementHandlers() { + static std::string challengeAchievement; + static std::string challengeDescription; + + static std::map> icons; + + ProjectFile::registerHandler({ + .basePath = "challenge", + .required = false, + .load = [](const std::fs::path &basePath, Tar &tar) { + if (!tar.contains(basePath / "achievements.json") || !tar.contains(basePath / "description.txt")) + return true; + + challengeAchievement = tar.readString(basePath / "achievements.json"); + challengeDescription = tar.readString(basePath / "description.txt"); + + nlohmann::json unlockedJson; + if (tar.contains(basePath / "unlocked.json")) { + unlockedJson = nlohmann::json::parse(tar.readString(basePath / "unlocked.json")); + } + + try { + auto json = nlohmann::json::parse(challengeAchievement); + + if (json.contains("achievements")) { + for (const auto &achievement : json["achievements"]) { + auto &newAchievement = AchievementManager::addTemporaryAchievement("hex.builtin.achievement.challenge", achievement["name"]) + .setDescription(achievement["description"]); + + if (achievement.contains("icon")) { + if (const auto &icon = achievement["icon"]; icon.is_string() && !icon.is_null()) { + auto iconPath = icon.get(); + + auto data = tar.readVector(basePath / iconPath); + newAchievement.setIcon(data); + icons[iconPath] = std::move(data); + } + } + + if (achievement.contains("requirements")) { + if (const auto &requirements = achievement["requirements"]; requirements.is_array()) { + for (const auto &requirement : requirements) { + newAchievement.addRequirement(requirement.get()); + } + } + } + + if (achievement.contains("visibility_requirements")) { + if (const auto &requirements = achievement["visibility_requirements"]; requirements.is_array()) { + for (const auto &requirement : requirements) { + newAchievement.addVisibilityRequirement(requirement.get()); + } + } + } + + if (achievement.contains("password")) { + if (const auto &password = achievement["password"]; password.is_string() && !password.is_null()) { + newAchievement.setClickCallback([password = password.get()](Achievement &achievement) { + if (password.empty()) + achievement.setUnlocked(true); + else + PopupTextInput::open("Enter Password", "Enter the password to unlock this achievement", [password, &achievement](const std::string &input) { + if (input == password) + achievement.setUnlocked(true); + else + PopupInfo::open("The password you entered was incorrect."); + }); + }); + + if (unlockedJson.contains("achievements") && unlockedJson["achievements"].is_array()) { + for (const auto &unlockedAchievement : unlockedJson["achievements"]) { + if (unlockedAchievement.is_string() && unlockedAchievement.get() == achievement["name"].get()) { + newAchievement.setUnlocked(true); + break; + } + } + } + } + } + } + } + } catch (const nlohmann::json::exception &e) { + log::error("Failed to load challenge project: {}", e.what()); + return false; + } + + PopupInfo::open(challengeDescription); + + + return true; + }, + .store = [](const std::fs::path &basePath, Tar &tar) { + if (!challengeAchievement.empty()) + tar.writeString(basePath / "achievements.json", challengeAchievement); + if (!challengeDescription.empty()) + tar.writeString(basePath / "description.txt", challengeDescription); + + for (const auto &[iconPath, data] : icons) { + tar.writeVector(basePath / iconPath, data); + } + + nlohmann::json unlockedJson; + + unlockedJson["achievements"] = nlohmann::json::array(); + for (const auto &[categoryName, achievements] : AchievementManager::getAchievements()) { + for (const auto &[achievementName, achievement] : achievements) { + if (achievement->isTemporary() && achievement->isUnlocked()) { + unlockedJson["achievements"].push_back(achievementName); + } + } + } + + tar.writeString(basePath / "unlocked.json", unlockedJson.dump(4)); + + return true; + } + }); + } + + } + + void registerAchievements() { + registerGettingStartedAchievements(); + registerHexEditorAchievements(); + registerPatternsAchievements(); + registerFindAchievements(); + registerDataProcessorAchievements(); + registerMiscAchievements(); + + registerEvents(); + registerChallengeAchievementHandlers(); + } + +} \ No newline at end of file diff --git a/plugins/builtin/source/content/data_formatters.cpp b/plugins/builtin/source/content/data_formatters.cpp index 4fff9aaf0..7503f3805 100644 --- a/plugins/builtin/source/content/data_formatters.cpp +++ b/plugins/builtin/source/content/data_formatters.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -48,6 +49,8 @@ namespace hex::plugin::builtin { }); ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.cpp", [](prv::Provider *provider, u64 offset, size_t size) { + AchievementManager::unlockAchievement("hex.builtin.achievement.hex_editor", "hex.builtin.achievement.hex_editor.copy_as.name"); + return formatLanguageArray(provider, offset, size, hex::format("constexpr std::array data = {{", size), "0x{0:02X}, ", "};"); }); diff --git a/plugins/builtin/source/content/data_processor_nodes.cpp b/plugins/builtin/source/content/data_processor_nodes.cpp index bca5c65b7..2866fc25a 100644 --- a/plugins/builtin/source/content/data_processor_nodes.cpp +++ b/plugins/builtin/source/content/data_processor_nodes.cpp @@ -1,7 +1,9 @@ #include +#include +#include + #include -#include #include #include #include @@ -467,6 +469,10 @@ namespace hex::plugin::builtin { const auto &address = this->getIntegerOnInput(0); const auto &data = this->getBufferOnInput(1); + if (!data.empty()) { + AchievementManager::unlockAchievement("hex.builtin.achievement.data_processor", "hex.builtin.achievement.data_processor.modify_data.name"); + } + this->setOverlayData(address, data); } }; diff --git a/plugins/builtin/source/content/project.cpp b/plugins/builtin/source/content/project.cpp index c6421c6e9..4c160f189 100644 --- a/plugins/builtin/source/content/project.cpp +++ b/plugins/builtin/source/content/project.cpp @@ -5,6 +5,8 @@ #include #include +#include + #include #include @@ -160,6 +162,9 @@ namespace hex::plugin::builtin { resetPath.release(); } + AchievementManager::unlockAchievement("hex.builtin.achievement.starting_out", "hex.builtin.achievement.starting_out.save_project.name"); + + return result; } diff --git a/plugins/builtin/source/content/providers/file_provider.cpp b/plugins/builtin/source/content/providers/file_provider.cpp index 88718bbc8..0b795667e 100644 --- a/plugins/builtin/source/content/providers/file_provider.cpp +++ b/plugins/builtin/source/content/providers/file_provider.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -247,6 +248,8 @@ namespace hex::plugin::builtin { this->m_file.close(); + AchievementManager::unlockAchievement("hex.builtin.achievement.starting_out", "hex.builtin.achievement.starting_out.open_file.name"); + return true; } diff --git a/plugins/builtin/source/content/views.cpp b/plugins/builtin/source/content/views.cpp index fc59586ff..4301613b5 100644 --- a/plugins/builtin/source/content/views.cpp +++ b/plugins/builtin/source/content/views.cpp @@ -20,6 +20,7 @@ #include "content/views/view_find.hpp" #include "content/views/view_theme_manager.hpp" #include "content/views/view_logs.hpp" +#include "content/views/view_achievements.hpp" namespace hex::plugin::builtin { @@ -46,6 +47,7 @@ namespace hex::plugin::builtin { ContentRegistry::Views::add(); ContentRegistry::Views::add(); ContentRegistry::Views::add(); + ContentRegistry::Views::add(); } } \ No newline at end of file diff --git a/plugins/builtin/source/content/views/view_about.cpp b/plugins/builtin/source/content/views/view_about.cpp index 897e9dd90..4ba28c9d4 100644 --- a/plugins/builtin/source/content/views/view_about.cpp +++ b/plugins/builtin/source/content/views/view_about.cpp @@ -1,6 +1,7 @@ #include "content/views/view_about.hpp" #include +#include #include #include @@ -23,7 +24,8 @@ namespace hex::plugin::builtin { ContentRegistry::Interface::addMenuItemSeparator({ "hex.builtin.menu.help" }, 2000); ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.help", "hex.builtin.view.help.documentation" }, 3000, Shortcut::None, [] { - hex::openWebpage("https://imhex.werwolv.net/docs"); + hex::openWebpage("https://docs.werwolv.net/imhex"); + AchievementManager::unlockAchievement("hex.builtin.achievement.starting_out", "hex.builtin.achievement.starting_out.docs.name"); }); ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.help", "hex.builtin.menu.help.ask_for_help" }, 4000, CTRLCMD + SHIFT + Keys::D, [] { diff --git a/plugins/builtin/source/content/views/view_achievements.cpp b/plugins/builtin/source/content/views/view_achievements.cpp new file mode 100644 index 000000000..9f111535e --- /dev/null +++ b/plugins/builtin/source/content/views/view_achievements.cpp @@ -0,0 +1,378 @@ +#include "content/views/view_achievements.hpp" + +#include + +#include + +#include + +#include + +namespace hex::plugin::builtin { + + ViewAchievements::ViewAchievements() : View("hex.builtin.view.achievements.name") { + ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.extras", "hex.builtin.view.achievements.name" }, 2600, Shortcut::None, [&, this] { + this->m_viewOpen = true; + this->getWindowOpenState() = true; + }); + + EventManager::subscribe(this, [this](const Achievement &achievement) { + this->m_achievementUnlockQueue.push_back(&achievement); + }); + + this->m_showPopup = bool(ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.achievement_popup", 1)); + } + + ViewAchievements::~ViewAchievements() { + EventManager::unsubscribe(this); + } + + void drawAchievement(ImDrawList *drawList, const AchievementManager::AchievementNode *node, ImVec2 position) { + const auto achievementSize = scaled({ 50, 50 }); + + auto &achievement = *node->achievement; + + const auto borderColor = [&] { + if (achievement.isUnlocked()) + return ImGui::GetCustomColorU32(ImGuiCustomCol_ToolbarYellow, 1.0F); + else if (node->isUnlockable()) + return ImGui::GetColorU32(ImGuiCol_Button, 1.0F); + else + return ImGui::GetColorU32(ImGuiCol_PlotLines, 1.0F); + }(); + + const auto fillColor = [&] { + if (achievement.isUnlocked()) + return ImGui::GetColorU32(ImGuiCol_FrameBg, 1.0F) | 0xFF000000; + else if (node->isUnlockable()) + return (u32(ImColor(ImLerp(ImGui::GetStyleColorVec4(ImGuiCol_TextDisabled), ImGui::GetStyleColorVec4(ImGuiCol_Text), sinf(ImGui::GetTime() * 6.0F) * 0.5F + 0.5F))) & 0x00FFFFFF) | 0x80000000; + else + return ImGui::GetColorU32(ImGuiCol_TextDisabled, 0.5F); + }(); + + if (achievement.isUnlocked()) { + drawList->AddRectFilled(position, position + achievementSize, fillColor, 5_scaled, 0); + drawList->AddRect(position, position + achievementSize, borderColor, 5_scaled, 0, 2_scaled); + } else { + drawList->AddRectFilled(position, position + achievementSize, ImGui::GetColorU32(ImGuiCol_WindowBg) | 0xFF000000, 5_scaled, 0); + } + + if (const auto &icon = achievement.getIcon(); icon.isValid()) { + ImVec2 iconSize; + if (icon.getSize().x > icon.getSize().y) { + iconSize.x = achievementSize.x; + iconSize.y = iconSize.x / icon.getSize().x * icon.getSize().y; + } else { + iconSize.y = achievementSize.y; + iconSize.x = iconSize.y / icon.getSize().y * icon.getSize().x; + } + + iconSize *= 0.7F; + + ImVec2 margin = (achievementSize - iconSize) / 2.0F; + drawList->AddImage(icon, position + margin, position + margin + iconSize); + } + + if (!achievement.isUnlocked()) { + drawList->AddRectFilled(position, position + achievementSize, fillColor, 5_scaled, 0); + drawList->AddRect(position, position + achievementSize, borderColor, 5_scaled, 0, 2_scaled); + } + + auto tooltipPos = position + ImVec2(achievementSize.x, 0); + auto tooltipSize = achievementSize * ImVec2(4, 0); + + if (ImGui::IsMouseHoveringRect(position, position + achievementSize)) { + ImGui::SetNextWindowPos(tooltipPos); + ImGui::SetNextWindowSize(tooltipSize); + if (ImGui::BeginTooltip()) { + if (achievement.isBlacked() && !achievement.isUnlocked()) { + ImGui::TextUnformatted("[ ??? ]"); + } else { + ImGui::BeginDisabled(!achievement.isUnlocked()); + ImGui::TextUnformatted(LangEntry(achievement.getUnlocalizedName())); + + if (auto requiredProgress = achievement.getRequiredProgress(); requiredProgress > 1) { + ImGui::ProgressBar(float(achievement.getProgress()) / float(requiredProgress + 1), ImVec2(achievementSize.x * 4, 5_scaled), ""); + } + + bool separator = false; + + if (achievement.getClickCallback() && !achievement.isUnlocked()) { + ImGui::Separator(); + separator = true; + + ImGui::TextFormattedColored(ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarYellow), "[ {} ]", LangEntry("hex.builtin.view.achievements.click")); + } + + if (const auto &desc = achievement.getUnlocalizedDescription(); !desc.empty()) { + if (!separator) + ImGui::Separator(); + else + ImGui::NewLine(); + + ImGui::TextFormattedWrapped("{}", LangEntry(desc)); + } + ImGui::EndDisabled(); + } + + ImGui::EndTooltip(); + } + + if (!achievement.isUnlocked() && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) { + if (ImGui::GetIO().KeyShift) { + #if defined (DEBUG) + AchievementManager::unlockAchievement(node->achievement->getUnlocalizedCategory(), node->achievement->getUnlocalizedName()); + #endif + } else { + if (auto clickCallback = achievement.getClickCallback(); clickCallback) + clickCallback(achievement); + } + } + } + } + + void drawOverlay(ImDrawList *drawList, ImVec2 windowMin, ImVec2 windowMax, const std::string &currCategory) { + auto &achievements = AchievementManager::getAchievements()[currCategory]; + auto unlockedCount = std::count_if(achievements.begin(), achievements.end(), [](const auto &entry) { + const auto &[name, achievement] = entry; + return achievement->isUnlocked(); + }); + + auto invisibleCount = std::count_if(achievements.begin(), achievements.end(), [](const auto &entry) { + const auto &[name, achievement] = entry; + return achievement->isInvisible(); + }); + + auto unlockedText = hex::format("{}: {} / {}{}", "hex.builtin.view.achievements.unlocked_count"_lang, unlockedCount, achievements.size() - invisibleCount, invisibleCount > 0 ? "+" : " "); + + auto &style = ImGui::GetStyle(); + auto overlaySize = ImGui::CalcTextSize(unlockedText.c_str()) + style.ItemSpacing + style.WindowPadding * 2.0F; + auto padding = scaled({ 10, 10 }); + + auto overlayPos = ImVec2(windowMax.x - overlaySize.x - padding.x, windowMin.y + padding.y); + + drawList->AddRectFilled(overlayPos, overlayPos + overlaySize, ImGui::GetColorU32(ImGuiCol_WindowBg, 0.8F)); + drawList->AddRect(overlayPos, overlayPos + overlaySize, ImGui::GetColorU32(ImGuiCol_Border)); + + ImGui::SetCursorScreenPos(overlayPos + padding); + ImGui::BeginGroup(); + + ImGui::TextUnformatted(unlockedText.c_str()); + + ImGui::EndGroup(); + } + + void drawBackground(ImDrawList *drawList, ImVec2 min, ImVec2 max, ImVec2 offset) { + const auto patternSize = scaled({ 10, 10 }); + + const auto darkColor = ImGui::GetColorU32(ImGuiCol_TableRowBg); + const auto lightColor = ImGui::GetColorU32(ImGuiCol_TableRowBgAlt); + + drawList->AddRect(min, max, ImGui::GetColorU32(ImGuiCol_Border), 0.0F, 0, 1.0_scaled); + + bool light = false; + bool prevStart = false; + for (float x = min.x + offset.x; x < max.x; x += i32(patternSize.x)) { + if (prevStart == light) + light = !light; + prevStart = light; + + for (float y = min.y + offset.y; y < max.y; y += i32(patternSize.y)) { + drawList->AddRectFilled({ x, y }, { x + patternSize.x, y + patternSize.y }, light ? lightColor : darkColor); + light = !light; + } + } + } + + ImVec2 ViewAchievements::drawAchievementTree(ImDrawList *drawList, const AchievementManager::AchievementNode * prevNode, const std::vector &nodes, ImVec2 position) { + ImVec2 maxPos = position; + for (auto &node : nodes) { + if (node->achievement->isInvisible() && !node->achievement->isUnlocked()) + continue; + + if (!node->visibilityParents.empty()) { + bool visible = true; + for (auto &parent : node->visibilityParents) { + if (!parent->achievement->isUnlocked()) { + visible = false; + break; + } + } + + if (!visible) + continue; + } + + drawList->ChannelsSetCurrent(1); + + if (prevNode != nullptr) { + if (prevNode->achievement->getUnlocalizedCategory() != node->achievement->getUnlocalizedCategory()) + continue; + + auto start = prevNode->position + scaled({ 25, 25 }); + auto end = position + scaled({ 25, 25 }); + auto middle = ((start + end) / 2.0F) - scaled({ 50, 0 }); + + const auto color = [prevNode]{ + if (prevNode->achievement->isUnlocked()) + return ImGui::GetColorU32(ImGuiCol_Text) | 0xFF000000; + else + return ImGui::GetColorU32(ImGuiCol_TextDisabled) | 0xFF000000; + }(); + + drawList->AddBezierQuadratic(start, middle, end, color, 2_scaled); + + if (this->m_achievementToGoto != nullptr) { + if (this->m_achievementToGoto == node->achievement) { + this->m_offset = position - scaled({ 100, 100 }); + } + } + } + + drawList->ChannelsSetCurrent(2); + + drawAchievement(drawList, node, position); + + node->position = position; + auto newMaxPos = drawAchievementTree(drawList, node, node->children, position + scaled({ 150, 0 })); + if (newMaxPos.x > maxPos.x) + maxPos.x = newMaxPos.x; + if (newMaxPos.y > maxPos.y) + maxPos.y = newMaxPos.y; + + position.y = maxPos.y + 100_scaled; + } + + return maxPos; + } + + void ViewAchievements::drawContent() { + if (ImGui::Begin(View::toWindowName("hex.builtin.view.achievements.name").c_str(), &this->m_viewOpen, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoDocking)) { + if (ImGui::BeginTabBar("##achievement_categories")) { + auto &startNodes = AchievementManager::getAchievementStartNodes(); + + std::vector categories; + for (const auto &[categoryName, achievements] : startNodes) { + categories.push_back(categoryName); + } + + std::reverse(categories.begin(), categories.end()); + + for (const auto &categoryName : categories) { + const auto &achievements = startNodes[categoryName]; + + bool visible = false; + for (const auto &achievement : achievements) { + if (achievement->isUnlocked() || achievement->isUnlockable()) { + visible = true; + break; + } + } + + if (!visible) + continue; + + ImGuiTabItemFlags flags = ImGuiTabItemFlags_None; + + if (this->m_achievementToGoto != nullptr) { + if (this->m_achievementToGoto->getUnlocalizedCategory() == categoryName) { + flags |= ImGuiTabItemFlags_SetSelected; + } + } + + if (ImGui::BeginTabItem(LangEntry(categoryName), nullptr, flags)) { + auto drawList = ImGui::GetWindowDrawList(); + + const auto cursorPos = ImGui::GetCursorPos(); + const auto windowPos = ImGui::GetWindowPos() + ImVec2(0, cursorPos.y); + const auto windowSize = ImGui::GetWindowSize() - ImVec2(0, cursorPos.y);; + const float borderSize = 20.0_scaled; + + const auto windowPadding = ImGui::GetStyle().WindowPadding; + const auto innerWindowPos = windowPos + ImVec2(borderSize, borderSize); + const auto innerWindowSize = windowSize - ImVec2(borderSize * 2, borderSize * 2) - ImVec2(0, ImGui::GetTextLineHeightWithSpacing()); + drawList->PushClipRect(innerWindowPos, innerWindowPos + innerWindowSize, true); + + drawList->ChannelsSplit(4); + + drawList->ChannelsSetCurrent(0); + + drawBackground(drawList, innerWindowPos, innerWindowPos + innerWindowSize, this->m_offset); + auto maxPos = drawAchievementTree(drawList, nullptr, achievements, innerWindowPos + scaled({ 100, 100 }) + this->m_offset); + + drawList->ChannelsSetCurrent(3); + + drawOverlay(drawList, innerWindowPos, innerWindowPos + innerWindowSize, categoryName); + + drawList->ChannelsMerge(); + + if (ImGui::IsMouseHoveringRect(innerWindowPos, innerWindowPos + innerWindowSize)) { + auto dragDelta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Left); + this->m_offset += dragDelta; + ImGui::ResetMouseDragDelta(ImGuiMouseButton_Left); + } + + this->m_offset = -ImClamp(-this->m_offset, { 0, 0 }, ImMax(maxPos - innerWindowPos - innerWindowSize, { 0, 0 })); + + drawList->PopClipRect(); + + ImGui::SetCursorScreenPos(innerWindowPos + ImVec2(0, innerWindowSize.y + windowPadding.y)); + ImGui::BeginGroup(); + { + if (ImGui::Checkbox("Show popup", &this->m_showPopup)) + ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.achievement_popup", i64(this->m_showPopup)); + } + ImGui::EndGroup(); + + ImGui::EndTabItem(); + } + } + + ImGui::EndTabBar(); + } + } + ImGui::End(); + + this->getWindowOpenState() = this->m_viewOpen; + + this->m_achievementToGoto = nullptr; + } + + void ViewAchievements::drawAlwaysVisible() { + if (this->m_achievementUnlockQueueTimer >= 0 && this->m_showPopup) { + this->m_achievementUnlockQueueTimer -= ImGui::GetIO().DeltaTime; + + if (this->m_currAchievement != nullptr) { + + const ImVec2 windowSize = scaled({ 200, 55 }); + ImGui::SetNextWindowPos(ImHexApi::System::getMainWindowPosition() + ImVec2 { ImHexApi::System::getMainWindowSize().x - windowSize.x - 100_scaled, 0 }); + ImGui::SetNextWindowSize(windowSize); + if (ImGui::Begin("##achievement_unlocked", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoInputs)) { + ImGui::TextFormattedColored(ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarYellow), "{}", "hex.builtin.view.achievements.unlocked"_lang); + + ImGui::Image(this->m_currAchievement->getIcon(), scaled({ 20, 20 })); + ImGui::SameLine(); + ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical); + ImGui::SameLine(); + ImGui::TextFormattedWrapped("{}", LangEntry(this->m_currAchievement->getUnlocalizedName())); + + if (ImGui::IsWindowHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) { + this->m_viewOpen = true; + this->getWindowOpenState() = this->m_viewOpen; + this->m_achievementToGoto = this->m_currAchievement; + } + } + ImGui::End(); + } + } else { + this->m_achievementUnlockQueueTimer = -1.0F; + this->m_currAchievement = nullptr; + if (!this->m_achievementUnlockQueue.empty()) { + this->m_currAchievement = this->m_achievementUnlockQueue.front(); + this->m_achievementUnlockQueue.pop_front(); + this->m_achievementUnlockQueueTimer = 2.5F; + } + } + } + +} \ No newline at end of file diff --git a/plugins/builtin/source/content/views/view_bookmarks.cpp b/plugins/builtin/source/content/views/view_bookmarks.cpp index eb12e6df1..3e6ce29f4 100644 --- a/plugins/builtin/source/content/views/view_bookmarks.cpp +++ b/plugins/builtin/source/content/views/view_bookmarks.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -289,8 +290,10 @@ namespace hex::plugin::builtin { auto newProvider = ImHexApi::Provider::createProvider("hex.builtin.provider.view", true); if (auto *viewProvider = dynamic_cast(newProvider); viewProvider != nullptr) { viewProvider->setProvider(region.getStartAddress(), region.getSize(), provider); - if (viewProvider->open()) + if (viewProvider->open()) { EventManager::post(viewProvider); + AchievementManager::unlockAchievement("hex.builtin.achievement.hex_editor", "hex.builtin.achievement.hex_editor.open_new_view.name"); + } } }); } diff --git a/plugins/builtin/source/content/views/view_data_inspector.cpp b/plugins/builtin/source/content/views/view_data_inspector.cpp index 4e173ea59..64fedf741 100644 --- a/plugins/builtin/source/content/views/view_data_inspector.cpp +++ b/plugins/builtin/source/content/views/view_data_inspector.cpp @@ -4,8 +4,7 @@ #include -#include - +#include #include #include @@ -144,6 +143,8 @@ namespace hex::plugin::builtin { editingFunction, false }); + + AchievementManager::unlockAchievement("hex.builtin.achievement.patterns", "hex.builtin.achievement.patterns.data_inspector.name"); } catch (const pl::core::err::EvaluatorError::Exception &error) { log::error("Failed to get value of pattern '{}': {}", pattern->getDisplayName(), error.what()); } diff --git a/plugins/builtin/source/content/views/view_data_processor.cpp b/plugins/builtin/source/content/views/view_data_processor.cpp index ad41549a2..e944aeb83 100644 --- a/plugins/builtin/source/content/views/view_data_processor.cpp +++ b/plugins/builtin/source/content/views/view_data_processor.cpp @@ -2,12 +2,11 @@ #include "content/popups/popup_notification.hpp" #include - -#include +#include +#include #include -#include - +#include #include #include @@ -166,6 +165,8 @@ namespace hex::plugin::builtin { editing = ImGui::IsItemActive(); if (ImGui::Button("hex.builtin.nodes.custom.custom.edit"_lang, ImVec2(200_scaled, ImGui::GetTextLineHeightWithSpacing()))) { + AchievementManager::unlockAchievement("hex.builtin.achievement.data_processor", "hex.builtin.achievement.data_processor.custom_node.name"); + this->m_dataProcessor->getWorkspaceStack().push_back(&this->m_workspace); this->m_requiresAttributeUpdate = true; @@ -595,6 +596,7 @@ namespace hex::plugin::builtin { ImNodes::SetNodeScreenSpacePos(node->getId(), this->m_rightClickedCoords); workspace.nodes.push_back(std::move(node)); ImHexApi::Provider::markDirty(); + AchievementManager::unlockAchievement("hex.builtin.achievement.data_processor", "hex.builtin.achievement.data_processor.place_node.name"); } ImGui::EndPopup(); @@ -818,6 +820,8 @@ namespace hex::plugin::builtin { fromAttr->addConnectedAttribute(newLink.getId(), toAttr); toAttr->addConnectedAttribute(newLink.getId(), fromAttr); + + AchievementManager::unlockAchievement("hex.builtin.achievement.data_processor", "hex.builtin.achievement.data_processor.create_connection.name"); } while (false); } } diff --git a/plugins/builtin/source/content/views/view_find.cpp b/plugins/builtin/source/content/views/view_find.cpp index 2edaea4e2..a3ed4162b 100644 --- a/plugins/builtin/source/content/views/view_find.cpp +++ b/plugins/builtin/source/content/views/view_find.cpp @@ -1,6 +1,8 @@ #include "content/views/view_find.hpp" #include +#include + #include #include @@ -439,6 +441,16 @@ namespace hex::plugin::builtin { void ViewFind::runSearch() { Region searchRegion = this->m_searchSettings.region; + if (this->m_searchSettings.mode == SearchSettings::Mode::Strings) + AchievementManager::unlockAchievement("hex.builtin.achievement.find", "hex.builtin.achievement.find.find_strings.name"); + else if (this->m_searchSettings.mode == SearchSettings::Mode::Sequence) + AchievementManager::unlockAchievement("hex.builtin.achievement.find", "hex.builtin.achievement.find.find_specific_string.name"); + else if (this->m_searchSettings.mode == SearchSettings::Mode::Value) { + if (this->m_searchSettings.value.inputMin == "250" && this->m_searchSettings.value.inputMax == "1000") + AchievementManager::unlockAchievement("hex.builtin.achievement.find", "hex.builtin.achievement.find.find_specific_string.name"); + } + + this->m_searchTask = TaskManager::createTask("hex.builtin.view.find.searching", searchRegion.getSize(), [this, settings = this->m_searchSettings, searchRegion](auto &task) { auto provider = ImHexApi::Provider::get(); diff --git a/plugins/builtin/source/content/views/view_hashes.cpp b/plugins/builtin/source/content/views/view_hashes.cpp index 8849b6b46..56a111545 100644 --- a/plugins/builtin/source/content/views/view_hashes.cpp +++ b/plugins/builtin/source/content/views/view_hashes.cpp @@ -3,6 +3,8 @@ #include "content/providers/memory_file_provider.hpp" #include +#include + #include #include @@ -176,8 +178,10 @@ namespace hex::plugin::builtin { ImGui::BeginDisabled(this->m_newHashName.empty() || this->m_selectedHash == nullptr); if (ImGui::IconButton(ICON_VS_ADD, ImGui::GetStyleColorVec4(ImGuiCol_Text))) { - if (this->m_selectedHash != nullptr) + if (this->m_selectedHash != nullptr) { this->m_hashFunctions->push_back(this->m_selectedHash->create(this->m_newHashName)); + AchievementManager::unlockAchievement("hex.builtin.achievement.misc", "hex.builtin.achievement.misc.create_hash.name"); + } } ImGui::EndDisabled(); diff --git a/plugins/builtin/source/content/views/view_hex_editor.cpp b/plugins/builtin/source/content/views/view_hex_editor.cpp index bf0952da1..0379b8e1a 100644 --- a/plugins/builtin/source/content/views/view_hex_editor.cpp +++ b/plugins/builtin/source/content/views/view_hex_editor.cpp @@ -2,10 +2,13 @@ #include #include -#include -#include -#include #include +#include + +#include +#include + +#include #include #include @@ -540,6 +543,8 @@ namespace hex::plugin::builtin { auto remainingSize = std::min(size - i, bytes.size()); provider->write(provider->getBaseAddress() + address + i, bytes.data(), remainingSize); } + + AchievementManager::unlockAchievement("hex.builtin.achievement.hex_editor", "hex.builtin.achievement.hex_editor.fill.name"); } private: diff --git a/plugins/builtin/source/content/views/view_information.cpp b/plugins/builtin/source/content/views/view_information.cpp index 259a4a41a..4f579ce5d 100644 --- a/plugins/builtin/source/content/views/view_information.cpp +++ b/plugins/builtin/source/content/views/view_information.cpp @@ -1,6 +1,7 @@ #include "content/views/view_information.hpp" #include +#include #include #include @@ -64,6 +65,8 @@ namespace hex::plugin::builtin { } void ViewInformation::analyze() { + AchievementManager::unlockAchievement("hex.builtin.achievement.misc", "hex.builtin.achievement.misc.analyze_file.name"); + this->m_analyzerTask = TaskManager::createTask("hex.builtin.view.information.analyzing", 0, [this](auto &task) { auto provider = ImHexApi::Provider::get(); diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index 373b7a386..2d1b4050b 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -1,6 +1,8 @@ #include "content/views/view_pattern_editor.hpp" #include +#include +#include #include #include @@ -11,7 +13,6 @@ #include #include -#include #include #include @@ -1086,6 +1087,7 @@ namespace hex::plugin::builtin { auto selection = ImHexApi::HexEditor::getSelection(); appendEditorText(hex::format("{0} {0}_at_0x{1:02X} @ 0x{1:02X};", type, selection->getStartAddress())); + AchievementManager::unlockAchievement("hex.builtin.achievement.patterns", "hex.builtin.achievement.patterns.place_menu.name"); } void ViewPatternEditor::appendArray(const std::string &type, size_t size) { @@ -1115,6 +1117,7 @@ namespace hex::plugin::builtin { PopupFileChooser::open(paths, std::vector{ { "Pattern File", "hexpat" } }, false, [this, provider](const std::fs::path &path) { this->loadPatternFile(path, provider); + AchievementManager::unlockAchievement("hex.builtin.achievement.patterns", "hex.builtin.achievement.patterns.load_existing.name"); }); }, ImHexApi::Provider::isValid); diff --git a/plugins/builtin/source/content/views/view_store.cpp b/plugins/builtin/source/content/views/view_store.cpp index 971126f15..e923f4e59 100644 --- a/plugins/builtin/source/content/views/view_store.cpp +++ b/plugins/builtin/source/content/views/view_store.cpp @@ -1,5 +1,6 @@ #include "content/views/view_store.hpp" #include +#include #include #include @@ -93,6 +94,7 @@ namespace hex::plugin::builtin { } else if (!entry.installed) { if (ImGui::Button("hex.builtin.view.store.download"_lang, buttonSize)) { entry.downloading = this->download(category.path, entry.fileName, entry.link, false); + AchievementManager::unlockAchievement("hex.builtin.achievement.misc", "hex.builtin.achievement.misc.download_from_store.name"); } } else { if (ImGui::Button("hex.builtin.view.store.remove"_lang, buttonSize)) { diff --git a/plugins/builtin/source/content/welcome_screen.cpp b/plugins/builtin/source/content/welcome_screen.cpp index a43bffe4c..e8ffda2a1 100644 --- a/plugins/builtin/source/content/welcome_screen.cpp +++ b/plugins/builtin/source/content/welcome_screen.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -284,6 +285,10 @@ namespace hex::plugin::builtin { { if (ImGui::DescriptionButton("hex.builtin.welcome.learn.latest.title"_lang, "hex.builtin.welcome.learn.latest.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0))) hex::openWebpage("hex.builtin.welcome.learn.latest.link"_lang); + if (ImGui::DescriptionButton("hex.builtin.welcome.learn.imhex.title"_lang, "hex.builtin.welcome.learn.imhex.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0))) { + AchievementManager::unlockAchievement("hex.builtin.achievement.starting_out", "hex.builtin.achievement.starting_out.docs.name"); + hex::openWebpage("hex.builtin.welcome.learn.imhex.link"_lang); + } if (ImGui::DescriptionButton("hex.builtin.welcome.learn.pattern.title"_lang, "hex.builtin.welcome.learn.pattern.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0))) hex::openWebpage("hex.builtin.welcome.learn.pattern.link"_lang); if (ImGui::DescriptionButton("hex.builtin.welcome.learn.plugins.title"_lang, "hex.builtin.welcome.learn.plugins.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0))) @@ -527,6 +532,10 @@ namespace hex::plugin::builtin { if (showTipOfTheDay) PopupTipOfTheDay::open(); } + + if (hasCrashed) { + AchievementManager::unlockAchievement("hex.builtin.achievement.starting_out", "hex.builtin.achievement.starting_out.crash.name"); + } } } diff --git a/plugins/builtin/source/plugin_builtin.cpp b/plugins/builtin/source/plugin_builtin.cpp index be1a5841d..97b12b899 100644 --- a/plugins/builtin/source/plugin_builtin.cpp +++ b/plugins/builtin/source/plugin_builtin.cpp @@ -38,6 +38,7 @@ namespace hex::plugin::builtin { void registerNetworkEndpoints(); void registerFileHandlers(); void registerProjectHandlers(); + void registerAchievements(); void addFooterItems(); void addTitleBarButtons(); @@ -96,6 +97,7 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") { registerFileHandlers(); registerProjectHandlers(); registerCommandForwarders(); + registerAchievements(); addFooterItems(); addTitleBarButtons(); diff --git a/plugins/builtin/source/ui/pattern_drawer.cpp b/plugins/builtin/source/ui/pattern_drawer.cpp index 25fee0f93..e7778d8bb 100644 --- a/plugins/builtin/source/ui/pattern_drawer.cpp +++ b/plugins/builtin/source/ui/pattern_drawer.cpp @@ -21,8 +21,10 @@ #include #include -#include +#include #include + +#include #include #include @@ -332,6 +334,7 @@ namespace hex::plugin::builtin::ui { if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) { this->m_editingPattern = &pattern; this->m_editingPatternOffset = pattern.getOffset(); + AchievementManager::unlockAchievement("hex.builtin.achievement.patterns", "hex.builtin.achievement.patterns.modify_data.name"); } ImGui::SameLine(0, 0);