From bce88e1d9bac79e5ca97fe6cb98cfb8fae0657b5 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Sat, 31 Oct 2026 16:28:18 +0000 Subject: [PATCH] Decompile fn_23737 (CSession::ToggleTrackedAchievement) Batch #8247 by eAthena: 0 byte-identical, 1 confirmed by peer review. - fn_23737 CSession::ToggleTrackedAchievement: logic confirmed by peer review Peer-reviewed-by: System4z, Toshiro, dori Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- Source/Client/Session.h | 15 ++++-- Source/Client/SessionAchievements.cpp | 76 +++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 5 deletions(-) diff --git a/Source/Client/Session.h b/Source/Client/Session.h index 84efb5f5..8b0f2a1e 100644 --- a/Source/Client/Session.h +++ b/Source/Client/Session.h @@ -67,14 +67,18 @@ struct MapPosEntry { }; struct SessionRecord6178Entry { - /* 0000 */ std::string unknown_0000; - /* 0018 */ int unknown_0018; + // INLINED + SessionRecord6178Entry(const std::string& text, bool completed) : text(text), completed(completed) { + } + + /* 0000 */ std::string text; + /* 0018 */ bool completed; }; struct SessionRecord6178 { - /* 0000 */ unsigned char unknown_0000; - /* 0001 */ unsigned char unknown_0001; - /* 0004 */ int id; + /* 0000 */ unsigned char unknown_0000 = 0; + /* 0001 */ unsigned char unknown_0001 = 0; + /* 0004 */ int id = -1; /* 0008 */ std::string unknown_0008; /* 0020 */ std::vector unknown_0020; }; @@ -655,6 +659,7 @@ public: int GetPetJobByEggItem(int eggItemId); const char* GetPetString(int id); int AddUnknown6160(int id); + bool ToggleTrackedAchievement(int id); const char* GetPetTalkName(int job); const char* GetPetTalkActionName(int action); void GetPetTalkText(int job, int hungerState, int action, char* text); diff --git a/Source/Client/SessionAchievements.cpp b/Source/Client/SessionAchievements.cpp index 2e8fd959..706d4b04 100644 --- a/Source/Client/SessionAchievements.cpp +++ b/Source/Client/SessionAchievements.cpp @@ -3,6 +3,8 @@ #include "Contents/Jobs/JobInheritance.h" #include "UI/Window/UIWindow.h" #include "UI/Window/UIWindowMgr.h" +#include "Contents/MessageTable.h" +#include "Utility/Text/FormatString.h" #include #include @@ -43,3 +45,77 @@ int CSession::AddUnknown6160(int id) { return value; } + +// OFFSET: 0x00E06580 +// FUNCTION: fn_23737 +bool CSession::ToggleTrackedAchievement(int id) { + std::vector& tracked = this->unknown_6178; + auto found = std::find_if(tracked.begin(), tracked.end(), [id](SessionRecord6178 record) { return id == record.id; }); + + SessionRecord6144* progress; + auto record = this->unknown_6144.find(id); + if (record != this->unknown_6144.end()) { + progress = &record->second; + } else { + this->unknown_6144.insert(std::make_pair(id, SessionRecord6144())); + reinterpret_cast(&this->unknown_6144[id].unknown_0000)[0] = 1; + progress = &this->unknown_6144[id]; + } + + if (!progress) { + return false; + } + + if (found != tracked.end()) { + tracked.erase(found); + } else { + if (tracked.size() >= 3) { + g_windowMgr.SendNotice(1, reinterpret_cast(LookupMessage(0xA78)), 0x64FFFF, 0, 0, 0); + return false; + } + + AchievementInfo info; + g_achievementMgr->GetAchievement(info, id); + + SessionRecord6178 entry; + entry.id = id; + entry.unknown_0001 = reinterpret_cast(&progress->unknown_0000)[1]; + entry.unknown_0008 = info.title; + + for (unsigned int i = 0; i < info.rewards.size(); ++i) { + const AchievementReward& reward = info.rewards[i]; + std::string text; + bool completed = false; + + if (info.unknown_0064 == 0) { + if (reward.text.size() > 40) { + text = FormatOwnedString("- %s...", reward.text.substr(0, 40).c_str()); + } else { + text = FormatOwnedString("- %s", reward.text.c_str()); + } + + completed = static_cast(progress->unknown_0004[i]) > 0; + } else if (info.unknown_0064 == 1) { + std::string count = FormatOwnedString("(%d/%d)", progress->unknown_0004[i], reward.unknown_0018); + if (reward.text.size() + count.size() > 40) { + text = FormatOwnedString("- %s...%s", reward.text.substr(0, 40 - count.size()).c_str(), count.c_str()); + } else { + text = FormatOwnedString("- %s %s", reward.text.c_str(), count.c_str()); + } + + completed = static_cast(progress->unknown_0004[i]) == reward.unknown_0018; + } + + entry.unknown_0020.emplace_back(text, completed); + } + + tracked.push_back(entry); + } + + if (tracked.size() == 0) { + g_windowMgr.CloseWindow(0x10F); + return false; + } + + return true; +}