#include "UI/Chat/UINewChatWnd.h" #include "Client/Application/ApplicationWindow.h" #include "Client/Mode/CGameMode.h" #include "Client/Mode/ModeMgr.h" #include "Contents/NavigationManager.h" #include "UI/Dialogs/UITipboxWnd.h" #include "UI/Window/UIWindowMgr.h" #include "Contents/Items/ItemInfo.h" #include "UI/Lists/UIScrollBar.h" #include "UI/Buttons/UITextButton.h" #include "UI/Text/UITextViewer.h" #include "UI/Window/WindowManagerWindows.h" #include "Contents/Items/ItemNaming.h" #include "UI/Lists/UIChatHisBox.h" #include "UI/Text/NavigationLink.h" #include "UI/Text/PixelTextWrapping.h" #include "UI/Text/TextMarkup.h" #include "UI/Text/TextWrapping.h" #include "Render/Text/TextContext.h" #include #include #include #include // INLINED __forceinline void UITextViewer::Activate(UITextButton* button, int id) { switch (id) { case 437: if (button) { const std::string& url = button->GetLine(0); if (!url.empty()) { ShellExecuteA(hWnd, "open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL); } } break; case 438: { if (!button) { break; } const int count = button->GetLinesCount(); if (count == 0) { break; } const std::string& map = button->GetLine(0); const int x = std::atoi(button->GetLine(1).c_str()); const int y = std::atoi(button->GetLine(2).c_str()); if (count > 3) { const int type = std::atoi(button->GetLine(3).c_str()); int policy = std::atoi(button->GetLine(4).c_str()); if (policy == -222) { std::string name = "$$DB "; if (type != 3) { name.clear(); } name += map; g_navigationManager.sub_B995D0(name, type, 0); break; } const int option = std::atoi(button->GetLine(5).c_str()); const int target = std::atoi(button->GetLine(6).c_str()); unsigned char flag = 0; if (policy >= 100) { flag = 1; policy -= 100; } if (policy >= 10) { flag += 2; policy -= 10; } if (policy >= 1) { flag += 4; } g_navigationManager.sub_B99030(map.c_str(), type, flag, option == 0, x, y, target); } else { g_navigationManager.sub_B99030(map.c_str(), 2, 5, false, x, y, 1002); } break; } case 464: { if (!button || button->GetLinesCount() == 0) { break; } int idValue = 0; if (!button->GetLine(1).empty()) { idValue = std::atoi(button->GetLine(1).c_str()); } ITEM_INFO item; item.identified = 1; item.unknown_0000[0] = static_cast(idValue); item.unknown_0060 = 0; item.itemId = button->GetLine(0); if (UIWindow* window = g_windowMgr.sub_A978D0(12)) { window->SendMsg(nullptr, 24, reinterpret_cast(&item), 0, 0, 0); } break; } case 517: if (button && button->GetLinesCount() != 0) { const std::string& tip = button->GetLine(0); if (UIWindow* window = g_windowMgr.sub_A978D0(315)) { static_cast(window)->ShowTip(std::atoi(tip.c_str())); } } break; case 539: if (button) { const int value = std::atoi(button->GetLine(0).c_str()); static_cast(g_modeMgr.GetGameMode())->ReceiveServiceRequest(6, value); } break; default: break; } } // INLINED __forceinline void UITextViewer::AppendText(char* text, int width, int carriageReturns, int pixels) { const int lineWidth = width == 0 ? 35 : width; std::vector wrapped; if (width == 138) { WrapPlainText(text, wrapped, 38); for (unsigned index = 0; index < wrapped.size(); ++index) { this->AddLine(wrapped[index].c_str()); } this->unknown_00BC = (this->unknown_00BC & ~255) | 1; return; } if (HasTextLinks(text)) { const std::string expanded = ExpandTextEscapes(text); strcpy_s(text, std::strlen(text) + 1, expanded.c_str()); std::string display = DisplayUrlTextTag(text); display = DisplayNavigationTextTag(display); display = DisplayTipBoxTextTag(display); display = DisplayItemTextTag(display); display = RemoveTextLinkInfo(display); if (g_windowMgr.window_01C8) { display = static_cast(g_windowMgr.window_01C8)->ConvertChat(display); } std::string navigation; DisplayNavigationLink(navigation, display); display = DisplayQuestTextTag(navigation); if (pixels) { const int scrollWidth = carriageReturns ? this->verticalBar->geometry.width + 2 : 0; this->WrapPixelText(display.c_str(), wrapped, this->geometry.width - scrollWidth - 4); } else { WrapRichText(display.c_str(), wrapped, lineWidth, carriageReturns != 0); } for (unsigned index = 0; index < wrapped.size(); ++index) { this->AddLine(wrapped[index].c_str()); } this->AddItemLinks(text, static_cast(wrapped.size())); this->AddUrlLinks(text, static_cast(wrapped.size())); this->AddNaviLinks(text, static_cast(wrapped.size())); this->AddTipLinks(text, static_cast(wrapped.size())); this->AddQuestLinks(text, static_cast(wrapped.size())); } else { if (pixels) { const int scrollWidth = carriageReturns ? this->verticalBar->geometry.width + 2 : 0; this->WrapPixelText(text, wrapped, this->geometry.width - scrollWidth - 4); } else { WrapRichText(text, wrapped, lineWidth, carriageReturns != 0); } for (unsigned index = 0; index < wrapped.size(); ++index) { this->AddLine(wrapped[index].c_str()); } } this->unknown_00BC &= ~255; } // OFFSET: 0x00899E90 // FUNCTION: fn_11562 int UITextViewer::SendMsg(UIWindow* sender, int message, std::intptr_t argument1, std::intptr_t argument2, std::intptr_t argument3, std::intptr_t argument4) { switch (message) { case 7: case 8: case 9: case 10: case 11: case 12: { const int previousX = this->horizontalOffset; UIListBox::SendMsg(sender, message, argument1, argument2, argument3, argument4); for (unsigned index = 0; index < this->links.size(); ++index) { UITextButton* button = this->links[index]; if (!button) { continue; } const int row = button->m_value; if (row >= this->topLine && row < this->geometry.height / this->lineHeight - this->bottomMargin + this->topLine) { button->Enable(1); button->Move(button->geometry.x - this->horizontalOffset + previousX, (row - this->topLine) * this->lineHeight + 3); } else { button->Enable(0); } } return 0; } case 18: if (this->verticalOverflow != 0) { this->SendMsg(this->verticalBar, 7, -1, 0, 0, 0); } return 0; case 19: if (this->verticalOverflow != 0) { this->SendMsg(this->verticalBar, 7, 1, 0, 0, 0); } return 0; case 29: this->AppendText(reinterpret_cast(argument1), static_cast(argument2), static_cast(argument3), static_cast(argument4)); this->Invalidate(); return 0; case 98: this->Activate(static_cast(sender), static_cast(argument1)); return 0; default: return UIListBox::SendMsg(sender, message, argument1, argument2, argument3, argument4); } }