From fb82bac1e1263641d31e8bd9102fb5ab76cb178b Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Fri, 30 Oct 2026 04:21:55 +0000 Subject: [PATCH] Decompile fn_08151 (CRuneSystemMgr::HasRequiredItems) Batch #4640 by Millenium: 0 byte-identical, 1 confirmed by peer review. - fn_08151 CRuneSystemMgr::HasRequiredItems: logic confirmed by peer review Peer-reviewed-by: eAthena, Lumen, Qwenkler3.8 Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- Source/Contents/Items/RuneSystem.cpp | 71 +++++++++++++++++++++++++++- Source/Contents/Items/RuneSystem.h | 4 +- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/Source/Contents/Items/RuneSystem.cpp b/Source/Contents/Items/RuneSystem.cpp index 4aa33c09..148927de 100644 --- a/Source/Contents/Items/RuneSystem.cpp +++ b/Source/Contents/Items/RuneSystem.cpp @@ -21,6 +21,19 @@ extern "C" { #include #include +namespace EquipmentProperties { +class CEquipmentPropertiesMgr { +public: + static CEquipmentPropertiesMgr* GetInstance(); + void sub_6B6E10(const int* param1, const int* param2); + void sub_6B6AF0(const int* param1, const int* param2, int param3); +}; +} + +struct SessionMessengerContext { + int GetList0Size() const; +}; + // GLOBAL: gl_24845 CRuneSystemMgr* g_runeSystemMgr; @@ -620,7 +633,7 @@ bool RuneSetData::IsRewardStep(int step) const { // OFFSET: 0x00767FF0 // FUNCTION: fn_08151 -bool CRuneSystemMgr::HasRequiredItems(int listId) { +__declspec(noinline) bool CRuneSystemMgr::HasRequiredItems(int listId) { const auto found = this->m_itemLists.find(listId); if (found == this->m_itemLists.end()) { return false; @@ -707,12 +720,68 @@ int CRuneSystemMgr::SendRequest(int packetId, RuneData* rune, int value) { return 1; } +// OFFSET: 0x007684C0 +// FUNCTION: fn_08153 +int CRuneSystemMgr::UpdateOwnedDecomItems() { + this->m_ownedDecomItems.clear(); + const auto* session = reinterpret_cast(&g_session); + for (int i = 0; i < session->GetList0Size(); ++i) { + ITEM_INFO item = g_session.GetInventoryItemAt(i); + if (this->m_itemDecoms.find(std::atoi(item.itemId.c_str())) != this->m_itemDecoms.end()) { + this->m_ownedDecomItems.push_back(std::atoi(item.itemId.c_str())); + } + } + return static_cast(this->m_ownedDecomItems.size()); +} + // OFFSET: 0x00768780 // FUNCTION: fn_08154 void CRuneSystemMgr::SetCurSlotCount(const int& count) { this->m_curSlotCount = count; } +// OFFSET: 0x007687B0 +// FUNCTION: fn_08155 +void CRuneSystemMgr::SetCurRuneSet(int tagId, int runeSetId, int grade, int slotCount) { + int oldId = 0; + if (this->m_curRuneSet != nullptr) { + oldId = static_cast(this->m_curRuneSet->m_id); + if (this->m_curRuneSet->m_id != runeSetId) { + EquipmentProperties::CEquipmentPropertiesMgr* mgr = EquipmentProperties::CEquipmentPropertiesMgr::GetInstance(); + const int one = 1; + mgr->sub_6B6E10(&one, &oldId); + } + } + + if (runeSetId == 0) { + this->m_curRuneSet = nullptr; + return; + } + + RuneSetData* runeSet = static_cast(this->FindRune(tagId, 0, runeSetId, nullptr)); + this->m_curRuneSet = runeSet; + if (runeSet != nullptr) { + int activeCount = 0; + for (RuneData* slot : runeSet->m_slots) { + if (slot != nullptr) { + activeCount += slot->m_active; + } + } + this->m_curSlotCount = activeCount; + if (grade != -1) { + runeSet->m_grade = grade; + } + if (slotCount != -1) { + this->m_curSlotCount = slotCount; + } + if (oldId != runeSetId) { + EquipmentProperties::CEquipmentPropertiesMgr* mgr = EquipmentProperties::CEquipmentPropertiesMgr::GetInstance(); + const int one = 1; + mgr->sub_6B6AF0(&one, &runeSetId, 0); + } + } +} + // OFFSET: 0x007688A0 // FUNCTION: fn_08156 void CRuneSystemMgr::SetSelectTag(int tagId) { diff --git a/Source/Contents/Items/RuneSystem.h b/Source/Contents/Items/RuneSystem.h index 2f5147d4..8d8ffc2b 100644 --- a/Source/Contents/Items/RuneSystem.h +++ b/Source/Contents/Items/RuneSystem.h @@ -166,8 +166,10 @@ public: void Reset(); void ClearCurRuneSet(); void LoadDefaultTag(); - bool HasRequiredItems(int listId); + __declspec(noinline) bool HasRequiredItems(int listId); int SendRequest(int packetId, RuneData* rune, int value); + int UpdateOwnedDecomItems(); + void SetCurRuneSet(int tagId, int runeSetId, int grade, int slotCount); void SetCurSlotCount(const int& count); void SetSelectTag(int tagId); void SetRequestPending(bool pending);