1
0
mirror of synced 2025-01-25 15:53:43 +01:00

fix: Various achievements issues (Edit the Hex, ROM Hacks) (#1985)

### Problem description
As described in #1846:
- the `Edit the Hex` achievement doesn't unlock when it should
- the `ROM Hacks` achievement is not using event-driven architecture
(the functions call `unlockAchievement` themselves)

### Implementation description
Firstly, for the `Edit the Hex` achievement:
- replaced the old event listener on `EventPatchCreated` with a listener
on `EventProviderDataModified`, which picks up bytes changes
- ensured the provider data change comes from a File provider, else
unlocking the achievement wouldn't make sense
- *Note*: a discovered side effect is that the "Fill" function modifies
the provider byte per byte (with a for loop)
- there is no use in testing the size of the data change, as it is
always 1 byte
- the Fill function could probably be reworked to fill in whole regions
at a time?

About the `ROM Hacks` achievement:
- implemented the new, still unused `EventPatchCreated` event.
- signal signature is `const unsigned char *, u64, const IPSKind`:
buffer pointer, buffer size, and IPS kind (IPS/IPS32)
- make use of the `::post` and `::subscribe` methods on said event to
unlock the achievement
- **WARNING::behaviour change**: the event's `post` signal has been
moved in the success branch of the IPS generation condition, meaning
that achievement will only unlock if IPS patch export has worked. I felt
it would make more sense than unlocking an achievement on an error, if
there was any to raise.

---------

Signed-off-by: BioTheWolff <47079795+BioTheWolff@users.noreply.github.com>
This commit is contained in:
BioTheWolff 2024-12-06 00:36:42 +01:00 committed by GitHub
parent 1b9f4f33de
commit 2dcaf2c77b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 27 additions and 8 deletions

View File

@ -11,6 +11,7 @@
#include <hex/api/imhex_api.hpp>
#include <hex/helpers/logger.hpp>
#include <hex/helpers/patches.hpp>
#include <wolv/types/type_name.hpp>
@ -253,7 +254,12 @@ namespace hex {
EVENT_DEF(EventWindowInitialized);
EVENT_DEF(EventWindowDeinitializing, GLFWwindow *);
EVENT_DEF(EventBookmarkCreated, ImHexApi::Bookmarks::Entry&);
EVENT_DEF(EventPatchCreated, u64, u8, u8);
/**
* @brief Called upon creation of an IPS patch.
* As for now, the event only serves a purpose for the achievement unlock.
*/
EVENT_DEF(EventPatchCreated, const u8*, u64, const PatchKind);
EVENT_DEF(EventPatternEvaluating);
EVENT_DEF(EventPatternExecuted, const std::string&);
EVENT_DEF(EventPatternEditorChanged, const std::string&);

View File

@ -21,6 +21,11 @@ namespace hex {
MissingEOF
};
enum class PatchKind {
IPS,
IPS32
};
class Patches {
public:
Patches() = default;

View File

@ -1,8 +1,10 @@
#include <iostream>
#include <hex/api/achievement_manager.hpp>
#include <hex/api/project_file_manager.hpp>
#include <hex/api/event_manager.hpp>
#include <hex/helpers/crypto.hpp>
#include <hex/providers/provider.hpp>
#include <toasts/toast_notification.hpp>
#include <popups/popup_notification.hpp>
@ -192,10 +194,16 @@ namespace hex::plugin::builtin {
AchievementManager::unlockAchievement("hex.builtin.achievement.hex_editor", "hex.builtin.achievement.hex_editor.create_bookmark.name");
});
EventPatchCreated::subscribe([](u64, u8, u8) {
EventProviderDataModified::subscribe([](const prv::Provider *, u64, const u64, const u8*) {
// Warning: overlaps with the "Flood fill" achievement, since "Fill" works by writing to bytes one-by-one.
// Thus, we do not check for size, that will always be equal to 1 even during a fill operation.
AchievementManager::unlockAchievement("hex.builtin.achievement.hex_editor", "hex.builtin.achievement.hex_editor.modify_byte.name");
});
EventPatchCreated::subscribe([](const u8 *, u8, PatchKind) {
AchievementManager::unlockAchievement("hex.builtin.achievement.hex_editor", "hex.builtin.achievement.hex_editor.create_patch.name");
});
EventImHexStartupFinished::subscribe(AchievementManager::loadProgress);
EventAchievementUnlocked::subscribe([](const Achievement &) {

View File

@ -297,12 +297,12 @@ namespace hex::plugin::builtin {
}
if (data.has_value()) {
file.writeVector(data.value());
const auto& bytes = data.value();
file.writeVector(bytes);
EventPatchCreated::post(bytes.data(), bytes.size(), PatchKind::IPS);
} else {
handleIPSError(data.error());
}
AchievementManager::unlockAchievement("hex.builtin.achievement.hex_editor", "hex.builtin.achievement.hex_editor.create_patch.name");
});
});
});
@ -336,12 +336,12 @@ namespace hex::plugin::builtin {
}
if (data.has_value()) {
file.writeVector(data.value());
const std::vector<u8>& bytes = data.value();
file.writeVector(bytes);
EventPatchCreated::post(bytes.data(), bytes.size(), PatchKind::IPS32);
} else {
handleIPSError(data.error());
}
AchievementManager::unlockAchievement("hex.builtin.achievement.hex_editor", "hex.builtin.achievement.hex_editor.create_patch.name");
});
});
});