From b51e87ee7d53daf2b2f904b2dd200ede4aef3571 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Fri, 30 Oct 2026 02:59:20 +0000 Subject: [PATCH] Decompile 46 functions in Source/Contents/Skills/SkillActionDruid.cpp, Source/Contents/Items/SelectPackageItemMgr.cpp, ... Batch #4416 by youko: 17 byte-identical, 29 confirmed by peer review. - fn_04427 utility::FillRandomBytes: logic confirmed by peer review - fn_04439 CSelectPackageItemMgr::CSelectPackageItemMgr: logic confirmed by peer review - fn_04445 CSelectPackageItemMgr::AddTab: logic confirmed by peer review - fn_04446 CSelectPackageItemMgr::FindItems: logic confirmed by peer review - fn_04454 Singleton::GetInstance: logic confirmed by peer review - fn_04456 CSelectPackageItemMgr::LuaAddTab: logic confirmed by peer review - fn_04458 CSkillAction_DR_WERERAPTOR::Slot02: byte-identical - fn_04459 CSkillAction_DR_WERERAPTOR::Slot11: logic confirmed by peer review - fn_04460 CEfstAction_WERERAPTOR::Slot03: logic confirmed by peer review - fn_04461 CEfstAction_WERERAPTOR::Slot04: logic confirmed by peer review - fn_04463 CSkillAction_DR_ENRAGE_WOLF::Slot01: byte-identical - fn_04464 CSkillAction_DR_ENRAGE_WOLF::Slot02: byte-identical - fn_04465 CSkillAction_DR_ENRAGE_WOLF::Slot08: logic confirmed by peer review - fn_04467 CEfstAction_ENRAGE_WOLF::Slot03: logic confirmed by peer review - fn_04468 CEfstAction_ENRAGE_WOLF::Slot04: logic confirmed by peer review - fn_04469 CSkillAction_DR_BLOOD_HOWLING::Slot01: byte-identical - fn_04470 CSkillAction_DR_BLOOD_HOWLING::Slot02: byte-identical - fn_04471 CSkillAction_DR_BLOOD_HOWLING::Slot08: logic confirmed by peer review - fn_04473 CEfstAction_BLOOD_HOWLING::Slot03: logic confirmed by peer review - fn_04474 CEfstAction_BLOOD_HOWLING::Slot04: logic confirmed by peer review - fn_04475 CSkillAction_DR_NOMERCY_CLAW::Slot02: byte-identical - fn_04477 CSkillAction_DR_HUNGER::Slot02: byte-identical - fn_04478 CSkillAction_DR_HUNGER::Slot11: logic confirmed by peer review - fn_04479 CSkillAction_DR_HUNGER::Slot15: logic confirmed by peer review - fn_04480 CSkillAction_DR_CRUEL_BITE::Slot02: byte-identical - fn_04482 CSkillAction_DR_ENRAGE_RAPTOR::Slot01: byte-identical - fn_04483 CSkillAction_DR_ENRAGE_RAPTOR::Slot02: byte-identical - fn_04484 CSkillAction_DR_ENRAGE_RAPTOR::Slot08: logic confirmed by peer review - fn_04486 CEfstAction_ENRAGE_RAPTOR::Slot03: logic confirmed by peer review - fn_04487 CEfstAction_ENRAGE_RAPTOR::Slot04: logic confirmed by peer review - fn_04488 CSkillAction_DR_PREENING::Slot01: byte-identical - fn_04489 CSkillAction_DR_PREENING::Slot02: byte-identical - fn_04490 CSkillAction_DR_PREENING::Slot08: logic confirmed by peer review - fn_04492 CEfstAction_PREENING::Slot03: logic confirmed by peer review - fn_04493 CEfstAction_PREENING::Slot04: logic confirmed by peer review - fn_04494 CSkillAction_DR_SHOOTING_FEATHER::Slot02: byte-identical - fn_04497 CSkillAction_DR_FLICKING_TONADO::Slot02: byte-identical - fn_04498 CSkillAction_DR_FLICKING_TONADO::Slot11: logic confirmed by peer review - fn_04499 CSkillAction_DR_LOW_FLIGHT::Slot02: byte-identical - fn_04501 CSkillAction_DR_NATURE_SHIELD::Slot01: byte-identical - fn_04502 CSkillAction_DR_NATURE_SHIELD::Slot02: byte-identical - fn_04503 CSkillAction_DR_NATURE_SHIELD::Slot08: logic confirmed by peer review - fn_04504 CSkillAction_DR_NATURE_SHIELD::Slot11: logic confirmed by peer review - fn_04505 CEfstAction_NATURE_SHIELD::Slot03: logic confirmed by peer review - fn_04506 CEfstAction_NATURE_SHIELD::Slot04: logic confirmed by peer review - fn_04507 CEfstAction_GROUND_GROW::Slot01: logic confirmed by peer review Peer-reviewed-by: eAthena, willerthal, KWDev 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/Skills/SkillActionDruid.cpp, Source/Contents/Items/SelectPackageItemMgr.cpp, Source/Utility/Random/RandomBytes.cpp --- .../Contents/Items/SelectPackageItemMgr.cpp | 91 ++++ Source/Contents/Items/SelectPackageItemMgr.h | 38 ++ Source/Contents/Skills/SkillActionDruid.cpp | 485 ++++++++++++++++++ Source/Utility/Random/RandomBytes.cpp | 15 + Source/Utility/Random/RandomBytes.h | 13 + data/compile.json | 3 + 6 files changed, 645 insertions(+) create mode 100644 Source/Contents/Items/SelectPackageItemMgr.cpp create mode 100644 Source/Contents/Items/SelectPackageItemMgr.h create mode 100644 Source/Contents/Skills/SkillActionDruid.cpp create mode 100644 Source/Utility/Random/RandomBytes.cpp create mode 100644 Source/Utility/Random/RandomBytes.h diff --git a/Source/Contents/Items/SelectPackageItemMgr.cpp b/Source/Contents/Items/SelectPackageItemMgr.cpp new file mode 100644 index 00000000..986412ce --- /dev/null +++ b/Source/Contents/Items/SelectPackageItemMgr.cpp @@ -0,0 +1,91 @@ +#include "Contents/Items/SelectPackageItemMgr.h" +#include "Network/TextEncoding.h" + +extern "C" { +#include +} +#include + +// GLOBAL: gl_24790 +template <> +CSelectPackageItemMgr* Singleton::s_instance = nullptr; + +// OFFSET: 0x0061E280 +// FUNCTION: fn_04439 +CSelectPackageItemMgr::CSelectPackageItemMgr() { +} + +// OFFSET: 0x0061EC30 +// FUNCTION: fn_04445 +void CSelectPackageItemMgr::AddTab(int packageId, int tabIndex, const std::string& name, int itemCount) { + if (this->m_packages.find(packageId) == this->m_packages.end()) { + this->m_packages[packageId] = std::map(); + } + + if (this->m_packages[packageId].find(tabIndex) == this->m_packages[packageId].end()) { + this->m_packages[packageId][tabIndex] = SelectPackageTab(); + } + + this->m_packages[packageId][tabIndex].name = name; + this->m_packages[packageId][tabIndex].items.resize(itemCount); +} + +// OFFSET: 0x0061EF60 +// FUNCTION: fn_04446 +std::optional*> CSelectPackageItemMgr::FindItems(int packageId, int tabIndex) { + std::map>::iterator package = this->m_packages.find(packageId); + if (package != this->m_packages.end()) { + std::map::iterator tab = package->second.find(tabIndex); + if (tab != package->second.end()) { + return &tab->second.items; + } + } + + return std::nullopt; +} + +// OFFSET: 0x0061F9A0 +// FUNCTION: fn_04454 +template <> +CSelectPackageItemMgr* Singleton::GetInstance() { + if (!s_instance) { + s_instance = new (std::nothrow) CSelectPackageItemMgr; + } + + return s_instance; +} + +// OFFSET: 0x0061FD90 +// FUNCTION: fn_04456 +int CSelectPackageItemMgr::LuaAddTab(lua_State* L) { + if (!lua_isnumber(L, -4)) { + lua_pushboolean(L, 0); + lua_pushstring(L, "L_AddTab : 1st argument must be number"); + return 2; + } + if (!lua_isnumber(L, -3)) { + lua_pushboolean(L, 0); + lua_pushstring(L, "L_AddTab : 2nd argument must be number"); + return 2; + } + if (!lua_isstring(L, -2)) { + lua_pushboolean(L, 0); + lua_pushstring(L, "L_AddTab : 3rd argument must be string"); + return 2; + } + if (!lua_isnumber(L, -1)) { + lua_pushboolean(L, 0); + lua_pushstring(L, "L_AddTab : 4th argument must be number"); + return 2; + } + + int packageId = static_cast(lua_tonumber(L, -4)); + int tabIndex = static_cast(lua_tonumber(L, -3)); + std::string name = FromUtf8(lua_tostring(L, -2), g_textCodePage); + int itemCount = static_cast(lua_tonumber(L, -1)); + CSelectPackageItemMgr::GetInstance()->AddTab(packageId, tabIndex, name, itemCount); + + lua_pushboolean(L, 1); + lua_pushstring(L, "good"); + return 2; +} diff --git a/Source/Contents/Items/SelectPackageItemMgr.h b/Source/Contents/Items/SelectPackageItemMgr.h new file mode 100644 index 00000000..a7476120 --- /dev/null +++ b/Source/Contents/Items/SelectPackageItemMgr.h @@ -0,0 +1,38 @@ +#ifndef RAGNAROK_SOURCE_CONTENTS_ITEMS_SELECTPACKAGEITEMMGR_H +#define RAGNAROK_SOURCE_CONTENTS_ITEMS_SELECTPACKAGEITEMMGR_H + +#include "Contents/Items/ItemInfo.h" +#include "Utility/Singleton.h" + +#include +#include +#include +#include +#include + +struct lua_State; + +struct SelectPackageTab { + /* 0000 */ std::string name; + /* 0018 */ std::vector items; +}; + +class CSelectPackageItemMgr : public Singleton { +public: + static int LuaAddTab(lua_State* L); + + /* 0004 */ std::map> m_packages; + + CSelectPackageItemMgr(); + + void AddTab(int packageId, int tabIndex, const std::string& name, int itemCount); + std::optional*> FindItems(int packageId, int tabIndex); +}; + +#if defined(_WIN32) && !defined(_WIN64) +static_assert(sizeof(SelectPackageTab) == 0x24); +static_assert(offsetof(SelectPackageTab, items) == 0x18); +static_assert(sizeof(CSelectPackageItemMgr) == 0xC); +#endif + +#endif diff --git a/Source/Contents/Skills/SkillActionDruid.cpp b/Source/Contents/Skills/SkillActionDruid.cpp new file mode 100644 index 00000000..eda7fe27 --- /dev/null +++ b/Source/Contents/Skills/SkillActionDruid.cpp @@ -0,0 +1,485 @@ +#include "Contents/Actors/GameActor.h" +#include "Contents/Actors/Pc.h" +#include "Contents/EffectResourceSwitcher.h" +#include "Contents/Effects/Effect.h" +#include "Contents/Effects/EffectActor.h" +#include "Contents/Effects/EffectLists.h" +#include "Contents/Effects/RagEffect.h" +#include "Contents/MessageTable.h" +#include "Contents/Skills/SkillInfo.h" +#include "Utility/Cipher/XorBytes.h" +#include "Utility/Math/Vector3d.h" + +#include +#include +#include + +namespace { + +template +class EncryptedName { +public: + explicit EncryptedName(const std::uint8_t (&source)[Length]) : m_encrypted(true) { + for (std::uint64_t index = 0; index < Length; ++index) { + this->m_text[index] = source[index]; + } + } + + ~EncryptedName() { + for (std::uint64_t index = 0; index < Length; ++index) { + this->m_text[index] = 0; + } + } + + const char* Text() { + if (this->m_encrypted) { + utility::XorBytes(this->m_text, Length, Key); + this->m_encrypted = false; + } + + return reinterpret_cast(this->m_text); + } + +private: + std::uint8_t m_text[Length]; + bool m_encrypted; +}; + +} + +class CSkillAction_AnimalForm : public CSkillAction { +public: + virtual bool Slot17(CGameActor* actor) = 0; + virtual void Slot18(CGameActor* actor) = 0; +}; + +class CSkillAction_Direction { +public: + int GetDirection(float angle); + bool IsValidDirection(unsigned int direction); +}; + +class CSkillAction_DamageWereRaptorForm : public CSkillAction_AnimalForm, public CSkillAction_Direction { +public: + void Slot16(int level, CGameActor* source, CGameActor* target) override; + bool Slot17(CGameActor* actor) override; + void Slot18(CGameActor* actor) override; +}; + +class CSkillAction_DamageWereWolfForm : public CSkillAction_AnimalForm { +public: + void Slot16(int level, CGameActor* source, CGameActor* target) override; + bool Slot17(CGameActor* actor) override; + void Slot18(CGameActor* actor) override; +}; + +class CEfstAction_BasicAction : public CEfstAction { +public: + void Slot00(int efstId, int value, int argument3, int argument4, CRenderObject* actor, bool argument6) override; + void Slot01(int efstId, int argument2, int argument3, int argument4, CRenderObject* actor) override; + void Slot02(int efstId, int value, int argument3, int argument4, CRenderObject* actor) override; + virtual int Slot05(int efstId, int argument4) = 0; +}; + +class CSkillAction_DR_WERERAPTOR : public CSkillAction_DamageWereRaptorForm { +public: + int Slot02() override; + void Slot11(int level, CGameActor* source, CGameActor* target) override; +}; + +class CEfstAction_WERERAPTOR : public CEfstAction { +public: + EfstActionMessage Slot03() override; + EfstActionMessage Slot04() override; +}; + +class CSkillAction_DR_ENRAGE_WOLF : public CSkillAction_DamageWereWolfForm { +public: + int Slot01() override; + int Slot02() override; + void Slot08(int level, CGameActor* source) override; +}; + +class CEfstAction_ENRAGE_WOLF : public CEfstAction { +public: + EfstActionMessage Slot03() override; + EfstActionMessage Slot04() override; +}; + +class CSkillAction_DR_BLOOD_HOWLING : public CSkillAction_DamageWereWolfForm { +public: + int Slot01() override; + int Slot02() override; + void Slot08(int level, CGameActor* source) override; +}; + +class CEfstAction_BLOOD_HOWLING : public CEfstAction { +public: + EfstActionMessage Slot03() override; + EfstActionMessage Slot04() override; +}; + +class CSkillAction_DR_NOMERCY_CLAW : public CSkillAction_DamageWereWolfForm { +public: + int Slot02() override; +}; + +class CSkillAction_DR_HUNGER : public CSkillAction_DamageWereWolfForm { +public: + int Slot02() override; + void Slot11(int level, CGameActor* source, CGameActor* target) override; + void Slot15(int caster, CGameActor* target, CGameActor* argument3) override; +}; + +class CSkillAction_DR_CRUEL_BITE : public CSkillAction_DamageWereWolfForm { +public: + int Slot02() override; +}; + +class CSkillAction_DR_ENRAGE_RAPTOR : public CSkillAction_DamageWereRaptorForm { +public: + int Slot01() override; + int Slot02() override; + void Slot08(int level, CGameActor* source) override; +}; + +class CEfstAction_ENRAGE_RAPTOR : public CEfstAction { +public: + EfstActionMessage Slot03() override; + EfstActionMessage Slot04() override; +}; + +class CSkillAction_DR_PREENING : public CSkillAction_DamageWereRaptorForm { +public: + int Slot01() override; + int Slot02() override; + void Slot08(int level, CGameActor* source) override; +}; + +class CEfstAction_PREENING : public CEfstAction { +public: + EfstActionMessage Slot03() override; + EfstActionMessage Slot04() override; +}; + +class CSkillAction_DR_SHOOTING_FEATHER : public CSkillAction_DamageWereRaptorForm { +public: + int Slot02() override; +}; + +class CSkillAction_DR_FLICKING_TONADO : public CSkillAction_DamageWereRaptorForm { +public: + int Slot02() override; + void Slot11(int level, CGameActor* source, CGameActor* target) override; +}; + +class CSkillAction_DR_LOW_FLIGHT : public CSkillAction_DamageWereRaptorForm { +public: + int Slot02() override; +}; + +class CSkillAction_DR_NATURE_SHIELD : public CSkillAction { +public: + int Slot01() override; + int Slot02() override; + void Slot08(int level, CGameActor* source) override; + void Slot11(int level, CGameActor* source, CGameActor* target) override; +}; + +class CEfstAction_NATURE_SHIELD : public CEfstAction { +public: + EfstActionMessage Slot03() override; + EfstActionMessage Slot04() override; +}; + +class CEfstAction_GROUND_GROW : public CEfstAction_BasicAction { +public: + void Slot01(int efstId, int argument2, int argument3, int argument4, CRenderObject* actor) override; +}; + +// OFFSET: 0x0061FF70 +// FUNCTION: fn_04458 +int CSkillAction_DR_WERERAPTOR::Slot02() { + return 64; +} + +// OFFSET: 0x0061FF80 +// FUNCTION: fn_04459 +void CSkillAction_DR_WERERAPTOR::Slot11(int level, CGameActor* source, CGameActor* target) { + if (!source) { + return; + } + if (this->Slot17(source) == true) { + return; + } + + const std::uint8_t effectSource[] = {0x7E, 0xCC, 0x35, 0x3A, 0xAB, 0x3C, 0x05, 0xA7, 0x66, 0xDB, 0x47}; + thread_local EncryptedName effectName(effectSource); + g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId(effectName.Text()), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); +} + +// OFFSET: 0x00620190 +// FUNCTION: fn_04460 +EfstActionMessage CEfstAction_WERERAPTOR::Slot03() { + return {LookupMessage(4648), 0xFFFF00}; +} + +// OFFSET: 0x006201C0 +// FUNCTION: fn_04461 +EfstActionMessage CEfstAction_WERERAPTOR::Slot04() { + return {LookupMessage(4649), 0xFF}; +} + +// OFFSET: 0x00620220 +// FUNCTION: fn_04463 +int CSkillAction_DR_ENRAGE_WOLF::Slot01() { + return 66; +} + +// OFFSET: 0x00620230 +// FUNCTION: fn_04464 +int CSkillAction_DR_ENRAGE_WOLF::Slot02() { + return 68; +} + +// OFFSET: 0x00620240 +// FUNCTION: fn_04465 +void CSkillAction_DR_ENRAGE_WOLF::Slot08(int level, CGameActor* source) { + if (source) { + source->LaunchEffect(54, level / 16); + } +} + +// OFFSET: 0x00620480 +// FUNCTION: fn_04467 +EfstActionMessage CEfstAction_ENRAGE_WOLF::Slot03() { + return {LookupMessage(4644), 0xFFFF00}; +} + +// OFFSET: 0x006204B0 +// FUNCTION: fn_04468 +EfstActionMessage CEfstAction_ENRAGE_WOLF::Slot04() { + return {LookupMessage(4645), 0xFF}; +} + +// OFFSET: 0x006204E0 +// FUNCTION: fn_04469 +int CSkillAction_DR_BLOOD_HOWLING::Slot01() { + return 66; +} + +// OFFSET: 0x006204F0 +// FUNCTION: fn_04470 +int CSkillAction_DR_BLOOD_HOWLING::Slot02() { + return 68; +} + +// OFFSET: 0x00620500 +// FUNCTION: fn_04471 +void CSkillAction_DR_BLOOD_HOWLING::Slot08(int level, CGameActor* source) { + if (source) { + source->LaunchEffect(54, level / 16); + } +} + +// OFFSET: 0x00620740 +// FUNCTION: fn_04473 +EfstActionMessage CEfstAction_BLOOD_HOWLING::Slot03() { + return {LookupMessage(4646), 0xFFFF00}; +} + +// OFFSET: 0x00620770 +// FUNCTION: fn_04474 +EfstActionMessage CEfstAction_BLOOD_HOWLING::Slot04() { + return {LookupMessage(4647), 0xFF}; +} + +// OFFSET: 0x006207A0 +// FUNCTION: fn_04475 +int CSkillAction_DR_NOMERCY_CLAW::Slot02() { + return 69; +} + +// OFFSET: 0x006209C0 +// FUNCTION: fn_04477 +int CSkillAction_DR_HUNGER::Slot02() { + return 70; +} + +// OFFSET: 0x006209D0 +// FUNCTION: fn_04478 +void CSkillAction_DR_HUNGER::Slot11(int level, CGameActor* source, CGameActor* target) { + if (!target) { + return; + } + + const std::uint8_t effectSource[] = {0x3D, 0x88, 0xDB, 0xBC, 0xA2, 0xC3, 0x2A, 0x47, 0x34, 0x8F, 0xD2, 0xBE, 0xB3, 0xB1}; + thread_local EncryptedName effectName(effectSource); + g_effectMgr->Spawn(target->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId(effectName.Text()), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); +} + +// OFFSET: 0x00620BE0 +// FUNCTION: fn_04479 +void CSkillAction_DR_HUNGER::Slot15(int caster, CGameActor* target, CGameActor* argument3) { + CGameActor* source = reinterpret_cast(caster); + if (!source) { + return; + } + + const std::uint8_t effectSource[] = {0x77, 0x44, 0xA3, 0x80, 0x88, 0x07, 0x6D}; + thread_local EncryptedName effectName(effectSource); + g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId(effectName.Text()), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); +} + +// OFFSET: 0x00620DE0 +// FUNCTION: fn_04480 +int CSkillAction_DR_CRUEL_BITE::Slot02() { + return 73; +} + +// OFFSET: 0x00621060 +// FUNCTION: fn_04482 +int CSkillAction_DR_ENRAGE_RAPTOR::Slot01() { + return 66; +} + +// OFFSET: 0x00621070 +// FUNCTION: fn_04483 +int CSkillAction_DR_ENRAGE_RAPTOR::Slot02() { + return 68; +} + +// OFFSET: 0x00621080 +// FUNCTION: fn_04484 +void CSkillAction_DR_ENRAGE_RAPTOR::Slot08(int level, CGameActor* source) { + if (source) { + source->LaunchEffect(56, level / 16); + } +} + +// OFFSET: 0x006212C0 +// FUNCTION: fn_04486 +EfstActionMessage CEfstAction_ENRAGE_RAPTOR::Slot03() { + return {LookupMessage(4650), 0xFFFF00}; +} + +// OFFSET: 0x006212F0 +// FUNCTION: fn_04487 +EfstActionMessage CEfstAction_ENRAGE_RAPTOR::Slot04() { + return {LookupMessage(4651), 0xFF}; +} + +// OFFSET: 0x00621320 +// FUNCTION: fn_04488 +int CSkillAction_DR_PREENING::Slot01() { + return 66; +} + +// OFFSET: 0x00621330 +// FUNCTION: fn_04489 +int CSkillAction_DR_PREENING::Slot02() { + return 68; +} + +// OFFSET: 0x00621340 +// FUNCTION: fn_04490 +void CSkillAction_DR_PREENING::Slot08(int level, CGameActor* source) { + if (source) { + source->LaunchEffect(56, level / 16); + } +} + +// OFFSET: 0x00621570 +// FUNCTION: fn_04492 +EfstActionMessage CEfstAction_PREENING::Slot03() { + return {LookupMessage(4652), 0xFFFF00}; +} + +// OFFSET: 0x006215A0 +// FUNCTION: fn_04493 +EfstActionMessage CEfstAction_PREENING::Slot04() { + return {LookupMessage(4653), 0xFF}; +} + +// OFFSET: 0x006215D0 +// FUNCTION: fn_04494 +int CSkillAction_DR_SHOOTING_FEATHER::Slot02() { + return 72; +} + +// OFFSET: 0x00621850 +// FUNCTION: fn_04497 +int CSkillAction_DR_FLICKING_TONADO::Slot02() { + return 67; +} + +// OFFSET: 0x00621860 +// FUNCTION: fn_04498 +void CSkillAction_DR_FLICKING_TONADO::Slot11(int level, CGameActor* source, CGameActor* target) { + if (!target) { + return; + } + + const std::uint8_t effectSource[] = {0x41, 0x6D, 0x6E, 0x0E, 0x68, 0xAC, 0x9D, 0x48, 0x78, 0x75, 0x68, 0x03, 0x62, 0xA1, 0x9C, 0x2F}; + thread_local EncryptedName effectName(effectSource); + g_effectMgr->Spawn(target->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId(effectName.Text()), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + + const std::uint8_t bottomSource[] = {0xD5, 0x0B, 0xAA, 0x30, 0x92, 0xF2, 0x5B, 0x70, 0xEC, 0x13, 0xAC, 0x3D, 0x98, 0xFF, 0x5A, 0x48, + 0xD1, 0x08, 0xB7, 0x27, 0x96, 0xF6, 0x35}; + thread_local EncryptedName bottomName(bottomSource); + g_effectMgr->Spawn(target->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId(bottomName.Text()), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); +} + +// OFFSET: 0x00621C00 +// FUNCTION: fn_04499 +int CSkillAction_DR_LOW_FLIGHT::Slot02() { + return 70; +} + +// OFFSET: 0x006221F0 +// FUNCTION: fn_04501 +int CSkillAction_DR_NATURE_SHIELD::Slot01() { + return 61; +} + +// OFFSET: 0x00622200 +// FUNCTION: fn_04502 +int CSkillAction_DR_NATURE_SHIELD::Slot02() { + return 65; +} + +// OFFSET: 0x00622210 +// FUNCTION: fn_04503 +void CSkillAction_DR_NATURE_SHIELD::Slot08(int level, CGameActor* source) { + if (source) { + source->LaunchEffect(12, level / 16); + } +} + +// OFFSET: 0x00622240 +// FUNCTION: fn_04504 +void CSkillAction_DR_NATURE_SHIELD::Slot11(int level, CGameActor* source, CGameActor* target) { + const std::uint8_t effectSource[] = {0xA9, 0xAC, 0x91, 0x48, 0x6D, 0x18, 0x3A, 0x86, 0xAF, 0xA4, 0x80, 0x51, 0x7B, 0x7D}; + thread_local EncryptedName effectName(effectSource); + g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId(effectName.Text()), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); +} + +// OFFSET: 0x00622440 +// FUNCTION: fn_04505 +EfstActionMessage CEfstAction_NATURE_SHIELD::Slot03() { + return {LookupMessage(4660), 0xFFFF00}; +} + +// OFFSET: 0x00622470 +// FUNCTION: fn_04506 +EfstActionMessage CEfstAction_NATURE_SHIELD::Slot04() { + return {LookupMessage(4661), 0xFF}; +} + +// OFFSET: 0x006224A0 +// FUNCTION: fn_04507 +void CEfstAction_GROUND_GROW::Slot01(int efstId, int argument2, int argument3, int argument4, CRenderObject* actor) { + for (int index = 0; index < 12; ++index) { + g_effectMgr->Retire(actor->render.accountId, this->Slot05(efstId, index + 1)); + } +} diff --git a/Source/Utility/Random/RandomBytes.cpp b/Source/Utility/Random/RandomBytes.cpp new file mode 100644 index 00000000..3b33c209 --- /dev/null +++ b/Source/Utility/Random/RandomBytes.cpp @@ -0,0 +1,15 @@ +#include "Utility/Random/RandomBytes.h" + +#include + +namespace utility { + // OFFSET: 0x0061CBE0 + // FUNCTION: fn_04427 + void FillRandomBytes(std::span bytes, unsigned int seed) { + std::mt19937 engine(seed); + std::uniform_int_distribution distribution(0, 255); + for (std::uint8_t& byte : bytes) { + byte = static_cast(distribution(engine)); + } + } +} diff --git a/Source/Utility/Random/RandomBytes.h b/Source/Utility/Random/RandomBytes.h new file mode 100644 index 00000000..9e829076 --- /dev/null +++ b/Source/Utility/Random/RandomBytes.h @@ -0,0 +1,13 @@ +#ifndef RAGNAROK_SOURCE_UTILITY_RANDOM_RANDOMBYTES_H +#define RAGNAROK_SOURCE_UTILITY_RANDOM_RANDOMBYTES_H + +#include +#include + +namespace utility { + + void FillRandomBytes(std::span bytes, unsigned int seed); + +} + +#endif diff --git a/data/compile.json b/data/compile.json index a17f69d3..2b080486 100644 --- a/data/compile.json +++ b/data/compile.json @@ -459,6 +459,7 @@ "Source/Contents/Items/ItemNaming.cpp": 4, "Source/Contents/Items/ItemResources.cpp": 4, "Source/Contents/Items/RuneSystem.cpp": 4, + "Source/Contents/Items/SelectPackageItemMgr.cpp": 4, "Source/Contents/Jobs/JobInheritance.cpp": 4, "Source/Contents/Jobs/JobNameInitialization.cpp": 4, "Source/Contents/Jobs/JobNames.cpp": 4, @@ -538,6 +539,7 @@ "Source/Contents/Skills/ClientSkills.cpp": 4, "Source/Contents/Skills/PlayerSkillBundle.cpp": 4, "Source/Contents/Skills/SkillActionAlitea.cpp": 4, + "Source/Contents/Skills/SkillActionDruid.cpp": 4, "Source/Contents/Skills/SkillActionImperialGuard.cpp": 4, "Source/Contents/Skills/SkillActionInfo.cpp": 4, "Source/Contents/Skills/SkillActionKarnos.cpp": 4, @@ -958,6 +960,7 @@ "Source/Utility/NFileLog.cpp": 0, "Source/Utility/NIPAddr.cpp": 0, "Source/Utility/ProcessSecurity.cpp": 0, + "Source/Utility/Random/RandomBytes.cpp": 0, "Source/Utility/RegistryKey.cpp": 0, "Source/Utility/SHA3.cpp": 0, "Source/Utility/Text/Base64.cpp": 0,