From a1105b5ec93e0ff4d0ee9d110d11ee8e4cdd2aee Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Thu, 29 Oct 2026 21:20:46 +0000 Subject: [PATCH] Decompile 13 functions in Source/Contents/Skills/SkillActionShinkiroShiranui.cpp, Source/Contents/Skills/SkillActionSkyEmperor.cpp, ... Batch #3312 by youko: 0 byte-identical, 13 confirmed by peer review. - fn_08785 CSkillAction_SS_REIKETSUHOU::Slot12: logic confirmed by peer review - fn_08788 CSkillAction_SS_RAIDENPOU::Slot08: logic confirmed by peer review - fn_08789 CSkillAction_SS_RAIDENPOU::Slot11: logic confirmed by peer review - fn_08790 CSkillAction_SS_RAIDENPOU::Slot16: logic confirmed by peer review - fn_08795 CSkillAction_SS_KINRYUUHOU::Slot16: logic confirmed by peer review - fn_08803 CSkillAction_SS_KAGEAKUMU::Slot15: logic confirmed by peer review - fn_08807 CSkillAction_SS_HITOUAKUMU::Slot11: logic confirmed by peer review - fn_08811 CSkillAction_SS_ANKOKURYUUAKUMU::Slot11: logic confirmed by peer review - fn_08812 CSkillAction_SS_ANKOKURYUUAKUMU::Slot15: logic confirmed by peer review - fn_08813 CSkillAction_SS_FOUR_CHARM::Slot11: logic confirmed by peer review - fn_08814 ??RShuffledSequence@?A0x3aba9267@@QBE?AV?$vector@HV?$allocator@H@std@@@std@@H@Z: logic confirmed by peer review - fn_08815 CSkillObjectAction_SKE_STAR_CANNON::Slot00: logic confirmed by peer review - fn_08820 CEfstAction_SKY_ENCHANT::Slot00: logic confirmed by peer review Peer-reviewed-by: eAthena, meitogi Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- .../Skills/SkillActionShinkiroShiranui.cpp | 121 ++++++++++++++++++ .../Contents/Skills/SkillActionSkyEmperor.cpp | 13 ++ 2 files changed, 134 insertions(+) diff --git a/Source/Contents/Skills/SkillActionShinkiroShiranui.cpp b/Source/Contents/Skills/SkillActionShinkiroShiranui.cpp index 7db863e5..a326028f 100644 --- a/Source/Contents/Skills/SkillActionShinkiroShiranui.cpp +++ b/Source/Contents/Skills/SkillActionShinkiroShiranui.cpp @@ -75,6 +75,21 @@ public: }; // OFFSET: 0x007950C0 +// FUNCTION: fn_08785 +void CSkillAction_SS_REIKETSUHOU::Slot12(vector3d position, int level, int argument3) { + g_effectMgr->Spawn(0, CEZ2STREffectMgr::GetInstance()->EffectId("reiketsuhou_bottom"), position.x, position.y, position.z, 0, -1, 0, 0); + + const int counts[] = {5, 5, 5, 5, 5, 6, 6, 6, 7, 7}; + const int count = counts[std::min(level, 10) - 1]; + for (int index = 0; index < count; ++index) { + vector3d spot = position; + spot.x += (std::max(0, std::rand() % (count * 50 + 1)) - count * 50 * 0.5f) * 0.1f; + spot.z += (std::max(0, std::rand() % (count * 50 + 1)) - count * 50 * 0.5f) * 0.1f; + if (CEffect* effect = g_effectMgr->Spawn(0, CEZ2STREffectMgr::GetInstance()->EffectId("reiketsuhou"), spot.x, spot.y, spot.z, 0, -1, 0, 0)) { + effect->Slot16(index * 80); + } + } +} // OFFSET: 0x00795450 // FUNCTION: fn_08786 @@ -89,10 +104,30 @@ int CSkillAction_SS_RAIDENPOU::Slot02() { } // OFFSET: 0x00795470 +// FUNCTION: fn_08788 +void CSkillAction_SS_RAIDENPOU::Slot08(int level, CGameActor* source) { + if (CEffect* effect = g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("new_raidenpou_cast"), + 0.0f, 0.0f, 0.0f, 0, -1, 0, 0)) { + effect->Slot14(level); + } +} // OFFSET: 0x007955F0 +// FUNCTION: fn_08789 +void CSkillAction_SS_RAIDENPOU::Slot11(int level, CGameActor* source, CGameActor* target) { + if (target) { + g_effectMgr->Spawn(target->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("new_raidenpou_bottom"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + g_effectMgr->Spawn(target->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("new_raidenpou"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + } +} // OFFSET: 0x00795860 +// FUNCTION: fn_08790 +void CSkillAction_SS_RAIDENPOU::Slot16(int level, CGameActor* source, CGameActor* target) { + if (source) { + g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("new_raidenpou_hit"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + } +} // OFFSET: 0x007959E0 // FUNCTION: fn_08791 @@ -107,6 +142,12 @@ int CSkillAction_SS_KINRYUUHOU::Slot02() { } // OFFSET: 0x00795BD0 +// FUNCTION: fn_08795 +void CSkillAction_SS_KINRYUUHOU::Slot16(int level, CGameActor* source, CGameActor* target) { + if (source) { + g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("kinryuuhou_hit"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + } +} // OFFSET: 0x00795D40 // FUNCTION: fn_08796 @@ -133,6 +174,12 @@ int CSkillAction_SS_KAGEAKUMU::Slot02() { } // OFFSET: 0x00795F60 +// FUNCTION: fn_08803 +void CSkillAction_SS_KAGEAKUMU::Slot15(int level, CGameActor* source, CGameActor* target) { + if (source) { + g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("kageakumu"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + } +} // OFFSET: 0x007960C0 // FUNCTION: fn_08804 @@ -147,6 +194,31 @@ int CSkillAction_SS_HITOUAKUMU::Slot02() { } // OFFSET: 0x00796140 +// FUNCTION: fn_08807 +void CSkillAction_SS_HITOUAKUMU::Slot11(int level, CGameActor* source, CGameActor* target) { + if (!source) { + return; + } + + g_effectMgr->Spawn(0, CEZ2STREffectMgr::GetInstance()->EffectId("hitouakumu"), source->render.position.x, source->render.position.y, + source->render.position.z, 0, -1, 0, 0); + + ShuffledSequence shuffle; + for (int ring = 0; ring < 3; ++ring) { + const int count = std::max(0, std::rand() % 5) + 15; + const float step = 360.0f / count; + const std::vector order = shuffle(count); + for (int index = 0; index < count; ++index) { + CEffect* effect = g_effectMgr->Spawn(0, CEZ2STREffectMgr::GetInstance()->EffectId(FormatOwnedString("hitouakumu_%02d", ring)), source->render.position.x, + source->render.position.y, source->render.position.z, 0, -1, 0, 0); + if (effect) { + const int spread = static_cast(step); + effect->Slot17(index * step + (spread ? std::max(0, std::rand() % spread) : 0)); + effect->Slot16((order[index] + ring * 10) * 32); + } + } + } +} // OFFSET: 0x00796490 // FUNCTION: fn_08808 @@ -161,9 +233,58 @@ int CSkillAction_SS_ANKOKURYUUAKUMU::Slot02() { } // OFFSET: 0x00796510 +// FUNCTION: fn_08811 +void CSkillAction_SS_ANKOKURYUUAKUMU::Slot11(int level, CGameActor* source, CGameActor* target) { + if (source) { + g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("ankokuryuuakumu_00"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + } +} // OFFSET: 0x00796690 +// FUNCTION: fn_08812 +void CSkillAction_SS_ANKOKURYUUAKUMU::Slot15(int level, CGameActor* source, CGameActor* target) { + if (source) { + g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("ankokuryuuakumu_01"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + } +} // OFFSET: 0x00796810 +// FUNCTION: fn_08813 +void CSkillAction_SS_FOUR_CHARM::Slot11(int level, CGameActor* source, CGameActor* target) { + if (!source) { + return; + } + + switch (source->charmType) { + case 1: + g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("four_charm_ice_bottom"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("four_charm_ice"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + break; + case 2: + g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("four_charm_earth_bottom"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("four_charm_earth"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + break; + case 3: + g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("four_charm_fire_bottom"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("four_charm_fire"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + break; + case 4: + g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("four_charm_wind_bottom"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + g_effectMgr->Spawn(source->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("four_charm_wind"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + break; + } +} // OFFSET: 0x00796EF0 +// FUNCTION: fn_08814 +std::vector ShuffledSequence::operator()(int count) const { + std::vector sequence; + for (int index = 0; index < count; ++index) { + sequence.push_back(index); + } + + std::random_device device; + std::mt19937 engine(device()); + std::shuffle(sequence.begin(), sequence.end(), engine); + return sequence; +} diff --git a/Source/Contents/Skills/SkillActionSkyEmperor.cpp b/Source/Contents/Skills/SkillActionSkyEmperor.cpp index bc839755..7a24a3a1 100644 --- a/Source/Contents/Skills/SkillActionSkyEmperor.cpp +++ b/Source/Contents/Skills/SkillActionSkyEmperor.cpp @@ -120,6 +120,12 @@ public: }; // OFFSET: 0x007975A0 +// FUNCTION: fn_08815 +void CSkillObjectAction_SKE_STAR_CANNON::Slot00(int argument, CRenderObject* object, CGameActor* source) { + if (object) { + g_effectMgr->Spawn(object->render.accountId, 2350, object->render.position.x, object->render.position.y, object->render.position.z, 0, argument, 0, 0); + } +} // OFFSET: 0x007975F0 // FUNCTION: fn_08816 @@ -128,6 +134,13 @@ int CSkillAction_SKE_ALL_IN_THE_SKY::Slot02() { } // OFFSET: 0x007977E0 +// FUNCTION: fn_08820 +void CEfstAction_SKY_ENCHANT::Slot00(int efstId, int value, int argument3, int argument4, CRenderObject* actor, bool argument6) { + if (actor) { + g_effectMgr->Spawn(actor->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("ske_enchanting_sky_00"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + g_effectMgr->Spawn(actor->render.accountId, CEZ2STREffectMgr::GetInstance()->EffectId("ske_enchanting_sky_01"), 0.0f, 0.0f, 0.0f, 0, -1, 0, 0); + } +} // OFFSET: 0x00797A70