From a957bc9fa6b60b7bfe7285dcf5b714a3dea9119e Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Thu, 29 Oct 2026 21:47:18 +0000 Subject: [PATCH] Decompile 15 functions in Source/Contents/Items/RuneSystem.cpp, Source/Contents/Items/RuneSystem.h Batch #3398 by eAthena: 14 byte-identical, 1 confirmed by peer review. - fn_08117 CRuneSystemMgr::GetTagCount: byte-identical - fn_08118 CRuneSystemMgr::GetOwnedDecomItemCount: byte-identical - fn_08119 CRuneSystemMgr::IsInitialized: byte-identical - fn_08122 RuneSetData::CountSlots: logic confirmed by peer review - fn_08124 RuneData::GetName: byte-identical - fn_08127 CRuneSystemMgr::GetCurRuneSet: byte-identical - fn_08128 CRuneSystemMgr::GetCurSlotCount: byte-identical - fn_08130 RuneData::GetId: byte-identical - fn_08139 CRuneSystemMgr::GetSelectTag: byte-identical - fn_08140 RuneData::GetTagId: byte-identical - fn_08141 RuneData::GetActiveType: byte-identical - fn_08142 RuneSetData::GetGradeValue: byte-identical - fn_08144 CRuneSystemMgr::IsRequestPending: byte-identical - fn_08145 RuneData::GetResName: byte-identical - fn_08148 CRuneSystemMgr::ClearCurRuneSet: byte-identical Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). Adds to the build: Source/Contents/Items/RuneSystem.cpp --- Source/Contents/Items/RuneSystem.cpp | 248 +++++++++++++++++++++++++++ Source/Contents/Items/RuneSystem.h | 204 ++++++++++++++++++++++ data/compile.json | 1 + 3 files changed, 453 insertions(+) create mode 100644 Source/Contents/Items/RuneSystem.cpp create mode 100644 Source/Contents/Items/RuneSystem.h diff --git a/Source/Contents/Items/RuneSystem.cpp b/Source/Contents/Items/RuneSystem.cpp new file mode 100644 index 00000000..e04fc3e8 --- /dev/null +++ b/Source/Contents/Items/RuneSystem.cpp @@ -0,0 +1,248 @@ +#include "Contents/Items/RuneSystem.h" +#include "Client/Application/ApplicationWindow.h" +#include "Client/Session.h" +#include "Contents/Items/ItemInfo.h" +#include "Network/Connection/Connection.h" +#include "Network/Packets/PacketLengths.h" +#include "Script/LuaScript.h" +#include "Utility/Text/FormatString.h" + +extern "C" { +#include +} + +#include +#include + +// GLOBAL: gl_24845 +CRuneSystemMgr* g_runeSystemMgr; + +namespace { + struct RuneTagPacket { + /* 0000 */ std::uint16_t id; + /* 0002 */ std::uint16_t tagId; + }; + + struct RuneItemPacket { + /* 0000 */ std::uint16_t id; + /* 0002 */ std::uint16_t tagId; + /* 0004 */ int runeId; + }; + + struct RuneSelectPacket { + /* 0000 */ std::uint16_t id; + /* 0002 */ std::uint16_t tagId; + /* 0004 */ int runeId; + /* 0008 */ std::uint8_t value; + }; + + struct RuneIdPacket { + /* 0000 */ std::uint16_t id; + /* 0004 */ int runeId; + }; + + struct RuneHeaderPacket { + /* 0000 */ std::uint16_t id; + }; +} + +// OFFSET: 0x00764C30 + +// OFFSET: 0x00764DE0 + +// OFFSET: 0x007657D0 + +// OFFSET: 0x007659C0 + +// OFFSET: 0x00765B10 + +// OFFSET: 0x007660C0 + +// OFFSET: 0x00766920 + +// OFFSET: 0x00766970 + +// OFFSET: 0x00766A10 + +// OFFSET: 0x00766A30 + +// OFFSET: 0x00766A70 +// FUNCTION: fn_08117 +int CRuneSystemMgr::GetTagCount() const { + return static_cast(this->m_tags.size()); +} + +// OFFSET: 0x00766A80 +// FUNCTION: fn_08118 +int CRuneSystemMgr::GetOwnedDecomItemCount() const { + return static_cast(this->m_ownedDecomItems.size()); +} + +// OFFSET: 0x00766B10 +// FUNCTION: fn_08119 +bool CRuneSystemMgr::IsInitialized() const { + return this->m_initialized; +} + +// OFFSET: 0x00766B20 + +// OFFSET: 0x00766B60 + +// OFFSET: 0x00766B90 +// FUNCTION: fn_08122 +int RuneSetData::CountSlots() const { + int count = 0; + for (RuneData* rune : this->m_slots) { + if (rune) { + ++count; + } + } + + return count; +} + +// OFFSET: 0x00766C70 + +// OFFSET: 0x00766CA0 +// FUNCTION: fn_08124 +const char* RuneData::GetName() const { + return this->m_name.c_str(); +} + +// OFFSET: 0x00766CB0 + +// OFFSET: 0x00766CE0 + +// OFFSET: 0x00766DB0 +// FUNCTION: fn_08127 +RuneSetData* CRuneSystemMgr::GetCurRuneSet() const { + return this->m_curRuneSet; +} + +// OFFSET: 0x00766DC0 +// FUNCTION: fn_08128 +int CRuneSystemMgr::GetCurSlotCount() const { + return this->m_curSlotCount; +} + +// OFFSET: 0x00766DD0 + +// OFFSET: 0x00766E40 +// FUNCTION: fn_08130 +std::int64_t RuneData::GetId() const { + return this->m_id; +} + +// OFFSET: 0x00766E50 + +// OFFSET: 0x00766E60 + +// OFFSET: 0x00766EB0 + +// OFFSET: 0x00766F00 + +// OFFSET: 0x00766F60 + +// OFFSET: 0x00766F80 + +// OFFSET: 0x00767070 + +// OFFSET: 0x007670C0 + +// OFFSET: 0x00767130 +// FUNCTION: fn_08139 +int CRuneSystemMgr::GetSelectTag() const { + return this->m_selectTag; +} + +// OFFSET: 0x00767140 +// FUNCTION: fn_08140 +int RuneData::GetTagId() const { + return this->m_tagId; +} + +// OFFSET: 0x00767150 +// FUNCTION: fn_08141 +int RuneData::GetActiveType() const { + return this->m_activeType; +} + +// OFFSET: 0x00767160 +// FUNCTION: fn_08142 +int RuneSetData::GetGradeValue() const { + if (this->m_grade < 15) { + return this->m_gradeList[this->m_grade]; + } + + return 0; +} + +// OFFSET: 0x00767180 + +// OFFSET: 0x00767230 +// FUNCTION: fn_08144 +bool CRuneSystemMgr::IsRequestPending() const { + return this->m_requestPending; +} + +// OFFSET: 0x00767240 +// FUNCTION: fn_08145 +const char* RuneData::GetResName() const { + return this->m_resName.c_str(); +} + +// OFFSET: 0x00767D20 + +// OFFSET: 0x00767E60 +// FUNCTION: fn_08148 +void CRuneSystemMgr::ClearCurRuneSet() { + this->m_curRuneSet = nullptr; +} + +// OFFSET: 0x00767E70 + +// OFFSET: 0x00767FA0 + +// OFFSET: 0x00767FF0 + +// OFFSET: 0x00768240 + +// OFFSET: 0x00768780 + +// OFFSET: 0x007688A0 + +// OFFSET: 0x00768920 + +// OFFSET: 0x00768960 + +// OFFSET: 0x00768A00 + +// OFFSET: 0x00769240 + +// OFFSET: 0x00769440 + +// OFFSET: 0x00769640 + +// OFFSET: 0x007698F0 + +// OFFSET: 0x00769B80 + +// OFFSET: 0x00769EE0 + +// OFFSET: 0x0076A240 + +// OFFSET: 0x0076A470 + +// OFFSET: 0x0076A690 + +// OFFSET: 0x0076A940 + +// OFFSET: 0x0076AA40 + +// OFFSET: 0x0076AC70 + +// OFFSET: 0x0076AFE0 + +// OFFSET: 0x0076B280 + +// OFFSET: 0x0076B4B0 diff --git a/Source/Contents/Items/RuneSystem.h b/Source/Contents/Items/RuneSystem.h new file mode 100644 index 00000000..33af6df7 --- /dev/null +++ b/Source/Contents/Items/RuneSystem.h @@ -0,0 +1,204 @@ +#ifndef RAGNAROK_SOURCE_CONTENTS_ITEMS_RUNESYSTEM_H +#define RAGNAROK_SOURCE_CONTENTS_ITEMS_RUNESYSTEM_H + +#include +#include +#include +#include +#include +#include + +struct lua_State; + +// VTABLE: vt_00501 +class Decom_ItemInfo { +public: + Decom_ItemInfo(int itemId, int minCount, int maxCount, int percent) : m_itemId(itemId), m_minCount(minCount), m_maxCount(maxCount), m_percent(percent) { + } + + /* 0004 */ int m_itemId; + /* 0008 */ int m_minCount; + /* 000C */ int m_maxCount; + /* 0010 */ int m_percent; + + virtual ~Decom_ItemInfo(); +}; + +// VTABLE: vt_00499 +class RuneData { +public: + /* 0008 */ int m_kind; + /* 000C */ bool m_active; + /* 0010 */ std::int64_t m_id; + /* 0018 */ std::string m_name; + /* 0030 */ std::string m_resName; + /* 0048 */ int m_tagId; + /* 004C */ int m_activeType; + + RuneData(); + + virtual ~RuneData() { + } + + bool IsSame(const RuneData& other) const; + std::int64_t GetId() const; + bool IsActive() const; + const char* GetName() const; + const char* GetResName() const; + int GetTagId() const; + int GetActiveType() const; +}; + +#pragma pack(push, 1) +struct RuneSetReward { + /* 0000 */ std::int64_t values[7]; + /* 0038 */ bool received; +}; +#pragma pack(pop) + +// VTABLE: vt_00500 +class RuneSetData : public RuneData { +public: + /* 0050 */ std::vector m_slots; + /* 005C */ std::vector m_descriptions[6]; + /* 00A4 */ int unknown_00A4; + /* 00A8 */ int m_gradeList[15]; + /* 00E4 */ int m_grade; + /* 00E8 */ int m_gradeLevel; + /* 00EC */ int m_gradeType; + /* 00F0 */ int m_gradeFailType; + /* 00F4 */ int m_rewardStep; + /* 00F8 */ RuneSetReward m_reward; + + RuneSetData() : m_grade(0), m_gradeLevel(0), m_gradeType(0), m_gradeFailType(0), m_rewardStep(0) { + this->m_kind = 0; + std::memset(this->m_gradeList, 0, sizeof(this->m_gradeList)); + std::memset(&this->m_reward, 0, sizeof(this->m_reward)); + } + + ~RuneSetData() override { + } + + int FindLastReward(int count) const; + int CountSlots() const; + int CountActiveSlots() const; + int GetGradeValue() const; + bool IsRewardStep(int step) const; +}; + +// VTABLE: vt_00502 +class CTagData { +public: + /* 0004 */ int m_id; + /* 0008 */ std::string m_name; + /* 0020 */ bool m_locked; + /* 0024 */ int m_activeCount[2]; + /* 002C */ std::vector m_runes[2]; + + CTagData(int id, std::string name) { + this->m_id = id; + this->m_name = name; + this->m_locked = false; + this->m_activeCount[1] = 0; + this->m_activeCount[0] = 0; + } + + virtual ~CTagData() { + for (int type = 0; type < 2; ++type) { + for (RuneData* rune : this->m_runes[type]) { + if (rune) { + delete rune; + } + } + } + } + + void UpdateActiveCount(int type); + int GetRuneCount(int type) const; + RuneData* FindRune(int type, std::int64_t id, unsigned int* index); +}; + +// VTABLE: vt_00503 +class CRuneSystemMgr { +public: + static bool Create(); + static void Destroy(); + + /* 0004 */ std::pair m_emptyItem; + /* 000C */ bool m_initialized; + /* 000D */ bool m_requestPending; + /* 0010 */ int m_selectTag; + /* 0014 */ RuneSetData* m_curRuneSet; + /* 0018 */ int m_curSlotCount; + /* 001C */ std::vector m_tags; + /* 0028 */ std::map> m_gradeTypes; + /* 0030 */ std::map> m_gradeFailTypes; + /* 0038 */ std::map>> m_itemLists; + /* 0040 */ std::vector m_decomItems; + /* 004C */ std::map> m_decomTypes; + /* 0054 */ std::map> m_itemDecoms; + /* 005C */ std::vector m_ownedDecomItems; + + CRuneSystemMgr(); + + virtual ~CRuneSystemMgr(); + + void AddRune(int tagId, int type, std::int64_t id, const std::string& resName, int activeType); + int GetTagCount() const; + int GetOwnedDecomItemCount() const; + bool IsInitialized() const; + CTagData* GetTag(int tagId); + CTagData* GetTagByIndex(int index); + int GetDecomItem(unsigned int index) const; + int GetOwnedDecomItem(unsigned int index) const; + RuneSetData* GetCurRuneSet() const; + int GetCurSlotCount() const; + int GetGradeFailValue(RuneSetData* runeSet); + const std::pair& GetItemListEntry(int listId, unsigned int index); + int GetItemListCount(int listId); + RuneData* GetCurrentRune(int type, int index); + int GetGradeValue(RuneSetData* runeSet); + RuneData* FindRune(int tagId, int type, std::int64_t id, unsigned int* index); + int GetSelectTag() const; + std::vector* GetDecomList(int itemId, int which); + bool IsRequestPending() const; + void Reset(); + void ClearCurRuneSet(); + void LoadDefaultTag(); + bool HasRequiredItems(int listId); + int SendRequest(int packetId, RuneData* rune, int value); + void SetCurSlotCount(const int& count); + void SetSelectTag(int tagId); + void SetRequestPending(bool pending); + int SetRuneGrade(int tagId, int type, std::int64_t id, int grade, int gradeLevel); + bool SetRewardStep(int tagId, std::int64_t id, int step); +}; + +extern CRuneSystemMgr* g_runeSystemMgr; + +int AddGradeType(lua_State* state); +int AddGradeTypeFail(lua_State* state); +int AddItemListTableType(lua_State* state); +int AddRuneData(lua_State* state); +int AddRuneSetReward(lua_State* state); +int AddRuneDescription(lua_State* state); +int AddRuneGradeList(lua_State* state); +int AddRuneSlotCollectionList(lua_State* state); +int AddTag(lua_State* state); +int AddDecomItemNum(lua_State* state); +int AddItemDecom(lua_State* state); +int AddItemDecomType(lua_State* state); +int SetRuneDisplayName(lua_State* state); +int SetRuneUpGradeTable(lua_State* state); +int SetRuneSystemInfo(lua_State* state); + +#if defined(_WIN32) && !defined(_WIN64) +static_assert(sizeof(Decom_ItemInfo) == 0x14); +static_assert(sizeof(RuneData) == 0x50); +static_assert(sizeof(RuneSetReward) == 0x39); +static_assert(sizeof(RuneSetData) == 0x138); +static_assert(sizeof(CTagData) == 0x44); +static_assert(sizeof(CRuneSystemMgr) == 0x68); +#endif + +#endif diff --git a/data/compile.json b/data/compile.json index 64dc97fa..3ff14e92 100644 --- a/data/compile.json +++ b/data/compile.json @@ -389,6 +389,7 @@ "Source/Contents/Items/ItemLink.cpp": 4, "Source/Contents/Items/ItemNaming.cpp": 4, "Source/Contents/Items/ItemResources.cpp": 4, + "Source/Contents/Items/RuneSystem.cpp": 4, "Source/Contents/Jobs/JobInheritance.cpp": 4, "Source/Contents/Jobs/JobNameInitialization.cpp": 4, "Source/Contents/Jobs/JobNames.cpp": 4,