From ee80f14d853a732f8b33deb034a143a34d8e4d0e Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Sun, 1 Nov 2026 14:12:45 +0000 Subject: [PATCH] Decompile fn_21581 (CGameMode::ReceiveSkillUpdate) Batch #9478 by meitogi: 0 byte-identical, 1 confirmed by peer review. - fn_21581 CGameMode::ReceiveSkillUpdate: logic confirmed by peer review Peer-reviewed-by: ragnarok-clanker, secret, Toshiro Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- Source/Client/Mode/CGameMode.h | 4 +++ Source/Client/Mode/GameMode.cpp | 44 +++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/Source/Client/Mode/CGameMode.h b/Source/Client/Mode/CGameMode.h index 2406749c..cdfb49d8 100644 --- a/Source/Client/Mode/CGameMode.h +++ b/Source/Client/Mode/CGameMode.h @@ -350,6 +350,10 @@ public: void OpenActorMenu(const ActorPickInfo* pick, int handled); int HandleActorPick(ActorPickInfo* pick, int result); void ReceiveSkillList(int packetType, const std::vector& skills); + void ShowActorNameBalloon(std::uint32_t id); + void ReceiveSkillUpdate( + std::uint16_t id, std::int16_t level, std::int16_t spCost, unsigned char upgradable, std::int16_t range, int type, std::int16_t unknown + ); std::uint32_t FindUnknown01AC(std::uint32_t key); std::string ActorName(std::uint32_t id); std::uint32_t ActorNameColor(int job, std::uint32_t aid); diff --git a/Source/Client/Mode/GameMode.cpp b/Source/Client/Mode/GameMode.cpp index caf8988f..2161cc96 100644 --- a/Source/Client/Mode/GameMode.cpp +++ b/Source/Client/Mode/GameMode.cpp @@ -3905,6 +3905,50 @@ void CGameMode::ReceiveSkillList(int packetType, const std::vectorRefreshPretend(); } +// OFFSET: 0x00D07250 +// FUNCTION: fn_21581 +void CGameMode::ReceiveSkillUpdate( + std::uint16_t id, std::int16_t level, std::int16_t spCost, unsigned char upgradable, std::int16_t range, int type, std::int16_t unknown +) { + *reinterpret_cast(&this->unknown_0100[0x0C]) = 0; + + ClientSkills client{ + g_session.m_skillBundle, + g_session.m_homunSkills, + g_session.m_mercSkills, + g_session.m_additionalSkills, + reinterpret_cast(g_session.m_jobFlags), + g_activeSkillEffects + }; + CSkillInfo skill = client.Lookup(id); + skill.level = level; + skill.unknown_0014 = spCost; + skill.unknown_0018 = upgradable; + skill.unknown_001C = range; + skill.unknown_000C = type; + skill.unknown_0030 = unknown; + skill.id = id; + + if (g_session.IsHomunculusSkill(id)) { + g_session.UpdateHomunSkill(skill, 1); + } else if (g_session.IsMercenarySkill(id)) { + g_session.UpdateMercSkill(skill, 1); + } else { + const SkillUseLevels levels{ + g_session.m_skillBundle.unknown_0064, *reinterpret_cast*>(g_session.unknown_0710), g_session.m_homunSkillLevels + }; + SkillWindows windows{g_windowMgr.window_02C4, g_windowMgr.window_01E8, *reinterpret_cast(&g_windowMgr)}; + client.Update(skill, 1, 1, *g_session.m_hotkeyScript, levels, windows); + } + + if (g_equipmentPropertiesMgr == nullptr) { + g_equipmentPropertiesMgr = new (std::nothrow) EquipmentProperties::CEquipmentPropertiesMgr; + } + g_equipmentPropertiesMgr->RefreshPretend(); +} + +// OFFSET: 0x00CDB910 + // OFFSET: 0x00CE2880 // OFFSET: 0x00CDD6B0