From 214e3ad79626890133aa5d33ee1858fa1e48ca64 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Wed, 28 Oct 2026 22:47:59 +0000 Subject: [PATCH] Decompile 4 functions in Source/UI/Buttons/UITextButton.cpp, Source/UI/UIStaticItem.h, ... Batch #1836 by ragnarok-clanker: 0 byte-identical, 4 confirmed by peer review. - fn_11448 UIBasicItemCtrl::Slot28: logic confirmed by peer review - fn_11449 UIBasicSkillCtrl::Slot28: logic confirmed by peer review - fn_11456 UIMemberListBox::Slot28: logic confirmed by peer review - fn_11458 UIStaticItem::Slot28: logic confirmed by peer review Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- Source/UI/Buttons/UITextButton.cpp | 142 +++++++++++++++++++++++++++++ Source/UI/Lists/UIMemberListBox.h | 22 +++++ Source/UI/UIBasicCtrl.h | 38 ++++++++ Source/UI/UIStaticItem.h | 11 +++ 4 files changed, 213 insertions(+) create mode 100644 Source/UI/Lists/UIMemberListBox.h create mode 100644 Source/UI/UIBasicCtrl.h diff --git a/Source/UI/Buttons/UITextButton.cpp b/Source/UI/Buttons/UITextButton.cpp index 934de5b..69f97e0 100644 --- a/Source/UI/Buttons/UITextButton.cpp +++ b/Source/UI/Buttons/UITextButton.cpp @@ -9,6 +9,14 @@ #include "UI/Lists/UITabControl.h" #include "UI/Lists/UITreeView.h" #include "UI/UIStaticItem.h" +#include "Client/Session.h" +#include "Contents/Hotkeys/HotkeyInfo.h" +#include "Contents/Items/ItemNaming.h" +#include "Contents/MessageTable.h" +#include "Contents/Skills/ClientSkills.h" +#include "UI/UIBasicCtrl.h" +#include "Utility/Text/FormatString.h" +#include "UI/Lists/UIMemberListBox.h" #include #include @@ -311,3 +319,137 @@ void UITabControl::Slot28(int x, int y) { this->m_controls->services.Tooltip(this->tooltips[index].c_str(), screenX, screenY, -1, false, true); } + +// OFFSET: 0x00822660 +// FUNCTION: fn_10280 +std::string SkillUseTextPercent(const char* name, int level, int sp, int ap) { + if (ap == 0) { + return FormatOwnedString("%s Use Lv %d (Sp : %d%%)", name, level, sp); + } + + return FormatOwnedString("%s Use Lv %d (Sp : %d%%, Ap : %d)", name, level, sp, ap); +} + +// OFFSET: 0x008226F0 +// FUNCTION: fn_10281 +std::string SkillUseTextFlat(const char* name, int level, int sp, int ap) { + if (ap == 0) { + return FormatOwnedString("%s Use Lv %d (Sp : %d)", name, level, sp); + } + + return FormatOwnedString("%s Use Lv %d (Sp : %d, Ap : %d)", name, level, sp, ap); +} + +// OFFSET: 0x00891350 +// FUNCTION: fn_11448 +void UIBasicItemCtrl::Slot28(int, int) { + std::string text; + + if (std::atoi(this->m_item.itemId.c_str()) < 1) { + text = this->m_tooltip; + } else if (this->m_item.unknown_0000[1] == 0) { + text = this->m_naming->DisplayName(this->m_item, 0); + } else if (this->m_item.unknown_0098 != 0) { + text = FormatOwnedString(LookupMessage(2551), this->m_naming->DisplayName(this->m_item, 0).c_str(), this->m_item.unknown_0098, this->m_item.quantity); + } else { + text = FormatOwnedString(LookupMessage(183), this->m_naming->DisplayName(this->m_item, 0).c_str(), this->m_item.quantity); + } + + int screenX = 0, screenY = 0; + + for (const UIWindow* window = this; window; window = window->parent) { + screenX = (screenX + window->geometry.x); + screenY = (screenY + window->geometry.y); + } + + if (!text.empty()) { + this->m_controls->services.Tooltip(text.c_str(), screenX, screenY, -1, false, true); + } +} + +// OFFSET: 0x008915E0 +// FUNCTION: fn_11449 +void UIBasicSkillCtrl::Slot28(int, int) { + if (this->m_skillId < 0) { + return; + } + + int screenX = 0, screenY = 0; + + for (const UIWindow* window = this; window; window = window->parent) { + screenX = (screenX + window->geometry.x); + screenY = (screenY + window->geometry.y); + } + + LuaScript& script = *g_session.m_hotkeyScript; + CSkillInfo skill = this->m_skills->Lookup(static_cast(this->m_skillId)); + const int sp = skill.UseSpAmount(script, skill.level); + const int ap = skill.UseApAmount(script, skill.level); + std::string text; + + if (SkillUsesPercentSp(static_cast(skill.id))) { + text = SkillUseTextPercent(skill.DisplayName(script), skill.level, sp, ap); + } else { + text = SkillUseTextFlat(skill.DisplayName(script), skill.level, sp, ap); + } + + if (!text.empty()) { + this->m_controls->services.Tooltip(text.c_str(), screenX, screenY, -1, false, true); + } +} + +// OFFSET: 0x00891BC0 +// FUNCTION: fn_11456 +void UIMemberListBox::Slot28(int, int y) { + const int line = this->topLine + y / this->lineHeight; + if (line < this->topLine) { + return; + } + + unsigned visible = static_cast(this->geometry.height / this->lineHeight - this->bottomMargin + this->topLine); + if (this->lines.size() < visible) { + visible = static_cast(this->lines.size()); + } + + if (line >= static_cast(visible)) { + return; + } + + const char* text = this->lines[line].c_str(); + const int width = this->TextWidth(this->m_controls->fonts, this->m_controls->locale, text, 0, 0, 12, 0, 0); + if (width <= this->geometry.width - this->verticalOverflow * 15) { + return; + } + + int screenX = -4; + int screenY = y - y % this->lineHeight; + + for (const UIWindow* window = this; window; window = window->parent) { + screenX = (screenX + window->geometry.x); + screenY = (screenY + window->geometry.y); + } + + this->m_controls->services.Tooltip(this->lines[line].c_str(), screenX, screenY, -1, false, true); +} + +// OFFSET: 0x00891E40 +// FUNCTION: fn_11458 +void UIStaticItem::Slot28(int, int) { + char text[260]; + std::memset(text, 0, sizeof(text)); + int capacity = sizeof(text); + this->m_descriptions->Name(this->m_item, text, capacity, 0); + + if (std::strlen(text) == 0) { + return; + } + + int screenX = 0, screenY = -20; + + for (const UIWindow* window = this; window; window = window->parent) { + screenX = (screenX + window->geometry.x); + screenY = (screenY + window->geometry.y); + } + + this->m_controls->services.Tooltip(text, screenX, screenY, -1, false, true); +} diff --git a/Source/UI/Lists/UIMemberListBox.h b/Source/UI/Lists/UIMemberListBox.h new file mode 100644 index 0000000..75a9b2f --- /dev/null +++ b/Source/UI/Lists/UIMemberListBox.h @@ -0,0 +1,22 @@ +#ifndef RAGNAROK_SOURCE_UI_LISTS_UIMEMBERLISTBOX_H +#define RAGNAROK_SOURCE_UI_LISTS_UIMEMBERLISTBOX_H + +#include "UI/Lists/UIListBox.h" + +struct UIButtonContext; + +class UIChatHisBox : public UIListBox { +}; + +class UIChatHisBox2 : public UIChatHisBox { +}; + +class UIMemberListBox : public UIChatHisBox2 { +public: + void Slot28(int x, int y) override; + +protected: + UIButtonContext* m_controls; +}; + +#endif diff --git a/Source/UI/UIBasicCtrl.h b/Source/UI/UIBasicCtrl.h new file mode 100644 index 0000000..c411e4c --- /dev/null +++ b/Source/UI/UIBasicCtrl.h @@ -0,0 +1,38 @@ +#ifndef RAGNAROK_SOURCE_UI_UIBASICCTRL_H +#define RAGNAROK_SOURCE_UI_UIBASICCTRL_H + +#include "Contents/Items/ItemInfo.h" +#include "UI/Window/UIWindow.h" + +#include + +struct ItemNaming; +struct ClientSkills; +struct UIButtonContext; + +class UIBasicItemCtrl : public UIWindow { +public: + void Slot28(int x, int y) override; + +protected: + /* 007C */ unsigned char unknown_007C[0xC]; + /* 0088 */ std::string m_tooltip; + /* 00A0 */ ItemInfo m_item; + ItemNaming* m_naming; + UIButtonContext* m_controls; +}; + +class UIBasicSkillCtrl : public UIWindow { +public: + void Slot28(int x, int y) override; + +protected: + /* 007C */ int m_skillId; + ClientSkills* m_skills; + UIButtonContext* m_controls; +}; + +std::string SkillUseTextPercent(const char* name, int level, int sp, int ap); +std::string SkillUseTextFlat(const char* name, int level, int sp, int ap); + +#endif diff --git a/Source/UI/UIStaticItem.h b/Source/UI/UIStaticItem.h index 8e5349b..d8b713f 100644 --- a/Source/UI/UIStaticItem.h +++ b/Source/UI/UIStaticItem.h @@ -1,9 +1,20 @@ #ifndef RAGNAROK_SOURCE_UI_UISTATICITEM_H #define RAGNAROK_SOURCE_UI_UISTATICITEM_H +#include "Contents/Items/ItemInfo.h" #include "UI/Window/UIWindow.h" +struct ItemDescriptions; +struct UIButtonContext; + class UIStaticItem : public UIWindow { +public: + void Slot28(int x, int y) override; + +protected: + /* 0080 */ ItemInfo m_item; + ItemDescriptions* m_descriptions; + UIButtonContext* m_controls; }; class UIStaticItem_Illust : public UIStaticItem {