Batch #17156 by eAthena: 2 byte-identical, 0 confirmed by peer review. - fn_07755 CRmaRes::Unload: byte-identical (already on main) - fn_07778 CRmaRes::~CRmaRes: byte-identical (already on main) Merged automatically: every function is byte-identical to the original.
4558 lines
177 KiB
C++
4558 lines
177 KiB
C++
#include "Render/DeviceContext/DCSurface.h"
|
|
#include "Client/Mode/ModeMessage.h"
|
|
#include "UI/Window/UIEnums.h"
|
|
#include "UI/Window/WindowId.h"
|
|
#include "UI/Window/UIEnums.h"
|
|
#include "Render/Text/FontCache.h"
|
|
#include "Contents/Items/ItemDescription.h"
|
|
#include "Contents/CombatTypes.h"
|
|
#include "Resource/Bitmap/BitmapResource.h"
|
|
#include "Resource/ResourceMgr.h"
|
|
#include "Resource/Bitmap/TextureNames.h"
|
|
#include "Resource/Bitmap/SkinPalette.h"
|
|
#include "UI/Dialogs/UICntWnd.h"
|
|
#include "UI/Chat/UIChatRoomWnd.h"
|
|
#include "UI/Shop/UIBank_NewWnd.h"
|
|
#include "UI/Edit/UIEditCtrl.h"
|
|
#include "Client/Session/Session.h"
|
|
#include "Utility/Text/GroupedInteger.h"
|
|
#include "UI/Buttons/UIBitmapButton.h"
|
|
#include "UI/Buttons/UIBmpTextButton.h"
|
|
#include "UI/Login/UILoginWnd.h"
|
|
#include "UI/Dialogs/UIMessageBox.h"
|
|
#include "UI/Dialogs/UINoticeWnd.h"
|
|
#include "UI/Lists/UIScrollBar.h"
|
|
#include "UI/Replay/UIReplayListBox.h"
|
|
#include "UI/Replay/UISelectReplayDataWnd.h"
|
|
#include "UI/Login/UISelectServerWnd.h"
|
|
#include "UI/Buttons/UIStaticBitmap.h"
|
|
#include "UI/Buttons/UITextButton.h"
|
|
#include "UI/Text/UITextViewer.h"
|
|
#include "UI/Window/WindowBorder.h"
|
|
#include "UI/Window/UIWindowMgr.h"
|
|
#include "UI/Status/UIMerInfoWnd.h"
|
|
#include "UI/Dialogs/UIMessageBoxAutoreturn.h"
|
|
#include "UI/Monster/UIMonsterInfoWnd.h"
|
|
#include "UI/Dialogs/UITalkboxTrapInputWnd.h"
|
|
#include "UI/Status/UIHomunInfoWnd.h"
|
|
#include "UI/Status/UIPetInfoWnd.h"
|
|
#include "UI/Replay/UIReplayRECControlWnd.h"
|
|
#include "Client/Mode/ModeMgr.h"
|
|
#include "Client/Application/Registry.h"
|
|
#include "Utility/Cipher/XorBytes.h"
|
|
#include "UI/Login/UILoginOTPWnd.h"
|
|
#include "UI/Window/InputFocus.h"
|
|
#include "UI/Buttons/UIButton.h"
|
|
#include "Render/Text/TextContext.h"
|
|
#include "Contents/Tables/MessageTable.h"
|
|
#include "UI/Text/ColoredText.h"
|
|
#include "Client/Mode/CMode.h"
|
|
#include "UI/CashShop/UIPayConfirmWnd.h"
|
|
#include "UI/Replay/UIReplayControlWnd.h"
|
|
#include "UI/Login/UIMakeCharWnd.h"
|
|
#include "Client/Mode/CLoginMode.h"
|
|
#include "Client/Replay/Replay.h"
|
|
#include "Client/Application/Launcher.h"
|
|
#include "UI/Lists/UIChatHisBox.h"
|
|
#include "UI/Lists/UIMemberListBox.h"
|
|
#include "UI/Window/UIResizer.h"
|
|
#include "Client/Application/ApplicationWindow.h"
|
|
#include "UI/Text/UIStaticText.h"
|
|
#include "UI/Gauges/UIBarGraph.h"
|
|
#include "Utility/Text/FormatString.h"
|
|
#include "Resource/Sprites/ActionResource.h"
|
|
#include "Resource/Sprites/SpriteResource.h"
|
|
#include <cstring>
|
|
#include <format>
|
|
#include "Client/Mode/CGameMode.h"
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <windows.h>
|
|
#include <timeapi.h>
|
|
#include <shellapi.h>
|
|
#include <imm.h>
|
|
#include <direct.h>
|
|
#include <io.h>
|
|
#include "UI/Lists/UIListBox.h"
|
|
#include "UI/Lists/UIComboBox.h"
|
|
#include "Contents/Sound/SoundMgr.h"
|
|
#include "Contents/Configuration/ServiceConfiguration.h"
|
|
#include "UI/Login/UINewSelectCharWnd.h"
|
|
#include "UI/Items/UIItemWnd.h"
|
|
#include "Contents/Sound/SoundMaker.h"
|
|
#include "UI/Buttons/UICheckBox.h"
|
|
#include "Contents/ClientState.h"
|
|
#include "Contents/Tables/ForbiddenWords.h"
|
|
#include "UI/Dialogs/UINormalMB.h"
|
|
#include "UI/Buttons/UINoneVisibleButton.h"
|
|
#include "Contents/Pet/PetEvolutionMgr.h"
|
|
#include "Contents/Items/ItemInfo.h"
|
|
#include "Contents/Hotkeys/HotkeyInfo.h"
|
|
#include <mbstring.h>
|
|
#include "Contents/Actors/Pc.h"
|
|
#include "Contents/Sprites/SpriteRidingOffset.h"
|
|
#include "Render/DeviceContext/DeviceContext.h"
|
|
#include "Render/Renderer.h"
|
|
#include "Render/Textures/SpriteAtlas.h"
|
|
#include "Render/Textures/Texture.h"
|
|
#include "Resource/Sprites/ImfResource.h"
|
|
#include "Resource/Bitmap/PaletteResource.h"
|
|
#include "Contents/Jobs/JobInheritance.h"
|
|
#include "Utility/Cipher/LocalEncryptedName.h"
|
|
#include "Utility/Cipher/CryptName.h"
|
|
|
|
#include "Resource/MSGSTRINGID.h"
|
|
|
|
extern template std::vector<std::string>::~vector();
|
|
extern template bool std::_Traits_equal<std::char_traits<char>>(const char*, std::size_t, const char*, std::size_t) noexcept;
|
|
// GLOBAL: gl_25153
|
|
static const std::string s_messageBoxItemLinkOpening = "<ITEML>";
|
|
|
|
// GLOBAL: gl_25154
|
|
static const std::string s_messageBoxItemLinkClosing = "</ITEML>";
|
|
|
|
namespace {
|
|
constexpr char prefix[] = "유저인터페이스\\";
|
|
|
|
// INLINED
|
|
int TileCount(int length, int tile) {
|
|
const std::div_t tiles = std::div(length, tile);
|
|
return tiles.quot + (tiles.rem != 0);
|
|
}
|
|
|
|
struct HangameJoinUrl {
|
|
EncryptedName<80, 0xF3CB6F7711A71B6DULL>& operator()() const;
|
|
};
|
|
}
|
|
|
|
// OFFSET: 0x008A39C0
|
|
// FUNCTION: fn_11661
|
|
UIMakeCharWnd::UIMakeCharWnd()
|
|
: UIFrameWnd(0), m_rotateLeftButton(0), m_rotateRightButton(0), m_hairStyleBar(0), m_hairColorBar(0), m_hairStyle(0), m_hairColor(0) {
|
|
this->geometry.animationFrame = 0;
|
|
this->m_nameEdit = nullptr;
|
|
this->m_info.sex = static_cast<unsigned char>(g_session.m_sex);
|
|
|
|
const int* preset = reinterpret_cast<const int*>(g_modeMgr.gameMode->SendMsg(LMM_GET_CHAR_PARAM, 0, 0, 0, 0));
|
|
this->m_info.stats[0] = static_cast<unsigned char>(preset[0]);
|
|
this->m_info.stats[1] = static_cast<unsigned char>(preset[1]);
|
|
this->m_info.stats[2] = static_cast<unsigned char>(preset[2]);
|
|
this->m_info.stats[3] = static_cast<unsigned char>(preset[3]);
|
|
this->m_info.stats[4] = static_cast<unsigned char>(preset[4]);
|
|
this->m_info.stats[5] = static_cast<unsigned char>(preset[5]);
|
|
this->m_info.headPalette = static_cast<std::int16_t>(preset[6]);
|
|
this->m_info.head = static_cast<std::int16_t>(preset[7]);
|
|
|
|
this->m_info.name[0] = 0;
|
|
this->m_info.job = 0;
|
|
this->m_info.jobPoint = 0;
|
|
this->m_info.hp = 100;
|
|
this->m_info.maxHp = 100;
|
|
this->m_info.sp = 100;
|
|
this->m_info.maxSp = 100;
|
|
this->m_info.exp = 0;
|
|
this->m_info.level = 1;
|
|
this->m_info.skillPoint = 1;
|
|
this->m_info.slot = static_cast<unsigned char>(g_selectedSlotIndex);
|
|
this->m_info.headPalette = 0;
|
|
this->m_info.bodyStyle = 0;
|
|
this->m_info.shield = 0;
|
|
this->m_info.accessory2 = 0;
|
|
this->m_info.accessory3 = 0;
|
|
this->m_view.actionBase = 0;
|
|
this->m_view.action = 0;
|
|
this->m_view.frame = 0;
|
|
this->m_view.x = 70;
|
|
this->m_view.y = 123;
|
|
|
|
this->m_view.actionNames[0].assign(GetBodyActionResourceName(this->m_info.job, this->m_info.sex, 0, 0));
|
|
this->m_view.spriteNames[0].assign(g_session.GetBodySprName(this->m_info.job, this->m_info.sex, 0, 0));
|
|
|
|
if (this->m_info.sex == 1 && this->m_info.head == 13) {
|
|
this->m_info.head = 14;
|
|
}
|
|
|
|
int head = this->m_info.head;
|
|
this->m_view.actionNames[1].assign(g_session.GetHeadActName(this->m_info.job, this->m_info.sex, &head));
|
|
this->m_view.spriteNames[1].assign(g_session.GetHeadSprName(this->m_info.job, this->m_info.sex, &head));
|
|
|
|
const int bodyPalette = this->m_info.bodyStyle;
|
|
this->m_info.head = static_cast<std::int16_t>(head);
|
|
this->m_view.bodyPalette = bodyPalette;
|
|
if (bodyPalette) {
|
|
this->m_view.bodyPaletteName.assign(g_session.GetBodyPalName(this->m_info.job, this->m_info.sex, bodyPalette, this->m_info.bodyCostume, 0, 0));
|
|
}
|
|
|
|
const int headPalette = this->m_info.headPalette;
|
|
this->m_view.headPalette = headPalette;
|
|
if (headPalette) {
|
|
this->m_view.headPaletteName.assign(g_session.GetHeadPalName(head, this->m_info.job, this->m_info.sex, headPalette));
|
|
}
|
|
|
|
this->m_view.imfName = GetBodyImfName(this->m_info.job, this->m_info.sex, this->m_info.head, this->m_info.bodyCostume);
|
|
this->geometry.currentAlpha = 0x80;
|
|
this->geometry.targetAlpha = 0xFF;
|
|
}
|
|
|
|
// OFFSET: 0x008A3F60
|
|
// FUNCTION: fn_11662
|
|
UIMerInfoWnd::UIMerInfoWnd() : UIFrameWnd(0) {
|
|
}
|
|
|
|
// OFFSET: 0x008A3FC0
|
|
// FUNCTION: fn_11663
|
|
UIMessageBox::UIMessageBox() : UIFrameWnd(0) {
|
|
this->counting = 0;
|
|
this->protectedMessage = 0;
|
|
}
|
|
|
|
// OFFSET: 0x008A40B0
|
|
// FUNCTION: fn_11664
|
|
UIMessageBoxAutoreturn::UIMessageBoxAutoreturn() : UIFrameWnd(0) {
|
|
this->counting = 0;
|
|
}
|
|
|
|
// OFFSET: 0x008A4170
|
|
// FUNCTION: fn_11665
|
|
UIMonsterInfoWnd::UIMonsterInfoWnd()
|
|
: UIFrameWnd(0) {
|
|
std::memset(&this->info, 0, offsetof(MonsterInfo, resistances) + sizeof(this->info.resistances));
|
|
this->actorId = 0;
|
|
}
|
|
|
|
// INLINED
|
|
UIReplayRECControlWnd::~UIReplayRECControlWnd() {
|
|
this->recordStart = 0;
|
|
this->mode = 0;
|
|
}
|
|
|
|
// OFFSET: 0x008A5220
|
|
// FUNCTION: fn_11680
|
|
UIMessageBox::~UIMessageBox() = default;
|
|
|
|
// OFFSET: 0x008B8E60
|
|
// FUNCTION: fn_11768
|
|
void UIMessageBox::Paint() {
|
|
this->DrawTitleBar(true, this->caption.c_str(), 0);
|
|
this->DrawPanelBackground(17, 0, "");
|
|
}
|
|
|
|
// OFFSET: 0x008AC410
|
|
// FUNCTION: fn_11729
|
|
bool UIBank_NewWnd::NeedsFrameRefresh() {
|
|
return true;
|
|
}
|
|
|
|
// OFFSET: 0x008AC420
|
|
// FUNCTION: fn_11730
|
|
bool UIReplayControlWnd::NeedsFrameRefresh() {
|
|
return true;
|
|
}
|
|
|
|
// OFFSET: 0x008AC430
|
|
// FUNCTION: fn_11731
|
|
bool UIReplayRECControlWnd::NeedsFrameRefresh() {
|
|
return true;
|
|
}
|
|
|
|
// OFFSET: 0x008B7A90
|
|
// FUNCTION: fn_11756
|
|
void UIMessageBox::OnDestroy() {
|
|
}
|
|
|
|
// OFFSET: 0x008B7AA0
|
|
// FUNCTION: fn_11757
|
|
void UINoticeWnd::OnDestroy() {
|
|
}
|
|
|
|
// OFFSET: 0x008B7AB0
|
|
// FUNCTION: fn_11758
|
|
void UISelectReplayDataWnd::OnDestroy() {
|
|
}
|
|
|
|
// OFFSET: 0x008B7AC0
|
|
// FUNCTION: fn_11759
|
|
void UISelectServerWnd::OnDestroy() {
|
|
}
|
|
|
|
// OFFSET: 0x008B8610
|
|
// FUNCTION: fn_11765
|
|
void UILoginWnd::Paint() {
|
|
this->ClearSurface(0xFFFF00FF);
|
|
}
|
|
|
|
// OFFSET: 0x008B8620
|
|
// FUNCTION: fn_11766
|
|
void UIMakeCharWnd::Paint() {
|
|
CBitmapRes* background = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve("유저인터페이스\\login_interface\\win_make2.bmp")));
|
|
this->DrawBitmap(0, 17, background, false);
|
|
this->DrawTitleBar(true, LookupMessage(MSI_SELECT_SEX), 0);
|
|
this->DrawButtonBar(2, 0, 1);
|
|
|
|
SpriteAtlasRecord record{};
|
|
for (int i = 0; i < 2; ++i) {
|
|
CImfRes* offsets = static_cast<CImfRes*>(ResourceMgr::Instance().Load(this->m_view.imfName.c_str()));
|
|
CActRes* action = static_cast<CActRes*>(ResourceMgr::Instance().Load(this->m_view.actionNames[i].c_str()));
|
|
CSprRes* sprite = static_cast<CSprRes*>(ResourceMgr::Instance().Load(this->m_view.spriteNames[i].c_str()));
|
|
const ActionFrame& frame = action->Frame(this->m_view.action, this->m_view.frame);
|
|
POINT offset = offsets->GetLongPoint(i, this->m_view.action, this->m_view.frame);
|
|
|
|
if (i == 1) {
|
|
CActRes* body = static_cast<CActRes*>(ResourceMgr::Instance().Load(this->m_view.actionNames[0].c_str()));
|
|
const ActionFrame& bodyFrame = body->Frame(this->m_view.action, this->m_view.frame);
|
|
if (frame.anchorCount != 0 && bodyFrame.anchorCount != 0 && frame.anchors[0].attachmentId == bodyFrame.anchors[0].attachmentId) {
|
|
offset.x += bodyFrame.anchors[0].x - frame.anchors[0].x;
|
|
offset.y += bodyFrame.anchors[0].y - frame.anchors[0].y;
|
|
}
|
|
}
|
|
|
|
const std::uint32_t* palette = sprite->palette;
|
|
switch (i) {
|
|
case 0:
|
|
if (this->m_view.bodyPalette) {
|
|
palette = static_cast<CPaletteRes*>(ResourceMgr::Instance().Load(this->m_view.bodyPaletteName.c_str()))->palette;
|
|
}
|
|
break;
|
|
case 1:
|
|
if (this->m_view.headPalette) {
|
|
palette = static_cast<CPaletteRes*>(ResourceMgr::Instance().Load(this->m_view.headPaletteName.c_str()))->palette;
|
|
}
|
|
break;
|
|
}
|
|
|
|
const SpriteFrameCell& cell = frame.Cell(i);
|
|
if (cell.image == -1) {
|
|
continue;
|
|
}
|
|
|
|
const SpriteRleImage* image = sprite->images[cell.imageType][cell.image];
|
|
CTexture* texture;
|
|
if (cell.imageType == 0) {
|
|
texture = g_renderer->atlas.Find(image, palette, record);
|
|
if (!texture) {
|
|
texture = g_renderer->atlas.Insert(*GetRenderSystemHolder()->system, image, palette, record, g_serviceType, g_resourceReuseDelay);
|
|
}
|
|
} else {
|
|
texture = static_cast<CTexture*>(const_cast<void*>(image->surface));
|
|
}
|
|
|
|
this->geometry.surface->DrawSurface(
|
|
this->m_view.x + cell.x + offset.x, this->m_view.y + cell.y + offset.y, texture, static_cast<int>(record.u0 * 256.0f),
|
|
static_cast<int>(record.v0 * 256.0f), image->width, image->height, cell.mirrored != 0, image->doubleWidth + 1, image->doubleHeight + 1, 0, 0
|
|
);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008B88F0
|
|
// FUNCTION: fn_11767
|
|
void UIMerInfoWnd::Paint() {
|
|
auto* background = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve("유저인터페이스\\basic_interface\\homuninfo_bg.bmp")));
|
|
this->DrawBitmap(0, 0, background, false);
|
|
char title[50] = {};
|
|
const unsigned kind = g_session.m_mercenaryClass;
|
|
const int titleId = kind - 6017 <= 9 ? 1181 : kind - 6037 <= 9 ? 1182 : kind - 6027 <= 9 ? 1183 : 1367;
|
|
std::sprintf(title, LookupMessage(titleId));
|
|
this->DrawTextAt(5, 2, title, 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(100, 24, LookupMessage(MSI_NAME), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(100, 47, LookupMessage(MSI_LEVEL), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(100, 111, LookupMessage(MSI_LEFT_TIME), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(100, 135, LookupMessage(MSI_MER_FRIENDLY), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(100, 159, LookupMessage(MSI_MER_CALLCOUNT), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(230, 133, LookupMessage(MSI_MER_KILL), 0, 0, 12, 0, 0, 0);
|
|
{
|
|
char number[24] = {};
|
|
int bytes = std::sprintf(number, "%d", g_session.m_mercenaryStats[0]);
|
|
this->DrawRightAlignedText(79, 24, number, bytes, 1, 14, 0, 0);
|
|
bytes = std::sprintf(number, "%d", g_session.m_mercenaryStats[1]);
|
|
this->DrawRightAlignedText(79, 42, number, bytes, 1, 14, 0, 0);
|
|
bytes = std::sprintf(number, "%d", g_session.m_mercenaryStats[2]);
|
|
this->DrawRightAlignedText(79, 60, number, bytes, 1, 14, 0, 0);
|
|
bytes = std::sprintf(number, "%d", g_session.m_mercenaryStats[3]);
|
|
this->DrawRightAlignedText(79, 78, number, bytes, 1, 14, 0, 0);
|
|
bytes = std::sprintf(number, "%d", g_session.m_mercenaryStats[4]);
|
|
this->DrawRightAlignedText(79, 96, number, bytes, 1, 14, 0, 0);
|
|
bytes = std::sprintf(number, "%d", g_session.m_mercenaryStats[5]);
|
|
this->DrawRightAlignedText(79, 114, number, bytes, 1, 14, 0, 0);
|
|
bytes = std::sprintf(number, "%d", g_session.m_mercenaryStats[6]);
|
|
this->DrawRightAlignedText(79, 132, number, bytes, 1, 14, 0, 0);
|
|
bytes = std::sprintf(number, "%d", (2000 - g_session.m_mercenaryStats[7]) / 10);
|
|
this->DrawRightAlignedText(79, 150, number, bytes, 1, 14, 0, 0);
|
|
}
|
|
this->DrawTextAt(136, 24, g_session.m_mercenaryName, 0, 0, 12, 0x646464, 0, 0);
|
|
this->DrawTextAt(135, 24, g_session.m_mercenaryName, 0, 0, 12, 0, 0, 0);
|
|
{
|
|
char level[12] = {};
|
|
_itoa(g_session.m_mercenaryLevel, level, 10);
|
|
this->DrawTextAt(135, 47, level, 0, 0, 12, 0, 0, 0);
|
|
}
|
|
if (g_session.m_mercenaryClass == -1) {
|
|
return;
|
|
}
|
|
char text[32] = {};
|
|
int bytes = std::sprintf(text, "%d / %d", g_session.m_mercenaryHp, g_session.m_mercenaryMaxHp);
|
|
this->DrawTextAt(218, 70, text, bytes, 1, 14, 0, 0, 0);
|
|
bytes = std::sprintf(text, "%d / %d", g_session.m_mercenarySp, g_session.m_mercenaryMaxSp);
|
|
this->DrawTextAt(218, 85, text, bytes, 1, 14, 0, 0, 0);
|
|
std::strftime(text, 128, LookupMessage(MSI_TIME_TYPE2), _localtime32(&g_session.m_mercenaryExpiration));
|
|
this->DrawTextAt(155, 111, text, static_cast<int>(std::strlen(text)), 0, 12, 255, 0, 0);
|
|
bytes = std::sprintf(text, "%d", g_session.m_mercenaryLoyalty);
|
|
this->DrawTextAt(170, 133, text, bytes, 1, 14, 0, 0, 0);
|
|
bytes = std::sprintf(text, "%d", g_session.m_mercenarySummons);
|
|
this->DrawTextAt(170, 157, text, bytes, 1, 14, 0, 0, 0);
|
|
bytes = std::sprintf(text, "%d", g_session.m_mercenaryKills);
|
|
this->DrawTextAt(245, 157, text, bytes, 1, 14, 0, 0, 0);
|
|
}
|
|
|
|
// OFFSET: 0x008A6E20
|
|
// FUNCTION: fn_11712
|
|
long long UIBank_NewWnd::TransactionAmount(unsigned char deposit) {
|
|
std::string text = this->m_amountEdit->Text();
|
|
this->m_amountEdit->SetText("");
|
|
if (text == std::string(LookupMessage(MSI_BANK_1_MINI))) {
|
|
const long long cash = g_session.m_zeny;
|
|
const long long balance = g_session.m_bankBalance;
|
|
const long long excess = cash + balance > 0x7FFFFFFF ? cash + balance - 0x7FFFFFFF : 0;
|
|
if (deposit) {
|
|
if (balance >= 0x7FFFFFFF) {
|
|
g_windowMgr.SendNotice(UIM_PUSHINTOCHATHISTORY, reinterpret_cast<std::intptr_t>(LookupMessage(MSI_ITEMMOVEINFO_CART)), 255, 0, 0, 0);
|
|
this->m_status = LookupMessage(MSI_BANK_6_MINI);
|
|
return 0;
|
|
}
|
|
if (g_session.m_zeny == 0) {
|
|
g_windowMgr.SendNotice(UIM_PUSHINTOCHATHISTORY, reinterpret_cast<std::intptr_t>(LookupMessage(MSI_BANK_3)), 255, 0, 0, 0);
|
|
this->m_status = LookupMessage(MSI_BANK_3_MINI);
|
|
return 0;
|
|
}
|
|
const long long amount = cash - excess;
|
|
if (amount < 0) {
|
|
g_windowMgr.SendNotice(UIM_PUSHINTOCHATHISTORY, reinterpret_cast<std::intptr_t>(LookupMessage(MSI_NOT_VALID_AUTH_TICKET)), 255, 0, 0, 0);
|
|
this->m_status = LookupMessage(MSI_BANK_3_MINI);
|
|
return 0;
|
|
}
|
|
return amount;
|
|
}
|
|
if (balance == 0) {
|
|
g_windowMgr.SendNotice(UIM_PUSHINTOCHATHISTORY, reinterpret_cast<std::intptr_t>(LookupMessage(MSI_BANK_3)), 255, 0, 0, 0);
|
|
this->m_status = LookupMessage(MSI_BANK_3_MINI);
|
|
return 0;
|
|
}
|
|
const long long amount = balance - excess;
|
|
return cash + amount > 0x7FFFFFFF ? static_cast<long long>(0x7FFFFFFF - g_session.m_zeny) : amount;
|
|
}
|
|
if (text.empty()) {
|
|
g_windowMgr.SendNotice(UIM_PUSHINTOCHATHISTORY, reinterpret_cast<std::intptr_t>(LookupMessage(MSI_BANK_2_MINI)), 255, 0, 0, 0);
|
|
this->m_status = LookupMessage(MSI_BANK_4_MINI);
|
|
return 0;
|
|
}
|
|
if (!this->IsNumeric(text)) {
|
|
g_windowMgr.SendNotice(UIM_PUSHINTOCHATHISTORY, reinterpret_cast<std::intptr_t>(LookupMessage(MSI_ITEM_COMPARISON)), 255, 0, 0, 0);
|
|
this->m_status = LookupMessage(MSI_BANK_5_MINI);
|
|
return 0;
|
|
}
|
|
const long long amount = _atoi64(text.c_str());
|
|
if (amount > 0x7FFFFFFF) {
|
|
g_windowMgr.SendNotice(UIM_PUSHINTOCHATHISTORY, reinterpret_cast<std::intptr_t>(LookupMessage(MSI_BANK_1)), 255, 0, 0, 0);
|
|
this->m_status = LookupMessage(MSI_BANK_6_MINI);
|
|
return 0;
|
|
}
|
|
if (amount < 1) {
|
|
g_windowMgr.SendNotice(UIM_PUSHINTOCHATHISTORY, reinterpret_cast<std::intptr_t>(LookupMessage(MSI_BANK_2)), 255, 0, 0, 0);
|
|
this->m_status = LookupMessage(MSI_BANK_7_MINI);
|
|
return 0;
|
|
}
|
|
return amount;
|
|
}
|
|
|
|
// OFFSET: 0x008A6C20
|
|
// FUNCTION: fn_11710
|
|
long long UIBank_NewWnd::AdjustAmount(int amount) {
|
|
std::string text = this->m_amountEdit->Text();
|
|
this->m_amountEdit->SetText("");
|
|
long long result;
|
|
if (text.empty()) {
|
|
result = amount;
|
|
} else if (!this->IsNumeric(text)) {
|
|
result = amount;
|
|
} else {
|
|
result = amount + _atoi64(text.c_str());
|
|
}
|
|
if (result > 0x7FFFFFFF) {
|
|
result = 0x7FFFFFFF;
|
|
} else if (result < 0) {
|
|
result = 0;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// OFFSET: 0x008C4B00
|
|
// FUNCTION: fn_11888
|
|
bool UIBank_NewWnd::IsNumeric(std::string text) {
|
|
if (text.size() == 0) {
|
|
return false;
|
|
}
|
|
|
|
for (auto it = text.begin(); it != text.end(); ++it) {
|
|
if (static_cast<unsigned char>(*it - '0') > 9) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// OFFSET: 0x008B7AD0
|
|
// FUNCTION: fn_11760
|
|
void UIBank_NewWnd::Paint() {
|
|
auto* background = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve("유저인터페이스\\bank\\bg_bank.bmp")));
|
|
this->DrawBitmap(0, this->DrawTitleBar(true, LookupMessage(MSI_BANK_4), 0), background, false);
|
|
|
|
char number[260] = {};
|
|
char text[260] = {};
|
|
this->DrawTextAt(30, 29, LookupMessage(MSI_BANK_5), 0, 0, 12, 0, 0, 0);
|
|
const int x = this->VerticalTextHeight(LookupMessage(MSI_BANK_5), 0, 0, 12, 0) + 43;
|
|
FormatGroupedInteger(g_session.m_bankBalance, number, 260);
|
|
std::sprintf(text, "%s z", number);
|
|
this->DrawTextAt(x, 29, text, 0, 0, 11, 0, 0, 0);
|
|
this->DrawTextAt(30, 46, LookupMessage(MSI_BANK_6), 0, 0, 12, 0, 0, 0);
|
|
FormatGroupedInteger(g_session.m_zeny, number, 260);
|
|
std::sprintf(text, "%s z", number);
|
|
this->DrawTextAt(x, 46, text, 0, 0, 11, 0, 0, 0);
|
|
if (!this->m_status.empty()) {
|
|
const int textWidth = this->VerticalTextHeight(this->m_status.c_str(), 0, 0, 12, 0);
|
|
const float statusX = this->geometry.width * 0.5f - textWidth * 0.5f;
|
|
this->DrawTextAt(static_cast<int>(statusX), 112, this->m_status.c_str(), 0, 0, 11, 255, 0, 0);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008B7CF0
|
|
// FUNCTION: fn_11761
|
|
void UIChatRoomWnd::Paint() {
|
|
const int titleHeight = this->DrawTitleBar(false, "", 0);
|
|
this->DrawPanelBackground(titleHeight, 0, "");
|
|
unsigned red, green, blue;
|
|
SkinPaletteChannels(ResourceMgr::Instance(), 20, 6, red, green, blue);
|
|
const int width = this->geometry.width;
|
|
this->FillRegion(width - width * 56 / 280 - 2, 17, 1, this->geometry.height - 38, RGB(red, green, blue));
|
|
this->DrawButtonBar(0, 0, 1);
|
|
}
|
|
|
|
// OFFSET: 0x008B7DA0
|
|
// FUNCTION: fn_11762
|
|
void UICntWnd::Paint() {
|
|
this->DrawBorder(0, 0, 0, 0);
|
|
}
|
|
|
|
// OFFSET: 0x008A91E0
|
|
// FUNCTION: fn_11721
|
|
void UIFrameWnd::DrawBorder(int x, int y, int width, int height) {
|
|
if (width == 0) {
|
|
width = this->geometry.width;
|
|
}
|
|
if (height == 0) {
|
|
height = this->geometry.height;
|
|
}
|
|
const auto load = [&](const char* name) {
|
|
return static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve(name)));
|
|
};
|
|
const int innerWidth = width - 28;
|
|
const int columns = TileCount(innerWidth, 14);
|
|
for (int i = 0; i < columns; ++i) {
|
|
auto* bitmap = load("유저인터페이스\\sysbox_mu.bmp");
|
|
this->DrawBitmap(x + 14 + i * 14, y, bitmap, false);
|
|
}
|
|
auto* bitmap = load("유저인터페이스\\sysbox_lu.bmp");
|
|
this->DrawBitmap(x, y, bitmap, false);
|
|
bitmap = load("유저인터페이스\\sysbox_ru.bmp");
|
|
this->DrawBitmap(x + width - bitmap->image.width, y, bitmap, false);
|
|
const int innerHeight = height - 28;
|
|
const int rows = TileCount(innerHeight, 14);
|
|
for (int i = 0; i < rows; ++i) {
|
|
bitmap = load("유저인터페이스\\sysbox_lm.bmp");
|
|
this->DrawBitmap(x, y + 14 + i * 14, bitmap, false);
|
|
}
|
|
for (int i = 0; i < rows; ++i) {
|
|
bitmap = load("유저인터페이스\\sysbox_rm.bmp");
|
|
this->DrawBitmap(x + width - bitmap->image.width, y + 14 + i * 14, bitmap, false);
|
|
}
|
|
for (int i = 0; i < columns; ++i) {
|
|
bitmap = load("유저인터페이스\\sysbox_md.bmp");
|
|
this->DrawBitmap(x + 14 + i * 14, y + height - bitmap->image.height, bitmap, false);
|
|
}
|
|
bitmap = load("유저인터페이스\\sysbox_ld.bmp");
|
|
this->DrawBitmap(x, y + height - bitmap->image.height, bitmap, false);
|
|
bitmap = load("유저인터페이스\\sysbox_rd.bmp");
|
|
this->DrawBitmap(x + width - bitmap->image.width, y + height - bitmap->image.height, bitmap, false);
|
|
unsigned red, green, blue;
|
|
SkinPaletteChannels(ResourceMgr::Instance(), 2, 2, red, green, blue);
|
|
this->FillRegion(x + 14, y + 14, innerWidth, innerHeight, RGB(red, green, blue));
|
|
}
|
|
|
|
// INLINED
|
|
__forceinline void UIMessageBox::FormatCountdown() {
|
|
char text[512];
|
|
std::sprintf(text, this->format.c_str(), this->remaining);
|
|
this->messageText = text;
|
|
}
|
|
|
|
// OFFSET: 0x008A7350
|
|
// FUNCTION: fn_11713
|
|
void UIMessageBox::Configure(
|
|
const char* text, int type, int defaultAccept, int timeout, const char* title, int width, int height, int modalValue, const char* icon
|
|
) {
|
|
this->caption = title;
|
|
this->messageText = text;
|
|
this->format = text;
|
|
this->started = timeGetTime();
|
|
this->deadline = timeGetTime() + static_cast<unsigned>(timeout);
|
|
this->remaining = (this->deadline - this->started) / 1000 + ((this->deadline - this->started) % 1000 != 0);
|
|
|
|
if (timeout) {
|
|
this->counting = 1;
|
|
this->FormatCountdown();
|
|
} else {
|
|
this->counting = 0;
|
|
}
|
|
|
|
this->modal = modalValue;
|
|
this->SetSize(width, height);
|
|
this->OnCreate(width, height);
|
|
this->OnSize(width, height);
|
|
this->Move((g_renderer->viewport.width - 640) / 2 + 185, (g_renderer->viewport.height - 480) / 2 + 180);
|
|
int inset = 0;
|
|
|
|
if (icon) {
|
|
auto* image = new UIStaticBitmap();
|
|
image->SetBitmap(icon);
|
|
image->SetSize(image->geometry.width, image->geometry.height);
|
|
image->Move(10, 22);
|
|
this->AddChild(image);
|
|
inset = image->geometry.width + image->geometry.x;
|
|
}
|
|
|
|
this->viewer = new UITextViewer();
|
|
this->viewer->Configure(inset + 10, 22, width - inset - 20, height - 55, 0);
|
|
unsigned red, green, blue;
|
|
SkinPaletteChannels(ResourceMgr::Instance(), 2, 2, red, green, blue);
|
|
this->viewer->backgroundColor = 0xFF000000u | RGB(red, green, blue);
|
|
this->viewer->Invalidate();
|
|
this->AddChild(this->viewer);
|
|
this->viewer->SendMsg(nullptr, UM_SETTEXT, reinterpret_cast<std::intptr_t>(this->messageText.data()), static_cast<int>(static_cast<double>(width) / 7.5), 0, 0);
|
|
this->m_message0 = type == 2 ? 188 : 185;
|
|
|
|
const std::string prefix("유저인터페이스\\");
|
|
int positions[3][2] = {{189, height - 24}, {189, height - 24}, {234, height - 24}};
|
|
const char* names[3][3] = {{"btn_ok", "btn_ok_a", "btn_ok_b"}, {"btn_ok", "btn_ok_a", "btn_ok_b"}, {"btn_cancel", "btn_cancel_a", "btn_cancel_b"}};
|
|
int ids[3] = {184, 187, 188};
|
|
|
|
switch (type) {
|
|
case 0: {
|
|
auto* button = new UIBitmapButton();
|
|
button->SetBitmap((prefix + names[0][0] + ".bmp").c_str(), 0, 0);
|
|
button->SetBitmap((prefix + names[0][1] + ".bmp").c_str(), 1, 0);
|
|
button->SetBitmap((prefix + names[0][2] + ".bmp").c_str(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight());
|
|
button->Move(width - 46, height - 24);
|
|
button->SetId(184);
|
|
this->AddChild(button);
|
|
this->m_message0 = 184;
|
|
break;
|
|
}
|
|
case 2: {
|
|
int x = width - 91;
|
|
|
|
for (int index = 1; index < 3; ++index) {
|
|
positions[index][0] = x;
|
|
auto* button = new UIBitmapButton();
|
|
button->SetBitmap((prefix + names[index][0] + ".bmp").c_str(), 0, 0);
|
|
button->SetBitmap((prefix + names[index][1] + ".bmp").c_str(), 1, 0);
|
|
button->SetBitmap((prefix + names[index][2] + ".bmp").c_str(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight());
|
|
button->Move(positions[index][0], positions[index][1]);
|
|
button->SetId(ids[index]);
|
|
this->AddChild(button);
|
|
x += 45;
|
|
}
|
|
|
|
this->m_message0 = defaultAccept ? 187 : 188;
|
|
this->m_message1 = 188;
|
|
break;
|
|
}
|
|
case 4: {
|
|
auto* button = new UIBitmapButton();
|
|
button->SetBitmap((prefix + names[2][0] + ".bmp").c_str(), 0, 0);
|
|
button->SetBitmap((prefix + names[2][1] + ".bmp").c_str(), 1, 0);
|
|
button->SetBitmap((prefix + names[2][2] + ".bmp").c_str(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight());
|
|
button->Move(width - 46, height - 24);
|
|
button->SetId(185);
|
|
this->AddChild(button);
|
|
this->m_message0 = 185;
|
|
break;
|
|
}
|
|
case 5: {
|
|
auto* button = new UIBitmapButton();
|
|
button->SetBitmap((prefix + names[0][0] + ".bmp").c_str(), 0, 0);
|
|
button->SetBitmap((prefix + names[0][1] + ".bmp").c_str(), 1, 0);
|
|
button->SetBitmap((prefix + names[0][2] + ".bmp").c_str(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight());
|
|
button->Move(width - 46, height - 24);
|
|
button->SetId(184);
|
|
this->AddChild(button);
|
|
this->m_message0 = 184;
|
|
|
|
auto* link = new UITextButton();
|
|
link->Configure(LookupMessage(MSI_FRIEND_ALREADY_FRIEND), 0x00F4934A, 0, 12, 0, 0);
|
|
link->m_hoverColor = 0x00FF7864;
|
|
link->Move(14, 70);
|
|
link->SetId(426);
|
|
link->SetDisabled(0);
|
|
link->Invalidate();
|
|
this->AddChild(link);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008BADC0
|
|
// FUNCTION: fn_11791
|
|
void UIMessageBox::OnProcess() {
|
|
if (this->counting == 0) {
|
|
return;
|
|
}
|
|
|
|
if (timeGetTime() > this->deadline) {
|
|
g_windowMgr.modalResponse = 187;
|
|
this->counting = 0;
|
|
return;
|
|
}
|
|
|
|
const unsigned previous = this->remaining;
|
|
const unsigned fraction = (this->deadline - timeGetTime()) % 1000 ? 1 : 0;
|
|
this->remaining = (this->deadline - timeGetTime()) / 1000 + fraction;
|
|
|
|
if (previous != this->remaining) {
|
|
this->FormatCountdown();
|
|
this->viewer->Clear();
|
|
this->viewer->SendMsg(nullptr, UM_SETTEXT, reinterpret_cast<std::intptr_t>(this->messageText.data()), 38, 0, 0);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008BF950
|
|
// FUNCTION: fn_11808
|
|
int UIMessageBox::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) {
|
|
switch (message) {
|
|
case UM_SET_MODAL:
|
|
this->modal = static_cast<int>(a);
|
|
return 0;
|
|
case UM_SETCOUNTMSG:
|
|
this->format = reinterpret_cast<const char*>(a);
|
|
return 0;
|
|
case UM_CHANGEMSG:
|
|
this->viewer->Clear();
|
|
this->viewer->SendMsg(nullptr, UM_SETTEXT, a, 38, 0, 0);
|
|
return 0;
|
|
case UM_COMMAND:
|
|
this->RecordResponse(static_cast<int>(a), b, c, d);
|
|
|
|
if (this->modal != 0) {
|
|
g_windowMgr.modalResponse = static_cast<int>(a);
|
|
} else {
|
|
switch (a) {
|
|
case ID_OK:
|
|
case ID_YES:
|
|
case ID_NO:
|
|
g_windowMgr.Schedule(this);
|
|
}
|
|
}
|
|
break;
|
|
case UM_TEXT_LBTN_UP:
|
|
if (a == 426) {
|
|
ShellExecuteA(hWnd, "open", LookupMessage(MSI_FRIEND_ALREADY_FRIEND), nullptr, nullptr, SW_SHOWNORMAL);
|
|
}
|
|
break;
|
|
case UM_SET_MESSAGE_PROTECTED:
|
|
this->protectedMessage = a > 0;
|
|
break;
|
|
case UM_IS_MESSAGE_PROTECTED:
|
|
return this->protectedMessage == 1;
|
|
default:
|
|
return UIFrameWnd::SendMsg(sender, message, a, b, c, d);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// OFFSET: 0x008BFB70
|
|
// FUNCTION: fn_11809
|
|
int UIMessageBoxAutoreturn::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) {
|
|
if (message != UM_COMMAND) {
|
|
return UIFrameWnd::SendMsg(sender, message, a, b, c, d);
|
|
}
|
|
|
|
g_windowMgr.modalResponse = static_cast<int>(a);
|
|
return 0;
|
|
}
|
|
|
|
// OFFSET: 0x008BFBA0
|
|
// FUNCTION: fn_11810
|
|
int UIMonsterInfoWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) {
|
|
switch (message) {
|
|
case UM_COMMAND:
|
|
if (a == 184) {
|
|
g_windowMgr.Schedule(this);
|
|
}
|
|
|
|
return 0;
|
|
case UM_SET_MONSTER_INFO:
|
|
if (a) {
|
|
std::memcpy(&this->info, reinterpret_cast<const void*>(a), offsetof(MonsterInfo, resistances) + sizeof(this->info.resistances));
|
|
}
|
|
|
|
this->Invalidate();
|
|
return 0;
|
|
default:
|
|
return UIFrameWnd::SendMsg(sender, message, a, b, c, d);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008C1DB0
|
|
// FUNCTION: fn_11817
|
|
int UITalkboxTrapInputWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) {
|
|
switch (message) {
|
|
case UM_COMMAND:
|
|
switch (a) {
|
|
case ID_OK: {
|
|
TalkboxTrapRequest request;
|
|
request.target.skillId = this->target.skillId;
|
|
request.target.cellX = this->target.cellX;
|
|
request.target.cellY = this->target.cellY;
|
|
request.target.skillLevel = this->target.skillLevel;
|
|
request.text = this->edit->Text();
|
|
g_modeMgr.GetGameMode()->SendMsg(MM_USE_SKILL_TOGROUND_WITH_TALKBOX, reinterpret_cast<int>(&request), 0, 0, 0);
|
|
}
|
|
[[fallthrough]];
|
|
case ID_CANCEL:
|
|
g_windowMgr.Schedule(this);
|
|
}
|
|
return 0;
|
|
case UM_SET_SKILL_INFO:
|
|
{
|
|
const auto* target = reinterpret_cast<const TalkboxTrapTarget*>(a);
|
|
this->target.skillId = target->skillId;
|
|
this->target.cellX = target->cellX;
|
|
this->target.cellY = target->cellY;
|
|
this->target.skillLevel = target->skillLevel;
|
|
}
|
|
return 0;
|
|
default:
|
|
return UIFrameWnd::SendMsg(sender, message, a, b, c, d);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008C1ED0
|
|
// FUNCTION: fn_11818
|
|
void UIWindowMgr::SetChatInputText(const char* text) {
|
|
this->chatInputText = text;
|
|
}
|
|
|
|
// OFFSET: 0x008C35A0
|
|
// FUNCTION: fn_11824
|
|
void UIChatRoomWnd::StoreInfo() {
|
|
if (this->saved) {
|
|
this->saved->width = this->geometry.width;
|
|
this->saved->height = this->geometry.height;
|
|
this->saved->x = this->geometry.x;
|
|
this->saved->y = this->geometry.y;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008C35E0
|
|
// FUNCTION: fn_11825
|
|
void UIHomunInfoWnd::StoreInfo() {
|
|
if (this->saved) {
|
|
this->saved->x = this->geometry.x;
|
|
this->saved->y = this->geometry.y;
|
|
this->saved->width = this->geometry.width;
|
|
this->saved->height = this->geometry.height;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008B0CA0
|
|
// FUNCTION: fn_11744
|
|
void UIMerInfoWnd::OnCreate(int, int) {
|
|
this->AddCloseButton("", 0);
|
|
{
|
|
const std::string name("유저인터페이스\\btn_fired");
|
|
this->button = new UIBitmapButton();
|
|
this->button->SetBitmap((name + ".bmp").c_str(), 0, 0);
|
|
this->button->SetBitmap((name + "_a.bmp").c_str(), 1, 0);
|
|
this->button->SetBitmap((name + "_b.bmp").c_str(), 2, 0);
|
|
this->button->SetSize(this->button->BitmapWidth(), this->button->BitmapHeight());
|
|
this->button->Move(187, 44);
|
|
this->button->SetId(350);
|
|
this->AddChild(this->button);
|
|
}
|
|
{
|
|
const std::string name("유저인터페이스\\btn_skill");
|
|
this->button = new UIBitmapButton();
|
|
this->button->SetBitmap((name + ".bmp").c_str(), 0, 0);
|
|
this->button->SetBitmap((name + "_a.bmp").c_str(), 1, 0);
|
|
this->button->SetBitmap((name + "_b.bmp").c_str(), 2, 0);
|
|
this->button->SetSize(this->button->BitmapWidth(), this->button->BitmapHeight());
|
|
this->button->Move(232, 44);
|
|
this->button->SetId(349);
|
|
this->AddChild(this->button);
|
|
}
|
|
|
|
this->hpBar = new UIBarGraphPlayer();
|
|
this->hpBar->SetValues([]() -> std::int64_t { return g_session.m_mercenaryHp; }, []() -> std::int64_t { return g_session.m_mercenaryMaxHp; });
|
|
this->hpBar->SetSize(85, 9);
|
|
this->hpBar->Move(117, 73);
|
|
this->AddChild(this->hpBar);
|
|
|
|
this->spBar = new UIBarGraphPlayer();
|
|
this->spBar->SetValues([]() -> std::int64_t { return g_session.m_mercenarySp; }, []() -> std::int64_t { return g_session.m_mercenaryMaxSp; });
|
|
this->spBar->SetSize(85, 9);
|
|
this->spBar->Move(117, 88);
|
|
this->AddChild(this->spBar);
|
|
|
|
this->m_message0 = 201;
|
|
}
|
|
|
|
// OFFSET: 0x008C3630
|
|
// FUNCTION: fn_11827
|
|
void UIMerInfoWnd::StoreInfo() {
|
|
if (this->saved) {
|
|
this->saved->x = this->geometry.x;
|
|
this->saved->y = this->geometry.y;
|
|
this->saved->width = this->geometry.width;
|
|
this->saved->height = this->geometry.height;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008BF720
|
|
// FUNCTION: fn_11807
|
|
int UIMerInfoWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) {
|
|
switch (message) {
|
|
case UM_DEFPUSH:
|
|
return 0;
|
|
case UM_COMMAND:
|
|
this->RecordResponse(static_cast<int>(a), b, c, d);
|
|
|
|
switch (a) {
|
|
case ID_OK:
|
|
this->Invalidate();
|
|
return 0;
|
|
case ID_CLOSE:
|
|
g_windowMgr.CloseWindow(WID_MERINFOWND);
|
|
return 0;
|
|
case ID_OPEN_MERSKILLLIST:
|
|
if (!g_windowMgr.CloseWindow(WID_SKILLLISTWND_SKILLTAB_1)) {
|
|
g_windowMgr.EnsureWindow(WID_SKILLLISTWND_SKILLTAB_1);
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
case ID_FIRE_MER: {
|
|
CMode* mode = g_modeMgr.GetGameMode();
|
|
|
|
if (g_windowMgr.Confirm(LookupMessage(MSI_DELETE_MER), 2, false, false, 0, "Message", 280, 120, 0) == 187) {
|
|
mode->SendMsg(MM_COMMAND_MER, 2, 0, 0, 0);
|
|
g_windowMgr.CloseWindow(WID_MERINFOWND);
|
|
g_windowMgr.CloseWindow(WID_SKILLLISTWND_SKILLTAB_1);
|
|
g_session.ResetMercenaryStats();
|
|
g_session.mercenaryAlive = 0;
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
default:
|
|
return 0;
|
|
}
|
|
case UM_SETINFO:
|
|
this->saved = reinterpret_cast<MerInfoWndInfo*>(a);
|
|
|
|
if (!this->saved->IsValid()) {
|
|
this->saved->Reset();
|
|
}
|
|
|
|
this->Move(this->saved->x, this->saved->y);
|
|
return 0;
|
|
default:
|
|
return UIFrameWnd::SendMsg(sender, message, a, b, c, d);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008C3670
|
|
// FUNCTION: fn_11828
|
|
void UIPetInfoWnd::StoreInfo() {
|
|
if (this->saved) {
|
|
this->saved->x = this->geometry.x;
|
|
this->saved->y = this->geometry.y;
|
|
this->saved->width = this->geometry.width;
|
|
this->saved->height = this->geometry.height;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008C36B0
|
|
// FUNCTION: fn_11829
|
|
void UIReplayRECControlWnd::StoreInfo() {
|
|
if (this->saved) {
|
|
this->saved->width = this->geometry.width;
|
|
this->saved->height = this->geometry.height;
|
|
this->saved->x = this->geometry.x;
|
|
this->saved->y = this->geometry.y;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008A6DC0
|
|
// FUNCTION: fn_11711
|
|
void UIReplayRECControlWnd::AnimateLoading() {
|
|
for (int index = 0; index < 4; ++index) {
|
|
this->tabs[index]->Move(-100, -100);
|
|
}
|
|
|
|
this->tabs[static_cast<int>(timeGetTime() % 1000) / 250]->Move(6, 5);
|
|
}
|
|
|
|
// OFFSET: 0x008AE8A0
|
|
// FUNCTION: fn_11741
|
|
void UILoginOTPWnd::OnCreate(int, int) {
|
|
const char prefixSource[] = {'\x8F', '\xC8', '\x2D', '\x7F', '\xC9', '\xF9', '\xFA', '\xB4', '\x89', '\x83', '\x2D', '\x49', '\xB4', '\x8D', '\x63', '\x79'};
|
|
thread_local EncryptedName<sizeof(prefixSource), 0x793F370985ED674FULL> prefixName(prefixSource);
|
|
const std::string prefix(prefixName.Text());
|
|
|
|
this->authCodeEdit = new UIEditCtrl();
|
|
this->authCodeEdit->SetSize(80, 16);
|
|
this->authCodeEdit->maximum = 8;
|
|
this->authCodeEdit->Move(99, 95);
|
|
this->authCodeEdit->mask = '*';
|
|
this->authCodeEdit->Background(243, 243, 243);
|
|
this->AddChild(this->authCodeEdit);
|
|
this->authCodeEdit->SetText("");
|
|
g_windowMgr.SetFocus(this->authCodeEdit);
|
|
|
|
UIStaticText* label = new UIStaticText();
|
|
label->SetSize(80, 20);
|
|
label->Move(141 - this->TextWidth(LookupMessage(MSI_ID), 0, 0, 12, 0, 0), 67);
|
|
label->SetText(LookupMessage(MSI_ID), 0);
|
|
this->AddChild(label);
|
|
|
|
this->timerText = new UIStaticText();
|
|
this->timerText->SetSize(80, 20);
|
|
this->timerText->Move(150, 66);
|
|
this->timerText->SetText(LookupMessage(MSI_ID), 0);
|
|
this->timerText->SetFont(0, 14, 1, 0);
|
|
this->timerText->SetColor(205, 19, 41);
|
|
this->AddChild(this->timerText);
|
|
|
|
label = new UIStaticText();
|
|
label->SetSize(200, 40);
|
|
label->SetText(LookupMessage(MSI_JOBNAME_TAEKWON), 0);
|
|
label->Move(static_cast<int>(141.0f - this->TextWidth(LookupMessage(MSI_JOBNAME_TAEKWON), 0, 0, 12, 0, 0) * 0.5f), 28);
|
|
this->AddChild(label);
|
|
|
|
label = new UIStaticText();
|
|
label->SetSize(200, 40);
|
|
label->SetText(LookupMessage(MSI_TO_BLOCK_WHISPER), 0);
|
|
label->Move(static_cast<int>(141.0f - this->TextWidth(LookupMessage(MSI_TO_BLOCK_WHISPER), 0, 0, 12, 0, 0) * 0.5f), 42);
|
|
this->AddChild(label);
|
|
|
|
label = new UIStaticText();
|
|
label->SetSize(80, 20);
|
|
label->Move(74 - this->TextWidth(LookupMessage(MSI_SERVER_PROPERTY_ADULT_NO_COUNT), 0, 0, 12, 0, 0), 98);
|
|
label->SetText(LookupMessage(MSI_SERVER_PROPERTY_ADULT_NO_COUNT), 0);
|
|
label->SetFont(0, 12, 1, 0);
|
|
label->SetColor(64, 64, 64);
|
|
this->AddChild(label);
|
|
|
|
UIBmpTextButton* button = new UIBmpTextButton();
|
|
const char normalSource[] = {'\xDD', '\xAA', '\x53', '\xD3', '\xB1', '\xED', '\x92', '\x28', '\xDB', '\xE1', '\x53', '\xE5', '\xCC', '\x99', '\x0B', '\x89', '\x72',
|
|
'\x62', '\xFA', '\x47', '\x2E', '\x4A', '\x39', '\x91', '\x78', '\x77', '\xF5', '\x48', '\x12', '\x46', '\x0B', '\x87', '\x69', '\x5A',
|
|
'\xFC', '\x5D', '\x01', '\x7C', '\x39', '\x8A', '\x6F', '\x68', '\xF2', '\x45', '\x5F', '\x41', '\x3A', '\x95', '\x1D'};
|
|
thread_local EncryptedName<sizeof(normalSource), 0xE55723712993051DULL> normalName(normalSource);
|
|
button->SetBitmap(normalName.Text(), 0, 0);
|
|
const char hoverSource[] = {'\xE3', '\x5E', '\x17', '\xED', '\x17', '\x87', '\x26', '\xB0', '\xE5', '\x15', '\x17', '\xDB', '\x6A', '\xF3', '\xBF', '\x11',
|
|
'\x4C', '\x96', '\xBE', '\x79', '\x88', '\x20', '\x8D', '\x09', '\x46', '\x83', '\xB1', '\x76', '\xB4', '\x2C', '\xBF', '\x1F',
|
|
'\x57', '\xAE', '\xB8', '\x63', '\xA7', '\x16', '\x8C', '\x0B', '\x46', '\x83', '\xF9', '\x75', '\xBA', '\x39', '\xE3'};
|
|
thread_local EncryptedName<sizeof(hoverSource), 0x7DE349D717D7F123ULL> hoverName(hoverSource);
|
|
button->SetBitmap(hoverName.Text(), 1, 0);
|
|
const char pressedSource[] = {'\xBF', '\x7A', '\x6F', '\xA1', '\xAB', '\x7F', '\xD0', '\xC2', '\xB9', '\x31', '\x6F', '\x97', '\xD6', '\x0B', '\x49', '\x63',
|
|
'\x10', '\xB2', '\xC6', '\x35', '\x34', '\xD8', '\x7B', '\x7B', '\x1A', '\xA7', '\xC9', '\x3A', '\x08', '\xD4', '\x49', '\x6D',
|
|
'\x0B', '\x8A', '\xC0', '\x2F', '\x1B', '\xEE', '\x65', '\x7D', '\x1A', '\xA6', '\xDC', '\x75', '\x09', '\xDC', '\x65', '\x0F'};
|
|
thread_local EncryptedName<sizeof(pressedSource), 0x0F15B16B5BAFD57FULL> pressedName(pressedSource);
|
|
button->SetBitmap(pressedName.Text(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight());
|
|
button->Move(186, 92);
|
|
button->SetId(382);
|
|
{
|
|
const std::string text(LookupMessage(MSI_PRIVATE_AIRPLANE_WARNNING_SELECT_NPC));
|
|
button->text = text;
|
|
button->Invalidate();
|
|
}
|
|
button->AddTextStyle(0, 12, 0x313131, 1, 1, -1000, -1000);
|
|
button->AddTextStyle(1, 12, 0x313131, 1, 1, -1000, -1000);
|
|
button->AddTextStyle(2, 12, 0x313131, 1, 1, -1000, -1000);
|
|
this->AddChild(button);
|
|
this->m_message0 = 382;
|
|
}
|
|
|
|
// OFFSET: 0x008B84B0
|
|
// FUNCTION: fn_11764
|
|
void UILoginOTPWnd::Paint() {
|
|
auto& resources = ResourceMgr::Instance();
|
|
constexpr auto sourceText = CRYPT_NAME("유저인터페이스\\login_interface\\bg_newotp1.bmp", 0x2FEB8739E5975BD1ULL);
|
|
const auto& source = sourceText.data;
|
|
thread_local EncryptedName<sizeof(source), 0x2FEB8739E5975BD1ULL> name(source);
|
|
auto* background = static_cast<CBitmapRes*>(resources.Load(Resolve(name.Text())));
|
|
this->DrawBitmap(0, 0, background, false);
|
|
this->DrawTitleBar(true, LookupMessage(MSI_PARTY_DO_YOU_WANT_BREAKING_UP), 280);
|
|
}
|
|
|
|
// OFFSET: 0x008C3620
|
|
// FUNCTION: fn_11826
|
|
void UILoginWnd::StoreInfo() {
|
|
this->SaveLogin();
|
|
}
|
|
|
|
// OFFSET: 0x008C39E0
|
|
// FUNCTION: fn_11831
|
|
void UILoginWnd::SaveLogin() {
|
|
HKEY key;
|
|
DWORD disposition = 0;
|
|
|
|
if (RegCreateKeyExA(HKEY_LOCAL_MACHINE, g_subKey, 0, nullptr, 0, KEY_ALL_ACCESS, nullptr, &key, &disposition) != ERROR_SUCCESS) {
|
|
return;
|
|
}
|
|
|
|
char id[52];
|
|
int saveId;
|
|
|
|
if (this->saveId != 0) {
|
|
std::strcpy(id, this->idEdit->Text());
|
|
saveId = this->saveId != 0;
|
|
id[50] = 0;
|
|
} else {
|
|
std::memset(id, 0, sizeof(id));
|
|
saveId = 0;
|
|
}
|
|
|
|
const char idSource[] = {'\x24', '\xFF', '\x95'};
|
|
thread_local EncryptedName<sizeof(idSource), 0xC517FB932D95BB6DULL> idName(idSource);
|
|
RegSetValueExA(key, idName.Text(), 0, REG_SZ, reinterpret_cast<const BYTE*>(id), 51);
|
|
|
|
const char checkSource[] = {'\xE6', '\xD5', '\x28', '\xBA', '\x28', '\x74', '\x36', '\x55', '\xE0', '\x9D'};
|
|
thread_local EncryptedName<sizeof(checkSource), 0x03772763F96D9DA5ULL> checkName(checkSource);
|
|
RegSetValueExA(key, checkName.Text(), 0, REG_DWORD, reinterpret_cast<const BYTE*>(&saveId), 4);
|
|
|
|
int bitwise = 1;
|
|
const char bitwiseSource[] = {'\xC5', '\x5A', '\x3F', '\x28', '\x70', '\x5A', '\x34', '\x0B'};
|
|
thread_local EncryptedName<sizeof(bitwiseSource), 0x0B7109397F6B1387ULL> bitwiseName(bitwiseSource);
|
|
RegSetValueExA(key, bitwiseName.Text(), 0, REG_DWORD, reinterpret_cast<const BYTE*>(&bitwise), 4);
|
|
RegCloseKey(key);
|
|
}
|
|
|
|
// OFFSET: 0x008C1F00
|
|
// FUNCTION: fn_11819
|
|
void UIReplayRECControlWnd::ApplyMode() {
|
|
this->Resize(194, 34);
|
|
|
|
if (this->mode == 0) {
|
|
this->recordStopButton->Move(-100, -100);
|
|
|
|
for (int index = 0; index < 5; ++index) {
|
|
this->tabs[index]->Move(-100, -100);
|
|
}
|
|
|
|
this->confirmFilenameButton->Move(-100, -100);
|
|
this->filenameEdit->Move(-100, -100);
|
|
this->button_00D0->Move(-100, -100);
|
|
this->optionsTitleText->Move(-100, -100);
|
|
|
|
for (int index = 0; index < 10; ++index) {
|
|
this->options[index]->Move(-100, -100);
|
|
}
|
|
|
|
this->userFilenameCheckBox->Move(-100, -100);
|
|
this->rejectExistingNameCheckBox->Move(-100, -100);
|
|
this->filenameEdit->Move(-100, -100);
|
|
this->recordStartButton->Move(110, 5);
|
|
this->button_00C8->Move(136, 5);
|
|
this->button_00C8->SetDisabled(0);
|
|
this->button_00C8->Invalidate();
|
|
this->button_00D0->Move(162, 5);
|
|
this->button_00D0->SetDisabled(0);
|
|
this->button_00D0->Invalidate();
|
|
this->recordTimeText->Move(32, 12);
|
|
this->tabs[0]->Move(6, 5);
|
|
} else if (this->mode == 1) {
|
|
this->recordStart = timeGetTime();
|
|
this->recordStartButton->Move(-100, -100);
|
|
|
|
for (int index = 0; index < 4; ++index) {
|
|
this->tabs[index]->Move(-100, -100);
|
|
}
|
|
|
|
this->tabs[4]->Move(-100, -100);
|
|
this->closeOptionsButton->Move(-100, -100);
|
|
this->options[7]->Move(-100, -100);
|
|
|
|
for (int index = 0; index < 10; ++index) {
|
|
this->options[index]->Move(-100, -100);
|
|
}
|
|
|
|
this->userFilenameCheckBox->Move(-100, -100);
|
|
this->rejectExistingNameCheckBox->Move(-100, -100);
|
|
this->confirmFilenameButton->Move(-100, -100);
|
|
this->filenameEdit->Move(-100, -100);
|
|
this->recordStopButton->Move(110, 5);
|
|
this->button_00C8->Move(136, 5);
|
|
this->button_00C8->SetDisabled(1);
|
|
this->button_00C8->Invalidate();
|
|
this->button_00D0->Move(162, 5);
|
|
this->button_00D0->SetDisabled(1);
|
|
this->button_00D0->Invalidate();
|
|
this->recordTimeText->Move(32, 12);
|
|
this->tabs[0]->Move(6, 5);
|
|
} else if (this->mode == 2) {
|
|
this->Resize(194, 200);
|
|
this->recordStartButton->Move(-100, -100);
|
|
this->recordStopButton->Move(-100, -100);
|
|
this->button_00C8->Move(-100, -100);
|
|
this->button_00D0->Move(-100, -100);
|
|
this->recordTimeText->Move(-100, -100);
|
|
|
|
for (int index = 0; index < 4; ++index) {
|
|
this->tabs[index]->Move(-100, -100);
|
|
}
|
|
|
|
this->confirmFilenameButton->Move(-100, -100);
|
|
this->filenameEdit->Move(-100, -100);
|
|
this->tabs[4]->Move(6, 5);
|
|
this->closeOptionsButton->Move(162, 5);
|
|
this->optionsTitleText->Move(42, 12);
|
|
this->options[0]->Move(17, 63);
|
|
this->options[1]->Move(17, 81);
|
|
this->options[2]->Move(17, 99);
|
|
this->options[3]->Move(17, 117);
|
|
this->options[4]->Move(-100, -100);
|
|
this->options[5]->Move(104, 81);
|
|
this->options[6]->Move(104, 99);
|
|
this->options[7]->Move(104, 117);
|
|
this->options[9]->Move(104, 63);
|
|
this->userFilenameCheckBox->Move(17, 160);
|
|
this->rejectExistingNameCheckBox->Move(17, 178);
|
|
} else if (this->mode == 3) {
|
|
this->recordStartButton->Move(-100, -100);
|
|
this->recordStopButton->Move(-100, -100);
|
|
this->button_00C8->Move(-100, -100);
|
|
this->button_00D0->Move(-100, -100);
|
|
this->recordTimeText->Move(-100, -100);
|
|
|
|
for (int index = 0; index < 4; ++index) {
|
|
this->tabs[index]->Move(-100, -100);
|
|
}
|
|
|
|
this->tabs[4]->Move(-100, -100);
|
|
this->closeOptionsButton->Move(-100, -100);
|
|
this->options[7]->Move(-100, -100);
|
|
|
|
for (int index = 0; index < 10; ++index) {
|
|
this->options[index]->Move(-100, -100);
|
|
}
|
|
|
|
this->userFilenameCheckBox->Move(-100, -100);
|
|
this->rejectExistingNameCheckBox->Move(-100, -100);
|
|
this->confirmFilenameButton->Move(162, 5);
|
|
this->filenameEdit->Move(7, 8);
|
|
g_windowMgr.SetFocus(this->filenameEdit);
|
|
}
|
|
|
|
this->SendMsg(nullptr, UM_REFRESH, 0, 0, 0, 0);
|
|
}
|
|
|
|
// OFFSET: 0x008B9790
|
|
// FUNCTION: fn_11771
|
|
void UINoticeWnd::Paint() {
|
|
this->DrawTitleBar(false, "", 0);
|
|
|
|
if (this->geometry.height == 17) {
|
|
return;
|
|
}
|
|
|
|
const int leftTiles = (this->geometry.height - 38) / 8 + ((this->geometry.height - 38) % 8 != 0);
|
|
for (int index = 0, y = 17; index < leftTiles; ++index, y += 8) {
|
|
auto* left = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve("유저인터페이스\\basic_interface\\itemwin_left.bmp")));
|
|
this->DrawBitmap(0, y, left, false);
|
|
}
|
|
|
|
const int rightTiles = (this->geometry.height - 38) / 8 + ((this->geometry.height - 38) % 8 != 0);
|
|
for (int index = 0, y = 17; index < rightTiles; ++index, y += 8) {
|
|
auto* right = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve("유저인터페이스\\basic_interface\\itemwin_right.bmp")));
|
|
this->DrawBitmap(this->geometry.width - right->image.width, y, right, false);
|
|
}
|
|
|
|
unsigned red;
|
|
unsigned green;
|
|
unsigned blue;
|
|
SkinPaletteChannels(ResourceMgr::Instance(), 2, 2, red, green, blue);
|
|
this->FillRegion(20, 17, this->geometry.width - 40, this->geometry.height - 38, RGB(red, green, blue));
|
|
this->FillRegion(
|
|
20, (this->geometry.height - 38) / 32 * 32 + 17, this->geometry.width - 24, (this->geometry.height - 38) % 32, RGB(red, green, blue)
|
|
);
|
|
this->DrawButtonBar(2, 0, 1);
|
|
}
|
|
|
|
// OFFSET: 0x008BFC20
|
|
// FUNCTION: fn_11811
|
|
int UINoticeWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) {
|
|
switch (message) {
|
|
case UM_DEFPUSH:
|
|
this->SendMsg(nullptr, UM_COMMAND, ID_OK, 0, 0, 0);
|
|
return 0;
|
|
case UM_COMMAND:
|
|
switch (a) {
|
|
case ID_OK: {
|
|
g_soundMgr->PlayWave("버튼소리.wav", 0.0f, 0.0f, 0.0f, 250, 40, 1.0f, 0);
|
|
FILE* file = std::fopen("notice_read.txt", "wb");
|
|
const int index = this->m_index;
|
|
unsigned char position;
|
|
|
|
if (index <= 0 && this->m_scroll <= 255) {
|
|
position = static_cast<unsigned char>(this->m_scroll);
|
|
|
|
if (position == this->m_bottomPositions[index] - 19) {
|
|
position = 255;
|
|
} else if (position != 255) {
|
|
position = static_cast<unsigned char>(this->m_scroll + 19);
|
|
const int limit = this->m_bottomPositions[index] - 19;
|
|
|
|
if (this->m_scroll + 19 > limit) {
|
|
position = limit < 0 ? 0 : static_cast<unsigned char>(this->m_bottomPositions[index] - 19);
|
|
}
|
|
}
|
|
} else {
|
|
position = 255;
|
|
}
|
|
|
|
std::fwrite(&position, 1, 1, file);
|
|
std::fclose(file);
|
|
g_windowMgr.CloseWindow(WID_NOTICEWND);
|
|
break;
|
|
}
|
|
case ID_NEXT:
|
|
++this->m_index;
|
|
|
|
if (this->m_index > this->m_noticeCount) {
|
|
this->m_index = this->m_noticeCount;
|
|
return 0;
|
|
}
|
|
|
|
this->m_scroll = this->m_scrollPositions[this->m_index];
|
|
this->LoadNotice();
|
|
break;
|
|
case ID_PREV:
|
|
--this->m_index;
|
|
|
|
if (this->m_index < 0) {
|
|
this->m_index = 0;
|
|
return 0;
|
|
}
|
|
|
|
this->m_scroll = this->m_scrollPositions[this->m_index];
|
|
this->LoadNotice();
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
case UM_SCROLLVERT:
|
|
case UM_SCROLLVERTPAGEUP:
|
|
case UM_SCROLLVERTPAGEDOWN: {
|
|
const int previous = this->m_scroll;
|
|
std::intptr_t delta = a;
|
|
|
|
if (message == UM_SCROLLVERTPAGEUP) {
|
|
delta = -1;
|
|
} else if (message == UM_SCROLLVERTPAGEDOWN) {
|
|
delta = 1;
|
|
}
|
|
|
|
this->m_scroll = previous + delta;
|
|
|
|
if (this->m_scroll > this->m_bottomPositions[this->m_index] - 19) {
|
|
this->m_scroll = this->m_bottomPositions[this->m_index] - 19;
|
|
}
|
|
|
|
if (this->m_scroll < this->m_scrollPositions[this->m_index]) {
|
|
this->m_scroll = this->m_scrollPositions[this->m_index];
|
|
}
|
|
|
|
this->LoadNotice();
|
|
return this->m_scroll - previous;
|
|
}
|
|
default:
|
|
return UIFrameWnd::SendMsg(sender, message, a, b, c, d);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008BB070
|
|
// FUNCTION: fn_11793
|
|
void UINoticeWnd::OnWheel(int delta) {
|
|
if (delta < 0) {
|
|
this->SendMsg(this->m_scrollBar, UM_SCROLLVERT, 6, 0, 0, 0);
|
|
} else {
|
|
this->SendMsg(this->m_scrollBar, UM_SCROLLVERT, -6, 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008A8AD0
|
|
// FUNCTION: fn_11715
|
|
void UIPayConfirmWnd::Configure(const std::string& text, int itemId) {
|
|
reinterpret_cast<UIMessageBox*>(this)->Configure(text.c_str(), 2, 187, 0, LookupMessage(MSI_TITLE_QUEST_BOARD_INFO), 0xDC, 0x85, 1, nullptr);
|
|
|
|
this->viewer->Resize(0xA5, 0x50);
|
|
this->viewer->Move(7, 0x17);
|
|
this->viewer->SetBackgroundColor(0xFFFF00FF);
|
|
|
|
auto accept = std::find_if(this->m_children.begin(), this->m_children.end(), [](UIWindow* child) { return child->geometry.id == 187; });
|
|
if (accept != this->m_children.end()) {
|
|
(*accept)->Move(0x59, 0x6D);
|
|
}
|
|
|
|
auto cancel = std::find_if(this->m_children.begin(), this->m_children.end(), [](UIWindow* child) { return child->geometry.id == 188; });
|
|
if (cancel != this->m_children.end()) {
|
|
auto* button = static_cast<UIBitmapButton*>(*cancel);
|
|
button->SetBitmap("유저인터페이스\\basic_interface\\sys_close_off.bmp", 0, 0);
|
|
button->SetBitmap("유저인터페이스\\basic_interface\\sys_close_on.bmp", 1, 0);
|
|
button->SetBitmap("유저인터페이스\\basic_interface\\sys_close_on.bmp", 2, 0);
|
|
button->Resize(button->BitmapWidth(), button->BitmapHeight());
|
|
button->Move(this->geometry.width - 0xE, 3);
|
|
}
|
|
|
|
std::string resource(FindItemDescription(itemId).identifiedResource);
|
|
if (!resource.empty()) {
|
|
CBitmapRes* bitmap = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(std::format("유저인터페이스\\collection\\{}.bmp", resource)));
|
|
this->m_image = bitmap ? &bitmap->image : nullptr;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008B9940
|
|
// FUNCTION: fn_11772
|
|
void UIPayConfirmWnd::Paint() {
|
|
this->DrawTitleBar(true, this->m_title.c_str(), 0);
|
|
this->DrawPanelBackground(17, 0, "");
|
|
this->DrawButtonBar(2, 0, 1);
|
|
|
|
if (this->m_image) {
|
|
this->DrawBitmapScaled(158, 27, 56, 75, this->m_image, 0);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008B9E90
|
|
// FUNCTION: fn_11774
|
|
void UIReplayControlWnd::Paint() {
|
|
auto* background = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve("유저인터페이스\\replay_interface\\replay_base.bmp")));
|
|
this->DrawBitmap(0, 0, background, false);
|
|
}
|
|
|
|
// OFFSET: 0x008B9ED0
|
|
// FUNCTION: fn_11775
|
|
void UIReplayRECControlWnd::Paint() {
|
|
this->ClearSurface(0xFFFF00FF);
|
|
DrawFilledRoundedBorder(*this, 0, 0, this->geometry.width, 34, 0xF5B899);
|
|
DrawRoundedBorder(*this, 0, 0, this->geometry.width, 34, 0x945A63);
|
|
DrawRoundedBorder(*this, 1, 1, this->geometry.width - 2, 32, 0xF7C6AD);
|
|
DrawRoundedBorder(*this, 2, 2, this->geometry.width - 4, 30, 0xFFFFFF);
|
|
DrawRoundedBorder(*this, 3, 3, this->geometry.width - 6, 28, 0xAD7B84);
|
|
|
|
if (this->mode == 2) {
|
|
DrawFilledRoundedBorder(*this, 0, 34, this->geometry.width, this->geometry.height - 34, 0xDEDEDE);
|
|
DrawFilledRoundedBorder(*this, 4, 38, this->geometry.width - 8, 95, 0xFFFFFF);
|
|
DrawFilledRoundedBorder(*this, 4, 138, this->geometry.width - 8, 57, 0xFFFFFF);
|
|
DrawOutlinedText(*this, 10, 42, LookupMessage(MSI_REPLAY_SETREPLAYSAVEDATA), 0, 0x7F3C00, 0xFFFFFF, 0, 12, 1, 0);
|
|
DrawOutlinedText(*this, 10, 142, LookupMessage(MSI_REPLAY_SETRECOPTION), 0, 0x7F3C00, 0xFFFFFF, 0, 12, 1, 0);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008BA010
|
|
// FUNCTION: fn_11776
|
|
void UISelectReplayDataWnd::Paint() {
|
|
this->DrawTitleBar(true, LookupMessage(MSI_NOT_MOVEABLE_TRADE), 0);
|
|
this->DrawPanelBackground(17, 0, "");
|
|
this->DrawButtonBar(2, 0, 1);
|
|
this->FillRegion(6, 32, 268, 77, 0xFFE7E7E7);
|
|
this->DrawTextAt(6, 19, LookupMessage(MSI_GUILD_DISBAND), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(6, 112, LookupMessage(MSI_PUT_DISBAND_GUILDNAME), 0, 0, 12, 0, 0, 0);
|
|
}
|
|
|
|
// OFFSET: 0x008BA0B0
|
|
// FUNCTION: fn_11777
|
|
void UISelectServerWnd::Paint() {
|
|
const char* title = LookupMessage(MSI_REPLAY_STR_FILEINFO);
|
|
|
|
if (g_modeMgr.GetLoginMode()->cursorType == 30) {
|
|
title = LookupMessage(MSI_REPLAY_STR_FILELIST);
|
|
}
|
|
|
|
this->DrawTitleBar(true, title, 0);
|
|
this->DrawPanelBackground(17, 0, "");
|
|
this->DrawButtonBar(2, 0, 1);
|
|
}
|
|
|
|
// OFFSET: 0x008BA110
|
|
// FUNCTION: fn_11778
|
|
void UITalkboxTrapInputWnd::Paint() {
|
|
const int titleHeight = this->DrawTitleBar(false, "", 0);
|
|
this->DrawPanelBackground(titleHeight, 0, "");
|
|
this->DrawButtonBar(2, 0, 1);
|
|
this->DrawTextAt(17, 3, LookupMessage(MSI_TALKBOX_WINDOW), 0, 0, 12, 0xFFFFFF, 0, 0);
|
|
this->DrawTextAt(16, 2, LookupMessage(MSI_TALKBOX_WINDOW), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(17, 23, LookupMessage(MSI_TALKBOX_WINDOW_MSG), 0, 0, 12, 0xFFFFFF, 0, 0);
|
|
this->DrawTextAt(16, 22, LookupMessage(MSI_TALKBOX_WINDOW_MSG), 0, 0, 12, 0, 0, 0);
|
|
}
|
|
|
|
// OFFSET: 0x008BA660
|
|
// FUNCTION: fn_11787
|
|
void UILoginWnd::OnMouseMove(int, int) {
|
|
}
|
|
|
|
// OFFSET: 0x008BADB0
|
|
// FUNCTION: fn_11790
|
|
void UIMakeCharWnd::OnProcess() {
|
|
}
|
|
|
|
// OFFSET: 0x008AC490
|
|
// FUNCTION: fn_11733
|
|
void UIMakeCharWnd::InitHairControls() {
|
|
const std::string prefix("유저인터페이스\\");
|
|
const char* names[2][3] = {{"btn_ok", "btn_ok_a", "btn_ok_b"}, {"btn_cancel", "btn_cancel_a", "btn_cancel_b"}};
|
|
int positions[2][2] = {{57, 262}, {104, 262}};
|
|
const char* tooltips[2] = {"", ""};
|
|
int ids[2] = {184, 185};
|
|
|
|
for (int index = 0; index < 2; ++index) {
|
|
auto* button = new UIBitmapButton();
|
|
button->SetBitmap((prefix + names[index][0] + ".bmp").c_str(), 0, 0);
|
|
button->SetBitmap((prefix + names[index][1] + ".bmp").c_str(), 1, 0);
|
|
button->SetBitmap((prefix + names[index][2] + ".bmp").c_str(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight());
|
|
button->Move(positions[index][0], this->geometry.height - button->BitmapHeight() - 5);
|
|
button->SetId(ids[index]);
|
|
button->SetTooltip(tooltips[index]);
|
|
this->AddChild(button);
|
|
}
|
|
|
|
this->m_rotateLeftButton = new (std::nothrow) UIBitmapButton();
|
|
this->m_rotateLeftButton->SetBitmap("유저인터페이스\\scroll1left.bmp", 0, 0);
|
|
this->m_rotateLeftButton->SetBitmap("유저인터페이스\\scroll1left.bmp", 1, 0);
|
|
this->m_rotateLeftButton->SetBitmap("유저인터페이스\\scroll1left.bmp", 2, 0);
|
|
this->m_rotateLeftButton->SetSize(this->m_rotateLeftButton->BitmapWidth(), this->m_rotateLeftButton->BitmapHeight());
|
|
this->m_rotateLeftButton->Move(20, 80);
|
|
this->m_rotateLeftButton->SetId(227);
|
|
this->m_rotateLeftButton->SetTooltip(LookupMessage(MSI_VIEW_BEFORE_WORLDINFO_TITLE));
|
|
this->AddChild(this->m_rotateLeftButton);
|
|
|
|
this->m_rotateRightButton = new (std::nothrow) UIBitmapButton();
|
|
this->m_rotateRightButton->SetBitmap("유저인터페이스\\scroll1right.bmp", 0, 0);
|
|
this->m_rotateRightButton->SetBitmap("유저인터페이스\\scroll1right.bmp", 1, 0);
|
|
this->m_rotateRightButton->SetBitmap("유저인터페이스\\scroll1right.bmp", 2, 0);
|
|
this->m_rotateRightButton->SetSize(this->m_rotateLeftButton->BitmapWidth(), this->m_rotateLeftButton->BitmapHeight());
|
|
this->m_rotateRightButton->Move(110, 80);
|
|
this->m_rotateRightButton->SetId(226);
|
|
this->m_rotateRightButton->SetTooltip(LookupMessage(MSI_VIEW_BEFORE_SERVERINFO));
|
|
this->AddChild(this->m_rotateRightButton);
|
|
|
|
this->m_hairStyle = this->m_info.head - 1;
|
|
if (this->m_hairStyle < 0) {
|
|
this->m_hairStyle = 0;
|
|
}
|
|
this->m_hairColor = this->m_view.headPalette >= 0 ? this->m_view.headPalette : 0;
|
|
|
|
this->m_hairStyleBar = new UIScrollBar();
|
|
this->m_hairStyleBar->Configure(10, 190, 0, 130);
|
|
this->AddChild(this->m_hairStyleBar);
|
|
|
|
this->m_hairColorBar = new UIScrollBar();
|
|
this->m_hairColorBar->Configure(10, 230, 0, 130);
|
|
this->AddChild(this->m_hairColorBar);
|
|
|
|
if (this->m_hairStyleBar) {
|
|
this->m_hairStyleBar->SetRange(22, 1, 23);
|
|
this->m_hairStyleBar->Invalidate();
|
|
}
|
|
if (this->m_hairColorBar) {
|
|
this->m_hairColorBar->SetRange(8, 1, 9);
|
|
this->m_hairColorBar->Invalidate();
|
|
}
|
|
this->m_hairStyleBar->SetPosition(this->m_hairStyle);
|
|
this->m_hairColorBar->SetPosition(this->m_hairColor);
|
|
}
|
|
|
|
// OFFSET: 0x008B0B60
|
|
// FUNCTION: fn_11743
|
|
void UIMakeCharWnd::OnCreate(int, int) {
|
|
g_modeMgr.gameMode->SendMsg(LMM_GET_MAKING_CHAR_NAME, 0, 0, 0, 0);
|
|
this->m_nameEdit = new UIBitmapEditCtrl;
|
|
this->m_nameEdit->SetBitmapName("유저인터페이스\\login_interface\\name-edit.bmp");
|
|
this->m_nameEdit->SetSize(this->m_nameEdit->geometry.width, this->m_nameEdit->geometry.height);
|
|
this->m_nameEdit->Move(40, 142);
|
|
this->m_nameEdit->maximum = 24;
|
|
this->m_nameEdit->SetId(184);
|
|
this->AddChild(this->m_nameEdit);
|
|
this->InitHairControls();
|
|
g_windowMgr.SetFocus(this->m_nameEdit);
|
|
this->m_message0 = 184;
|
|
}
|
|
|
|
// OFFSET: 0x008AD130
|
|
// FUNCTION: fn_11734
|
|
void UIChatRoomWnd::Move(int x, int y) {
|
|
this->geometry.Move(x, y);
|
|
this->RefreshSnap();
|
|
}
|
|
|
|
// OFFSET: 0x008AD3C0
|
|
// FUNCTION: fn_11738
|
|
void UIChatRoomWnd::OnCreate(int, int) {
|
|
this->m_message0 = 184;
|
|
|
|
this->resizer = new UIResizer();
|
|
this->resizer->SetSize(16, 16);
|
|
this->resizer->SetDirection(7);
|
|
this->resizer->SetBitmapName("유저인터페이스\\btn_resize.bmp");
|
|
this->resizer->Move(this->geometry.width - 15, this->geometry.height - 15);
|
|
this->resizer->SetColors(0xFFFF00FF, 0xFFFF00FF);
|
|
this->AddChild(this->resizer);
|
|
|
|
this->edit = new UIChatEditCtrl();
|
|
this->edit->SetSize(this->geometry.width - 30, 16);
|
|
this->edit->Move(3, this->geometry.height - 18);
|
|
this->edit->maximum = 70;
|
|
this->edit->Background(242, 242, 242);
|
|
this->AddChild(this->edit);
|
|
g_windowMgr.SetFocus(this->edit);
|
|
this->edit->SetId(494);
|
|
|
|
UIChatHisBox2* history = new UIChatHisBox2();
|
|
this->history = history;
|
|
history->Configure(0, 0, this->geometry.width - this->geometry.width * 56 / 280 - 3, this->geometry.height - 38, 0);
|
|
this->history->Move(1, 17);
|
|
this->history->SetId(184);
|
|
this->AddChild(this->history);
|
|
|
|
this->memberList = new UIMemberListBox();
|
|
this->memberList->Configure(0, 0, this->geometry.width * 56 / 280, this->geometry.height - 38, 0);
|
|
this->memberList->Move(this->geometry.width - this->geometry.width * 56 / 280 - 1, 17);
|
|
this->memberList->SetId(184);
|
|
this->AddChild(this->memberList);
|
|
|
|
this->closeButton = this->AddCloseButton("/q", 0);
|
|
|
|
this->titleText = new UIStaticText();
|
|
this->titleText->SetSize(this->geometry.width - 30, 15);
|
|
this->titleText->Move(9, 2);
|
|
this->titleText->SetTextFitted("");
|
|
this->titleText->SetFont(0, 12, 0, 0);
|
|
this->AddChild(this->titleText);
|
|
}
|
|
|
|
// OFFSET: 0x008B1760
|
|
// FUNCTION: fn_11746
|
|
void UINoticeWnd::OnCreate(int, int) {
|
|
const std::string prefix("유저인터페이스\\");
|
|
const char* names[3][3] = {{"btn_ok", "btn_ok_a", "btn_ok_b"}, {"btn_back", "btn_back_a", "btn_back_b"}, {"btn_next", "btn_next_a", "btn_next_b"}};
|
|
int ids[3] = {184, 246, 218};
|
|
int positions[3][2] = {{534, 376}, {244, 376}, {294, 376}};
|
|
|
|
for (int index = 0; index < 3; ++index) {
|
|
auto* button = new UIBitmapButton();
|
|
button->SetBitmap((prefix + names[index][0] + ".bmp").c_str(), 0, 0);
|
|
button->SetBitmap((prefix + names[index][1] + ".bmp").c_str(), 1, 0);
|
|
button->SetBitmap((prefix + names[index][2] + ".bmp").c_str(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight());
|
|
button->Move(positions[index][0], positions[index][1]);
|
|
button->SetId(ids[index]);
|
|
this->AddChild(button);
|
|
}
|
|
|
|
this->m_message0 = 184;
|
|
|
|
if (!std::fopen(this->m_patchFile, "r")) {
|
|
FILE* file = std::fopen(this->m_patchFile, "w");
|
|
std::fwrite("공지사항파일없음", 16, 1, file);
|
|
std::fclose(file);
|
|
g_windowMgr.Schedule(this);
|
|
}
|
|
|
|
if (!std::fopen("notice_check.txt", "r")) {
|
|
FILE* file = std::fopen("notice_check.txt", "w");
|
|
std::fwrite("없으니만들자", 12, 1, file);
|
|
std::fclose(file);
|
|
}
|
|
|
|
unsigned char flag;
|
|
if (!std::fopen("notice_read.txt", "r")) {
|
|
FILE* file = std::fopen("notice_read.txt", "wb");
|
|
flag = 0;
|
|
std::fwrite(&flag, 1, 1, file);
|
|
std::fclose(file);
|
|
}
|
|
|
|
FILE* patch = std::fopen(this->m_patchFile, "r");
|
|
FILE* check = std::fopen("notice_check.txt", "r");
|
|
std::fseek(patch, 0, SEEK_END);
|
|
const int patchSize = std::ftell(patch);
|
|
std::fseek(check, 0, SEEK_END);
|
|
const int checkSize = std::ftell(check);
|
|
int changed = checkSize == 0 ? 1000 : 0;
|
|
char* patchText = new char[patchSize + 1];
|
|
char* checkText = new char[checkSize + 1];
|
|
std::fseek(patch, 0, SEEK_SET);
|
|
std::fread(patchText, patchSize, 1, patch);
|
|
patchText[patchSize] = 0;
|
|
std::fclose(patch);
|
|
std::fseek(check, 0, SEEK_SET);
|
|
std::fread(checkText, checkSize, 1, check);
|
|
checkText[checkSize] = 0;
|
|
std::fclose(check);
|
|
|
|
int lines[20];
|
|
lines[0] = 0;
|
|
int lineCount = 1;
|
|
this->lineCount = 0;
|
|
for (int i = 0; i < patchSize; ++i) {
|
|
const char c = patchText[i];
|
|
if (c == '\n') {
|
|
patchText[i] = 0;
|
|
lines[lineCount] = i + 1;
|
|
++lineCount;
|
|
if (lineCount > 20) {
|
|
lineCount = 20;
|
|
}
|
|
++this->lineCount;
|
|
} else if (c == '\r') {
|
|
patchText[i] = 0;
|
|
} else if (c == '^') {
|
|
const int previous = lineCount - 1;
|
|
this->m_bottomPositions[this->m_noticeCount] = this->lineCount - 1;
|
|
++this->m_noticeCount;
|
|
this->m_scrollPositions[this->m_noticeCount] = this->lineCount + 1;
|
|
lineCount = previous < 0 ? 0 : previous;
|
|
} else if (i < checkSize && static_cast<unsigned int>(i) < 1000 && c != checkText[i]) {
|
|
++changed;
|
|
}
|
|
}
|
|
|
|
if (lineCount > 19) {
|
|
lineCount = 19;
|
|
}
|
|
|
|
this->m_bottomPositions[this->m_noticeCount] = this->lineCount;
|
|
|
|
if (changed == 0) {
|
|
FILE* file = std::fopen("notice_read.txt", "rb");
|
|
std::fread(&flag, 1, 1, file);
|
|
std::fclose(file);
|
|
if (flag == 0xFF) {
|
|
g_windowMgr.Schedule(this);
|
|
}
|
|
} else {
|
|
FILE* file = std::fopen("notice_read.txt", "wb");
|
|
flag = 0;
|
|
std::fwrite(&flag, 1, 1, file);
|
|
std::fclose(file);
|
|
}
|
|
|
|
for (int i = 0, y = 22; y < 364; ++i, y += 18) {
|
|
this->m_texts[i]->SetSize(540, 16);
|
|
this->m_texts[i]->SetFont(0, 16, 0, 0);
|
|
if (i < lineCount) {
|
|
this->m_texts[i]->SetText(patchText + lines[i], 1);
|
|
} else {
|
|
this->m_texts[i]->SetText("", 1);
|
|
}
|
|
this->m_texts[i]->Move(30, y);
|
|
this->AddChild(this->m_texts[i]);
|
|
}
|
|
|
|
this->m_scrollBar = new UIScrollBar();
|
|
static_cast<UIScrollBar*>(this->m_scrollBar)->Configure(583, 18, 1, this->geometry.height - 48);
|
|
const int total = this->m_bottomPositions[this->m_index] - this->m_scrollPositions[this->m_index];
|
|
static_cast<UIScrollBar*>(this->m_scrollBar)->SetRange(total - 19, 19, total);
|
|
if (this->m_bottomPositions[this->m_index] - this->m_scrollPositions[this->m_index] < 19) {
|
|
static_cast<UIScrollBar*>(this->m_scrollBar)->SetRange(0, 19, 19);
|
|
}
|
|
static_cast<UIScrollBar*>(this->m_scrollBar)->SetPosition(this->m_scroll);
|
|
this->AddChild(this->m_scrollBar);
|
|
|
|
FILE* source = std::fopen(this->m_patchFile, "r");
|
|
FILE* target = std::fopen("notice_check.txt", "w");
|
|
std::fseek(source, 0, SEEK_END);
|
|
std::fseek(target, 0, SEEK_END);
|
|
const int size = std::ftell(source);
|
|
char* copy = new char[size + 1];
|
|
std::fseek(source, 0, SEEK_SET);
|
|
std::fread(copy, size, 1, source);
|
|
copy[size] = 0;
|
|
std::fclose(source);
|
|
for (int i = 0; i < size; ++i) {
|
|
std::fwrite(©[i], 1, 1, target);
|
|
}
|
|
std::fclose(target);
|
|
|
|
if (changed == 0) {
|
|
FILE* file = std::fopen("notice_read.txt", "rb");
|
|
std::fread(&flag, 1, 1, file);
|
|
std::fclose(file);
|
|
if (flag != 0xFF) {
|
|
this->m_scroll = flag;
|
|
}
|
|
if (this->m_scroll > this->m_bottomPositions[this->m_index] - 19) {
|
|
this->m_scroll = this->m_bottomPositions[this->m_index] - 19;
|
|
}
|
|
if (this->m_scroll < 0) {
|
|
this->m_scroll = 0;
|
|
}
|
|
this->LoadNotice();
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008B42D0
|
|
// FUNCTION: fn_11749
|
|
void UIReplayRECControlWnd::OnCreate(int, int) {
|
|
const std::string prefix("유저인터페이스\\replay_interface\\");
|
|
const char* names[11] = {
|
|
"btn_start_", "btn_stop_", "btn_start_", "btn_save_", "btn_setup_", "btn_close_",
|
|
"replay_recrun_1", "replay_recrun_2", "replay_recrun_3", "replay_recrun_4", "replay_recrun_5",
|
|
};
|
|
const char* tooltips[16] = {
|
|
LookupMessage(MSI_REPLAY_START), LookupMessage(MSI_REPLAY_STOP), LookupMessage(MSI_REPLAY_START2), LookupMessage(MSI_REPLAY_OPENOPTION), LookupMessage(MSI_REPLAY_CLOSEOPION), LookupMessage(MSI_REPLAY_END),
|
|
LookupMessage(MSI_REPLAY_TIME), LookupMessage(MSI_CHARACTER_INFO), LookupMessage(MSI_EQUIPED_ITEM), LookupMessage(MSI_ITEM), LookupMessage(MSI_SKILLLIST), LookupMessage(MSI_REPLAY_PARTYFRIEND),
|
|
LookupMessage(MSI_REPLAY_CHAT), LookupMessage(MSI_REPLAY_SHORTCUTS), LookupMessage(MSI_REPLAY_AUTOMATICFILENAME), LookupMessage(MSI_REPLAY_CHECKINGFILE),
|
|
};
|
|
int ids[6] = {420, 421, 422, 423, 424, 425};
|
|
|
|
for (int index = 0; index < 2; ++index) {
|
|
this->buttons[index] = new UIReplayButton();
|
|
this->buttons[index]->SetBitmap((prefix + names[index] + "a.bmp").c_str(), 0, 0);
|
|
this->buttons[index]->SetBitmap((prefix + names[index] + "a.bmp").c_str(), 1, 0);
|
|
this->buttons[index]->SetBitmap((prefix + names[index] + "b.bmp").c_str(), 2, 0);
|
|
this->buttons[index]->SetSize(this->buttons[index]->BitmapWidth(), this->buttons[index]->BitmapHeight());
|
|
this->buttons[index]->Move(-100, -100);
|
|
this->buttons[index]->SetId(ids[index]);
|
|
this->buttons[index]->SetTooltip(tooltips[index]);
|
|
this->AddChild(this->buttons[index]);
|
|
}
|
|
|
|
for (int index = 2; index < 6; ++index) {
|
|
this->buttons[index] = new UIBitmapButton();
|
|
this->buttons[index]->SetBitmap((prefix + names[index] + "a.bmp").c_str(), 0, 0);
|
|
this->buttons[index]->SetBitmap((prefix + names[index] + "a.bmp").c_str(), 1, 0);
|
|
this->buttons[index]->SetBitmap((prefix + names[index] + "b.bmp").c_str(), 2, 0);
|
|
this->buttons[index]->SetSize(this->buttons[index]->BitmapWidth(), this->buttons[index]->BitmapHeight());
|
|
this->buttons[index]->Move(-100, -100);
|
|
this->buttons[index]->SetId(ids[index]);
|
|
this->buttons[index]->SetTooltip(tooltips[index]);
|
|
this->AddChild(this->buttons[index]);
|
|
}
|
|
|
|
for (int index = 0; index < 5; ++index) {
|
|
this->tabs[index] = new UIStaticBitmap();
|
|
static_cast<UIStaticBitmap*>(this->tabs[index])->SetBitmap((prefix + names[index + 6] + ".bmp").c_str());
|
|
this->tabs[index]->SetSize(this->tabs[index]->geometry.width, this->tabs[index]->geometry.height);
|
|
this->tabs[index]->Move(-100, -100);
|
|
this->tabs[index]->SetId(reinterpret_cast<int>(tooltips[index]));
|
|
this->AddChild(this->tabs[index]);
|
|
}
|
|
|
|
int textSizes[2][2] = {{50, 12}, {80, 12}};
|
|
const char* labels[2] = {"000:00:00", LookupMessage(MSI_REPLAY_REPLAYOPTIONSETTING)};
|
|
for (int index = 0; index < 2; ++index) {
|
|
this->texts[index] = new UIStaticText();
|
|
this->texts[index]->SetSize(textSizes[index][0], textSizes[index][1]);
|
|
this->texts[index]->SetText(labels[index], 0);
|
|
this->texts[index]->Move(-100, -100);
|
|
this->texts[index]->SetColor(255, 255, 255);
|
|
this->AddChild(this->texts[index]);
|
|
}
|
|
|
|
std::memcpy(this->recordOptions, &Replay::Instance().header.options, sizeof(this->recordOptions));
|
|
const char* optionNames[12] = {
|
|
"Basicinfo", "Equip", "Item", "Skill", "Guild", "Party", "Chatting", "Shortcut", "Status", "ALL", "User Defined File Name", "Repeated File Check",
|
|
};
|
|
for (int index = 0; index < 10; ++index) {
|
|
this->options[index] = new UICheckBox();
|
|
this->options[index]->SetSize(70, 12);
|
|
static_cast<UICheckBox*>(this->options[index])->SetImages("유저인터페이스\\checkbox_1.bmp", "유저인터페이스\\checkbox_0.bmp", optionNames[index]);
|
|
this->options[index]->Move(-100, -100);
|
|
static_cast<UICheckBox*>(this->options[index])->SetChecked(Replay::Instance().header.options.Get(static_cast<ReplayRecordOption>(index)));
|
|
this->AddChild(this->options[index]);
|
|
}
|
|
|
|
for (int index = 0; index < 2; ++index) {
|
|
this->fileOptions[index] = new UICheckBox();
|
|
this->fileOptions[index]->SetSize(150, 12);
|
|
this->fileOptions[index]->SetImages("유저인터페이스\\checkbox_1.bmp", "유저인터페이스\\checkbox_0.bmp", optionNames[index + 10]);
|
|
this->fileOptions[index]->Move(-100, -100);
|
|
this->fileOptions[index]->SetChecked(0);
|
|
this->AddChild(this->fileOptions[index]);
|
|
}
|
|
|
|
const bool pathEnabled = ReplayFileList::Instance().pathEnabled;
|
|
this->fileOptions[0]->SetChecked(pathEnabled);
|
|
this->replayPathEnabled = pathEnabled;
|
|
const bool option119 = ReplayFileList::Instance().rejectExistingName;
|
|
this->fileOptions[1]->SetChecked(option119);
|
|
this->replayOption119 = option119;
|
|
|
|
this->filenameEdit = new UIEditCtrl();
|
|
this->filenameEdit->SetSize(151, 18);
|
|
this->filenameEdit->Move(-100, -100);
|
|
this->filenameEdit->maximum = 80;
|
|
this->filenameEdit->Background(232, 232, 232);
|
|
this->filenameEdit->SetText("");
|
|
std::string& tooltip = this->filenameEdit->tooltip;
|
|
if (const char* text = LookupMessage(MSI_REPLAY_ENTERTHEFILENAME)) {
|
|
tooltip = text;
|
|
}
|
|
this->AddChild(this->filenameEdit);
|
|
this->filenameEdit->SelectAll();
|
|
this->ApplyMode();
|
|
this->Invalidate();
|
|
}
|
|
|
|
// OFFSET: 0x008B5A50
|
|
// FUNCTION: fn_11750
|
|
void UISelectReplayDataWnd::OnCreate(int width, int height) {
|
|
this->m_list = new UIReplayListBox();
|
|
this->m_list->Configure(6, 127, width - 12, height - 170, 0);
|
|
this->m_list->backgroundRed = 240;
|
|
this->m_list->backgroundGreen = 240;
|
|
this->m_list->backgroundBlue = 240;
|
|
this->m_list->SetId(184);
|
|
this->AddChild(this->m_list);
|
|
|
|
const std::string prefix("유저인터페이스\\");
|
|
const char* names[4][3] = {
|
|
{"btn_ok", "btn_ok_a", "btn_ok_b"},
|
|
{"btn_cancel", "btn_cancel_a", "btn_cancel_b"},
|
|
{"login_interface\\btn_exit", "login_interface\\btn_exit_a", "login_interface\\btn_exit_b"},
|
|
{"replay_interface\\btn_selectserver", "replay_interface\\btn_selectserver_a", "replay_interface\\btn_selectserver_b"},
|
|
};
|
|
int ids[4] = {184, 185, 221, 400};
|
|
int positions[4][2] = {{189, height - 25}, {-100, -100}, {234, height - 25}, {100, height - 25}};
|
|
|
|
std::string name;
|
|
for (int index = 0; index < 4; ++index) {
|
|
auto* button = new UIBitmapButton();
|
|
name.assign(prefix);
|
|
name += names[index][0];
|
|
name += ".bmp";
|
|
button->SetBitmap(name.c_str(), 0, 0);
|
|
name.assign(prefix);
|
|
name += names[index][1];
|
|
name += ".bmp";
|
|
button->SetBitmap(name.c_str(), 1, 0);
|
|
name.assign(prefix);
|
|
name += names[index][2];
|
|
name += ".bmp";
|
|
button->SetBitmap(name.c_str(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight());
|
|
button->Move(positions[index][0], positions[index][1]);
|
|
button->SetId(ids[index]);
|
|
this->AddChild(button);
|
|
if (ids[index] == 221) {
|
|
this->m_serverButton = button;
|
|
}
|
|
}
|
|
|
|
this->m_message0 = 184;
|
|
|
|
UIStaticText** text = this->m_texts;
|
|
for (int y = 35; y < 110; y += 15) {
|
|
*text = new UIStaticText();
|
|
(*text)->SetSize(width - 12, 15);
|
|
(*text)->SetText("", 0);
|
|
(*text)->Move(12, y);
|
|
(*text)->SetColor(100, 100, 200);
|
|
this->AddChild(*text);
|
|
++text;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008B7040
|
|
// FUNCTION: fn_11752
|
|
void UITalkboxTrapInputWnd::OnCreate(int, int) {
|
|
this->edit = new UIEditCtrl();
|
|
this->edit->SetSize(240, 16);
|
|
this->edit->Move(22, 50);
|
|
this->edit->maximum = 78;
|
|
this->edit->Background(242, 242, 242);
|
|
this->AddChild(this->edit);
|
|
g_windowMgr.SetFocus(this->edit);
|
|
|
|
const std::string prefix("유저인터페이스\\");
|
|
const char* names[2][3] = {{"btn_ok", "btn_ok_a", "btn_ok_b"}, {"btn_cancel", "btn_cancel_a", "btn_cancel_b"}};
|
|
int ids[2] = {184, 185};
|
|
int positions[2][2] = {{189, 96}, {234, 96}};
|
|
|
|
for (int index = 0; index < 2; ++index) {
|
|
auto* button = new UIBitmapButton();
|
|
button->SetBitmap((prefix + names[index][0] + ".bmp").c_str(), 0, 0);
|
|
button->SetBitmap((prefix + names[index][1] + ".bmp").c_str(), 1, 0);
|
|
button->SetBitmap((prefix + names[index][2] + ".bmp").c_str(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight());
|
|
button->Move(positions[index][0], positions[index][1]);
|
|
button->SetId(ids[index]);
|
|
this->AddChild(button);
|
|
}
|
|
|
|
this->m_message0 = 184;
|
|
}
|
|
|
|
// OFFSET: 0x008B7A60
|
|
// FUNCTION: fn_11753
|
|
void UILoginOTPWnd::OnDestroy() {
|
|
}
|
|
|
|
// OFFSET: 0x008B7A70
|
|
// FUNCTION: fn_11754
|
|
void UILoginWnd::OnDestroy() {
|
|
}
|
|
|
|
// OFFSET: 0x008B7A80
|
|
// FUNCTION: fn_11755
|
|
void UIMakeCharWnd::OnDestroy() {
|
|
}
|
|
|
|
// OFFSET: 0x008B8E90
|
|
// FUNCTION: fn_11769
|
|
void UIMessageBoxAutoreturn::Paint() {
|
|
auto* background = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve("유저인터페이스\\win_msgbox.bmp")));
|
|
this->DrawBitmap(0, 0, background, false);
|
|
}
|
|
|
|
// OFFSET: 0x008BA670
|
|
// FUNCTION: fn_11788
|
|
void UILoginOTPWnd::OnProcess() {
|
|
auto* login = static_cast<CLoginMode*>(g_modeMgr.GetLoginMode());
|
|
if (login == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const unsigned remaining = static_cast<unsigned>(60.0 - (timeGetTime() - login->otpStarted) * 0.001);
|
|
UIStaticText* timer = this->timerText;
|
|
constexpr auto sourceText = CRYPT_NAME("%02d : %02d", 0x7941D76335CFA14FULL);
|
|
const auto& source = sourceText.data;
|
|
thread_local EncryptedName<sizeof(source), 0x7941D76335CFA14FULL> format(source);
|
|
timer->SetText(FormatOwnedString(format.Text(), remaining / 60, remaining % 60).c_str(), 0);
|
|
this->Invalidate();
|
|
}
|
|
|
|
// OFFSET: 0x008BAEF0
|
|
// FUNCTION: fn_11792
|
|
void UIMessageBoxAutoreturn::OnProcess() {
|
|
if (this->counting == 0) {
|
|
return;
|
|
}
|
|
|
|
if (timeGetTime() > this->deadline) {
|
|
g_windowMgr.modalResponse = 187;
|
|
this->counting = 0;
|
|
return;
|
|
}
|
|
|
|
const unsigned previous = this->remaining;
|
|
const unsigned fraction = (this->deadline - timeGetTime()) % 1000 ? 1 : 0;
|
|
this->remaining = (this->deadline - timeGetTime()) / 1000 + fraction;
|
|
|
|
if (previous != this->remaining) {
|
|
char text[512];
|
|
std::sprintf(text, this->format.c_str(), this->remaining);
|
|
this->messageText = text;
|
|
this->viewer->Clear();
|
|
this->viewer->SendMsg(nullptr, UM_SETTEXT, reinterpret_cast<std::intptr_t>(this->messageText.data()), 38, 0, 0);
|
|
}
|
|
|
|
UIBarGraph2* gauge = this->gauge;
|
|
const unsigned duration = this->seconds * 1000;
|
|
const unsigned progress = (timeGetTime() + (duration - this->deadline)) * 100 / duration;
|
|
gauge->SetValue(static_cast<float>(progress));
|
|
}
|
|
|
|
// OFFSET: 0x008AA9D0
|
|
// FUNCTION: fn_11723
|
|
void UIItemWnd::DrawNewItemMark(int x, int y) {
|
|
this->DrawBitmap(x, y, static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve("유저인터페이스\\basic_interface\\new_item.bmp"))), false);
|
|
}
|
|
|
|
// OFFSET: 0x008AAA10
|
|
// FUNCTION: fn_11724
|
|
void UIMonsterInfoWnd::DrawResistance(int x, int y, const char* label, int value, std::uint32_t border, std::uint32_t fill) {
|
|
char text[64];
|
|
wsprintfA(text, "%s:%d", label, value);
|
|
unsigned red;
|
|
unsigned green;
|
|
unsigned blue;
|
|
SkinPaletteChannels(ResourceMgr::Instance(), 22, 2, red, green, blue);
|
|
this->FillRegion(x, y, 70, 16, border);
|
|
this->FillRegion(x + 1, y + 1, 68, 14, fill);
|
|
this->DrawTextAt((70 - this->TextWidth(text, 0, 0, 12, 0, 0)) / 2 + x, y + 2, text, 0, 0, 12, RGB(red, blue, green), 0, 0);
|
|
}
|
|
|
|
// OFFSET: 0x008B8ED0
|
|
// FUNCTION: fn_11770
|
|
void UIMonsterInfoWnd::Paint() {
|
|
unsigned red;
|
|
unsigned green;
|
|
unsigned blue;
|
|
SkinPaletteChannels(ResourceMgr::Instance(), 2, 2, red, green, blue);
|
|
const std::uint32_t fill = RGB(red, green, blue);
|
|
this->ClearSurface(fill);
|
|
this->DrawPanelBackground(this->DrawTitleBar(false, "", 0), 0, "");
|
|
this->DrawButtonBar(2, 0, 1);
|
|
SkinPaletteChannels(ResourceMgr::Instance(), 22, 2, red, green, blue);
|
|
const std::uint32_t border = RGB(red, green, blue);
|
|
|
|
this->DrawTextAt(17, 3, LookupMessage(MSI_MONSTER_INFO_WINDOW), 0, 0, 12, 0xFFFFFF, 0, 0);
|
|
this->DrawTextAt(16, 2, LookupMessage(MSI_MONSTER_INFO_WINDOW), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(120, 30, LookupMessage(MSI_NAME), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(160, 30, this->name.c_str(), 0, 0, 12, 0, 0, 0);
|
|
|
|
char text[256];
|
|
StringFormat(text, sizeof(text), static_cast<std::size_t>(-1), "%d", this->info.level);
|
|
this->DrawTextAt(120, 50, LookupMessage(MSI_LEVEL), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(160, 50, text, 0, 0, 12, 0, 0, 0);
|
|
StringFormat(text, sizeof(text), static_cast<std::size_t>(-1), "%d", this->info.hp);
|
|
this->DrawTextAt(120, 70, LookupMessage(MSI_HP), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(160, 70, text, 0, 0, 12, 0, 0, 0);
|
|
StringFormat(text, sizeof(text), static_cast<std::size_t>(-1), "%d", this->info.defense);
|
|
this->DrawTextAt(120, 90, LookupMessage(MSI_ZEROQUEST_ALLSELECT), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(160, 90, text, 0, 0, 12, 0, 0, 0);
|
|
|
|
this->DrawTextAt(260, 30, LookupMessage(MSI_SIZE), 0, 0, 12, 0, 0, 0);
|
|
switch (this->info.size) {
|
|
case SZ_SMALL:
|
|
this->DrawTextAt(300, 30, LookupMessage(MSI_MONSTERINFO_DEF), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case SZ_MEDIUM:
|
|
this->DrawTextAt(300, 30, LookupMessage(MSI_BAN_TEENAGER), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case SZ_BIG:
|
|
this->DrawTextAt(300, 30, LookupMessage(MSI_STYLINGSHOP_COLOR_RESET), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
}
|
|
|
|
StringFormat(text, sizeof(text), static_cast<std::size_t>(-1), "%d", this->info.race);
|
|
this->DrawTextAt(260, 50, LookupMessage(MSI_RACETYPE), 0, 0, 12, 0, 0, 0);
|
|
switch (this->info.race) {
|
|
case RC_FORMLESS:
|
|
this->DrawTextAt(300, 50, LookupMessage(MSI_MONSTERINFO_TRIBE_PLANT), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case RC_UNDEAD:
|
|
this->DrawTextAt(300, 50, LookupMessage(MSI_MONSTERINFO_TRIBE_INSECT), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case RC_BRUTE:
|
|
this->DrawTextAt(300, 50, LookupMessage(MSI_MONSTERINFO_TRIBE_MARINE), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case RC_PLANT:
|
|
this->DrawTextAt(300, 50, LookupMessage(MSI_MONSTERINFO_TRIBE_DEVIL), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case RC_INSECT:
|
|
this->DrawTextAt(300, 50, LookupMessage(MSI_MONSTERINFO_TRIBE_HUMAN), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case RC_FISH:
|
|
this->DrawTextAt(300, 50, LookupMessage(MSI_MONSTERINFO_TRIBE_ANGEL), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case RC_DEMON:
|
|
this->DrawTextAt(300, 50, LookupMessage(MSI_MONSTERINFO_TRIBE_DRAGON), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case RC_DEMIHUMAN:
|
|
this->DrawTextAt(300, 50, LookupMessage(MSI_MONSTERINFO_PROPERTY_NEUTURAL), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case RC_ANGEL:
|
|
this->DrawTextAt(300, 50, LookupMessage(MSI_MONSTERINFO_PROPERTY_WATER), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case RC_DRAGON:
|
|
this->DrawTextAt(300, 50, LookupMessage(MSI_MONSTERINFO_PROPERTY_EARTH), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
}
|
|
|
|
StringFormat(text, sizeof(text), static_cast<std::size_t>(-1), "%d", this->info.magicDefense);
|
|
this->DrawTextAt(260, 90, LookupMessage(MSI_MDEFPOWER), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(300, 90, text, 0, 0, 12, 0, 0, 0);
|
|
|
|
this->DrawTextAt(260, 70, LookupMessage(MSI_PROPERTY), 0, 0, 12, 0, 0, 0);
|
|
switch (this->info.element % 20) {
|
|
case ELE_NEUTRAL:
|
|
this->DrawTextAt(300, 70, LookupMessage(MSI_MONSTERINFO_PROPERTY_FIRE), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case ELE_WATER:
|
|
this->DrawTextAt(300, 70, LookupMessage(MSI_MONSTERINFO_PROPERTY_WIND), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case ELE_EARTH:
|
|
this->DrawTextAt(300, 70, LookupMessage(MSI_MONSTERINFO_PROPERTY_POISON), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case ELE_FIRE:
|
|
this->DrawTextAt(300, 70, LookupMessage(MSI_MONSTERINFO_PROPERTY_SAINT), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case ELE_WIND:
|
|
this->DrawTextAt(300, 70, LookupMessage(MSI_MONSTERINFO_PROPERTY_DARK), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case ELE_POISON:
|
|
this->DrawTextAt(300, 70, LookupMessage(MSI_MONSTERINFO_PROPERTY_MENTAL), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case ELE_HOLY:
|
|
this->DrawTextAt(300, 70, LookupMessage(MSI_MONSTERINFO_PROPERTY_UNDEAD), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case ELE_DARK:
|
|
this->DrawTextAt(300, 70, LookupMessage(MSI_MONSTERINFO_SIZE_SMALL), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case ELE_GHOST:
|
|
this->DrawTextAt(300, 70, LookupMessage(MSI_MONSTERINFO_SIZE_MIDDLE), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
case ELE_UNDEAD:
|
|
this->DrawTextAt(300, 70, LookupMessage(MSI_MONSTERINFO_SIZE_BIG), 0, 0, 12, 0, 0, 0);
|
|
break;
|
|
}
|
|
|
|
this->DrawResistance(120, 110, LookupMessage(MSI_MONSTERINFO_PROPERTY_WIND), this->info.resistances[0], border, fill);
|
|
this->DrawResistance(120, 128, LookupMessage(MSI_MONSTERINFO_PROPERTY_POISON), this->info.resistances[1], border, fill);
|
|
this->DrawResistance(120, 146, LookupMessage(MSI_MONSTERINFO_PROPERTY_SAINT), this->info.resistances[2], border, fill);
|
|
this->DrawResistance(200, 110, LookupMessage(MSI_MONSTERINFO_PROPERTY_DARK), this->info.resistances[3], border, fill);
|
|
this->DrawResistance(200, 128, LookupMessage(MSI_MONSTERINFO_PROPERTY_MENTAL), this->info.resistances[4], border, fill);
|
|
this->DrawResistance(200, 146, LookupMessage(MSI_MONSTERINFO_PROPERTY_UNDEAD), this->info.resistances[5], border, fill);
|
|
this->DrawResistance(280, 110, LookupMessage(MSI_MONSTERINFO_SIZE_SMALL), this->info.resistances[6], border, fill);
|
|
this->DrawResistance(280, 128, LookupMessage(MSI_MONSTERINFO_SIZE_MIDDLE), this->info.resistances[7], border, fill);
|
|
this->DrawResistance(280, 146, LookupMessage(MSI_MONSTERINFO_SIZE_BIG), this->info.resistances[8], border, fill);
|
|
|
|
char spriteName[128];
|
|
StringFormat(spriteName, sizeof(spriteName), static_cast<std::size_t>(-1), "몬스터\\%s.spr", g_session.GetJobName(this->info.job, -1));
|
|
char actionName[128];
|
|
StringFormat(actionName, sizeof(actionName), static_cast<std::size_t>(-1), "몬스터\\%s.act", g_session.GetJobName(this->info.job, -1));
|
|
if (ResourceMgr::Instance().Exists(actionName) && ResourceMgr::Instance().Exists(spriteName)) {
|
|
auto* action = static_cast<CActRes*>(ResourceMgr::Instance().Load(actionName));
|
|
auto* sprite = static_cast<CSprRes*>(ResourceMgr::Instance().Load(spriteName));
|
|
this->DrawActionSprite(sprite, action, 2, 19, 116, 152, 0, true, nullptr);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008C3440
|
|
// FUNCTION: fn_11823
|
|
void UIReplayRECControlWnd::UpdateRecordTime() {
|
|
for (int index = 0; index < 4; ++index) {
|
|
this->tabs[index]->Move(-100, -100);
|
|
}
|
|
|
|
this->tabs[static_cast<int>(timeGetTime() % 1000) / 250]->Move(6, 5);
|
|
if (timeGetTime() - this->recordStart <= 200) {
|
|
return;
|
|
}
|
|
|
|
const int elapsed = static_cast<int>(timeGetTime() - Replay::Instance().started) / 1000;
|
|
const int totalMinutes = elapsed / 60;
|
|
const int seconds = elapsed % 60;
|
|
const int hours = totalMinutes / 60;
|
|
const int minutes = totalMinutes % 60;
|
|
if (hours == 100) {
|
|
this->recordTimeText->Move(124, 47);
|
|
} else if (hours == 1000) {
|
|
this->recordTimeText->Move(116, 47);
|
|
}
|
|
|
|
char text[100] = {};
|
|
std::sprintf(text, "%03d:%02d:%02d", hours, minutes, seconds);
|
|
this->recordTimeText->SetTextFitted(text);
|
|
this->Invalidate();
|
|
this->InvalidateChildren();
|
|
this->recordStart = timeGetTime();
|
|
}
|
|
|
|
// OFFSET: 0x008C0DF0
|
|
// FUNCTION: fn_11814
|
|
int UIReplayRECControlWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) {
|
|
switch (message) {
|
|
case UM_SETINFO:
|
|
this->saved = reinterpret_cast<ReplayRECControlWndInfo*>(a);
|
|
|
|
if (!this->saved->IsValid()) {
|
|
this->saved->Reset();
|
|
}
|
|
|
|
this->Move(this->saved->x, this->saved->y);
|
|
return 0;
|
|
case UM_COMMAND:
|
|
switch (a) {
|
|
case ID_START_REPLAY_RECORDING:
|
|
if (!this->replayPathEnabled) {
|
|
this->mode = 1;
|
|
g_modeMgr.gameMode->SendMsg(MM_START_REPLAY_RECORDING, 0, 0, 0, 0);
|
|
this->ApplyMode();
|
|
return 0;
|
|
}
|
|
|
|
this->mode = 3;
|
|
this->ApplyMode();
|
|
return 0;
|
|
case ID_STOP_REPLAY_RECORDING:
|
|
this->mode = 0;
|
|
this->ApplyMode();
|
|
g_modeMgr.gameMode->SendMsg(MM_STOP_REPLAY_RECORDING, 0, 0, 0, 0);
|
|
return 0;
|
|
case ID_CONFIRM_REPLAY_RECORDING_PATH: {
|
|
auto* edit = static_cast<UIEditCtrl*>(this->filenameEdit);
|
|
int error;
|
|
|
|
if (edit->Length() <= 0) {
|
|
error = 1972;
|
|
} else if (_mbsstr(reinterpret_cast<const unsigned char*>(edit->Text()), reinterpret_cast<const unsigned char*>(s_messageBoxItemLinkOpening.c_str())) ||
|
|
_mbsstr(reinterpret_cast<const unsigned char*>(edit->Text()), reinterpret_cast<const unsigned char*>(s_messageBoxItemLinkClosing.c_str()))) {
|
|
error = 2812;
|
|
} else {
|
|
ReplayFileList::Instance().SetPath(edit->Text());
|
|
g_windowMgr.SetFocus(nullptr);
|
|
edit->SetText("");
|
|
g_modeMgr.gameMode->SendMsg(MM_START_REPLAY_RECORDING, 0, 0, 0, 0);
|
|
|
|
if (Replay::Instance().state == 1) {
|
|
return 0;
|
|
}
|
|
|
|
this->mode = 1;
|
|
this->ApplyMode();
|
|
return 0;
|
|
}
|
|
|
|
g_windowMgr.Confirm(LookupMessage(error), 0, true, false, 0, "Message", 280, 120, 0);
|
|
return 0;
|
|
}
|
|
case ID_REPLAY_RECORDING_OPTIONS:
|
|
this->mode = 2;
|
|
this->ApplyMode();
|
|
return 0;
|
|
case ID_CANCEL_REPLAY_RECORDING_OPTIONS:
|
|
this->mode = 0;
|
|
this->ApplyMode();
|
|
return 0;
|
|
case ID_CLOSE_REPLAY_RECORDING:
|
|
this->mode = 0;
|
|
g_windowMgr.CloseWindow(WID_REPLAYRECCONTROLWND);
|
|
return 0;
|
|
case ID_CHECK:
|
|
if (sender == this->userFilenameCheckBox) {
|
|
ReplayFileList::Instance().pathEnabled = b != 0;
|
|
this->replayPathEnabled = ReplayFileList::Instance().pathEnabled;
|
|
return 0;
|
|
}
|
|
|
|
if (sender == this->rejectExistingNameCheckBox) {
|
|
ReplayFileList::Instance().rejectExistingName = b != 0;
|
|
this->replayOption119 = ReplayFileList::Instance().rejectExistingName;
|
|
return 0;
|
|
}
|
|
|
|
if (sender == this->options[9]) {
|
|
if (b == 1) {
|
|
for (int index = 0; index < 10; ++index) {
|
|
if (index != 9) {
|
|
this->recordOptions[index] = 1;
|
|
static_cast<UICheckBox*>(this->options[index])->SetChecked(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
this->recordOptions[9] = b != 0;
|
|
} else if (sender == this->options[0]) {
|
|
if (b == 0) {
|
|
for (int index = 1; index < 10; ++index) {
|
|
this->recordOptions[index] = 0;
|
|
static_cast<UICheckBox*>(this->options[index])->SetChecked(0);
|
|
}
|
|
}
|
|
|
|
this->recordOptions[0] = b != 0;
|
|
} else {
|
|
if (b == 1) {
|
|
if (this->options[0]->geometry.state == 0) {
|
|
static_cast<UICheckBox*>(this->options[0])->SetChecked(1);
|
|
this->recordOptions[0] = 1;
|
|
}
|
|
} else if (this->options[9]->geometry.state == 1) {
|
|
static_cast<UICheckBox*>(this->options[9])->SetChecked(0);
|
|
this->recordOptions[9] = 0;
|
|
}
|
|
|
|
for (int index = 1; index < 9; ++index) {
|
|
if (sender == this->options[index]) {
|
|
this->recordOptions[index] = b != 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
Replay::Instance().SetOptions(this->recordOptions, 10);
|
|
return 0;
|
|
default:
|
|
return 0;
|
|
}
|
|
case UM_UPDATE_RECORD_TIME:
|
|
this->UpdateRecordTime();
|
|
return 0;
|
|
case UM_SETPOS:
|
|
Replay::Instance().recordingState = this->geometry.x;
|
|
Replay::Instance().playbackState = this->geometry.y;
|
|
return 0;
|
|
case UM_REFRESH:
|
|
this->Invalidate();
|
|
this->InvalidateChildren();
|
|
return 0;
|
|
case UM_REPLAY_FRAMED_DATA:
|
|
case 251:
|
|
return 0;
|
|
default:
|
|
return UIFrameWnd::SendMsg(sender, message, a, b, c, d);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008BA820
|
|
// FUNCTION: fn_11789
|
|
void UILoginWnd::OnProcess() {
|
|
if (g_windowMgr.GetHoverWindow() == this->idEdit) {
|
|
this->idEdit->TextColor(0, 0, 0, 0xFFFFFFFF);
|
|
if (this->idPlaceholder == true) {
|
|
const char source[] = {'\xA4', '\x31', '\x61'};
|
|
thread_local EncryptedName<sizeof(source), 0x2D51E3B7236175EDULL> placeholder(source);
|
|
if (std::strcmp(placeholder.Text(), this->idEdit->Text()) == 0) {
|
|
this->idEdit->SetText("");
|
|
goto password;
|
|
}
|
|
}
|
|
this->idPlaceholder = false;
|
|
} else {
|
|
if (std::strcmp("", this->idEdit->Text()) == 0) {
|
|
this->idEdit->TextColor(156, 156, 156, 0xFFFFFFFF);
|
|
UIEditCtrl_Custom* edit = this->idEdit;
|
|
this->idPlaceholder = true;
|
|
const char source[] = {'\x5E', '\x5F', '\x2D'};
|
|
thread_local EncryptedName<sizeof(source), 0x0F41EBBDA32D1B17ULL> placeholder(source);
|
|
edit->SetText(placeholder.Text());
|
|
}
|
|
if (this->idPlaceholder == false) {
|
|
this->idEdit->TextColor(0, 0, 0, 0xFFFFFFFF);
|
|
}
|
|
}
|
|
|
|
password:
|
|
if (g_windowMgr.GetHoverWindow() == this->passwordEdit) {
|
|
HIMC context = ImmGetContext(hWnd);
|
|
DWORD conversion;
|
|
DWORD sentence;
|
|
ImmGetConversionStatus(context, &conversion, &sentence);
|
|
conversion &= ~(IME_CMODE_NATIVE | IME_CMODE_KATAKANA);
|
|
ImmSetConversionStatus(context, IME_CMODE_ALPHANUMERIC, sentence);
|
|
ImmReleaseContext(hWnd, context);
|
|
this->passwordEdit->TextColor(0, 0, 0, 0xFFFFFFFF);
|
|
if (this->passwordPlaceholder == true) {
|
|
const char source[] = {'\x99', '\x52', '\xAA', '\x20', '\xAE', '\x96', '\x47', '\x35', '\xC9'};
|
|
thread_local EncryptedName<sizeof(source), 0x7115D9F973F913C9ULL> placeholder(source);
|
|
if (std::strcmp(placeholder.Text(), this->passwordEdit->Text()) == 0) {
|
|
this->passwordEdit->SetText("");
|
|
this->passwordEdit->mask = 0;
|
|
return;
|
|
}
|
|
}
|
|
this->passwordPlaceholder = false;
|
|
} else {
|
|
if (std::strcmp("", this->passwordEdit->Text()) == 0) {
|
|
this->passwordPlaceholder = true;
|
|
this->passwordEdit->TextColor(156, 156, 156, 0xFFFFFFFF);
|
|
auto* edit = this->passwordEdit;
|
|
const char source[] = {'\x33', '\xB4', '\xB2', '\x2C', '\x6C', '\x6A', '\x4F', '\x8F', '\x63'};
|
|
thread_local EncryptedName<sizeof(source), 0xCB1D253B7FE1F563ULL> placeholder(source);
|
|
edit->SetText(placeholder.Text());
|
|
this->passwordEdit->mask = 0;
|
|
}
|
|
if (this->passwordPlaceholder != false) {
|
|
return;
|
|
}
|
|
this->passwordEdit->TextColor(0, 0, 0, 0xFFFFFFFF);
|
|
}
|
|
|
|
this->passwordEdit->mask = '*';
|
|
}
|
|
|
|
// OFFSET: 0x008C36F0
|
|
// FUNCTION: fn_11830
|
|
void UIChatRoomWnd::SaveChatLog() {
|
|
int index = 0;
|
|
char path[2048];
|
|
std::sprintf(path, "%s\\Chat", g_applicationDirectory);
|
|
if (_access(path, 0) != 0 && _mkdir(path) != 0) {
|
|
return;
|
|
}
|
|
|
|
std::string name = this->title;
|
|
for (unsigned position = 0; position < name.size(); ++position) {
|
|
const char character = name[position];
|
|
if (character == '\\' || character == '/' || character == ':' || character == '*' || character == '?' || character == '"' || character == '<' ||
|
|
character == '>' || character == '|') {
|
|
name[position] = '_';
|
|
}
|
|
}
|
|
|
|
std::sprintf(path, "%s\\Chat\\%s.txt", g_applicationDirectory, name.c_str());
|
|
while (_access(path, 0) == 0) {
|
|
++index;
|
|
std::sprintf(path, "%s\\Chat\\%s%03d.txt", g_applicationDirectory, name.c_str(), index);
|
|
}
|
|
|
|
if (this->history->SaveChatLog(path)) {
|
|
std::string message = path;
|
|
message.append(" is Saved.", 10);
|
|
g_windowMgr.SendNotice(UIM_OPENCHATWND, 0, 0, 0, 0, 0);
|
|
g_windowMgr.SendNotice(UIM_PUSHINTOCHATHISTORY, reinterpret_cast<std::intptr_t>(message.c_str()), 0xFF00, 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008AAAF0
|
|
// FUNCTION: fn_11725
|
|
std::vector<unsigned char> UIChatRoomWnd::SerializeReplayData() {
|
|
std::vector<unsigned char> records;
|
|
{
|
|
const auto record = BuildReplayTaggedRecord(0x5014, nullptr, 0);
|
|
records.insert(records.end(), record.begin(), record.end());
|
|
}
|
|
{
|
|
const auto record = BuildReplayTaggedRecord(0x5016, this->saved, 0x10);
|
|
records.insert(records.end(), record.begin(), record.end());
|
|
}
|
|
{
|
|
const auto record = BuildReplayTaggedRecord(0x5017, this->title.data(), static_cast<std::uint32_t>(this->title.size()));
|
|
records.insert(records.end(), record.begin(), record.end());
|
|
}
|
|
{
|
|
const auto record = BuildReplayTaggedRecord(0x5018, this->roomSettingsText.data(), static_cast<std::uint32_t>(this->roomSettingsText.size()));
|
|
records.insert(records.end(), record.begin(), record.end());
|
|
}
|
|
{
|
|
const auto record = BuildReplayTaggedRecord(0x5019, this->roomStatusValues, 4);
|
|
records.insert(records.end(), record.begin(), record.end());
|
|
}
|
|
{
|
|
const auto record = BuildReplayTaggedRecord(0x501A, this->roomStatusValues + 4, 4);
|
|
records.insert(records.end(), record.begin(), record.end());
|
|
}
|
|
{
|
|
const auto record = BuildReplayTaggedRecord(0x501B, this->roomStatusValues + 8, 4);
|
|
records.insert(records.end(), record.begin(), record.end());
|
|
}
|
|
{
|
|
const auto record = BuildReplayTaggedRecord(0x501C, this->roomStatusValues + 12, 4);
|
|
records.insert(records.end(), record.begin(), record.end());
|
|
}
|
|
|
|
for (const auto& entry : this->memberRoles) {
|
|
if (entry.second == 0) {
|
|
const auto record = BuildReplayTaggedRecord(0x501E, entry.first.data(), static_cast<std::uint32_t>(entry.first.size()));
|
|
records.insert(records.end(), record.begin(), record.end());
|
|
}
|
|
}
|
|
|
|
for (const auto& entry : this->memberRoles) {
|
|
if (entry.second != 0) {
|
|
const auto record = BuildReplayTaggedRecord(0x501F, entry.first.data(), static_cast<std::uint32_t>(entry.first.size()));
|
|
records.insert(records.end(), record.begin(), record.end());
|
|
}
|
|
}
|
|
|
|
{
|
|
const auto record = BuildReplayTaggedRecord(0x5015, nullptr, 0);
|
|
records.insert(records.end(), record.begin(), record.end());
|
|
}
|
|
return records;
|
|
}
|
|
|
|
// OFFSET: 0x008ABDB0
|
|
// FUNCTION: fn_11728
|
|
void UILoginWnd::LoadLogin() {
|
|
HKEY probe;
|
|
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, g_subKey, 0, KEY_QUERY_VALUE, &probe) == ERROR_SUCCESS) {
|
|
RegCloseKey(probe);
|
|
HKEY key;
|
|
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, g_subKey, 0, KEY_QUERY_VALUE, &key) != ERROR_SUCCESS) {
|
|
return;
|
|
}
|
|
|
|
DWORD type = REG_DWORD;
|
|
DWORD size = 4;
|
|
int saveId;
|
|
const char checkSource[] = {'\xB2', '\x8F', '\x7C', '\x4A', '\x5C', '\x2A', '\x0E', '\xA7', '\xB4', '\xC7'};
|
|
thread_local EncryptedName<sizeof(checkSource), 0xF14F79170939C7F1ULL> checkName(checkSource);
|
|
RegQueryValueExA(key, checkName.Text(), nullptr, &type, reinterpret_cast<BYTE*>(&saveId), &size);
|
|
if (saveId != 1) {
|
|
saveId = 0;
|
|
}
|
|
|
|
int bitwise;
|
|
const char bitwiseSource[] = {'\xDD', '\x8C', '\x39', '\xFC', '\x9E', '\x7A', '\xB8', '\xA5'};
|
|
thread_local EncryptedName<sizeof(bitwiseSource), 0xA5FD29D7AB6DC59FULL> bitwiseName(bitwiseSource);
|
|
RegQueryValueExA(key, bitwiseName.Text(), nullptr, &type, reinterpret_cast<BYTE*>(&bitwise), &size);
|
|
|
|
char id[52];
|
|
std::memset(id, 0, sizeof(id));
|
|
char password[26] = {};
|
|
type = REG_SZ;
|
|
size = 25;
|
|
const char passwordSource[] = {'\xB1', '\x3A', '\xAA', '\x84', '\x82', '\x5C', '\x6B', '\x99', '\xE1'};
|
|
thread_local EncryptedName<sizeof(passwordSource), 0xDD3913D5D7F97BE1ULL> passwordName(passwordSource);
|
|
RegQueryValueExA(key, passwordName.Text(), nullptr, &type, reinterpret_cast<BYTE*>(password), &size);
|
|
password[24] = 0;
|
|
|
|
type = REG_SZ;
|
|
size = 51;
|
|
const char idSource[] = {'\xD2', '\x13', '\x03'};
|
|
thread_local EncryptedName<sizeof(idSource), 0x050505679903579BULL> idName(idSource);
|
|
RegQueryValueExA(key, idName.Text(), nullptr, &type, reinterpret_cast<BYTE*>(id), &size);
|
|
id[50] = 0;
|
|
password[24] = 0;
|
|
this->saveId = saveId;
|
|
|
|
if (saveId != 0) {
|
|
unsigned char shade;
|
|
bool placeholder = std::strcmp("", id) == 0;
|
|
if (!placeholder) {
|
|
const char compareSource[] = {'\xF4', '\xF9', '\xED'};
|
|
thread_local EncryptedName<sizeof(compareSource), 0x83EFBFBB37EDBDBDULL> compareName(compareSource);
|
|
placeholder = std::strcmp(compareName.Text(), id) == 0;
|
|
}
|
|
|
|
if (!placeholder) {
|
|
shade = 0;
|
|
this->idPlaceholder = false;
|
|
} else {
|
|
this->idPlaceholder = true;
|
|
UIEditCtrl_Custom* edit = this->idEdit;
|
|
const char textSource[] = {'\xEE', '\xB1', '\x7F'};
|
|
thread_local EncryptedName<sizeof(textSource), 0xBF2B4B31397FF5A7ULL> textName(textSource);
|
|
edit->SetText(textName.Text());
|
|
shade = 156;
|
|
}
|
|
|
|
this->idEdit->TextColor(shade, shade, shade, 0xFFFFFFFF);
|
|
this->idEdit->SetText(id);
|
|
this->passwordEdit->SetText("");
|
|
}
|
|
|
|
RegCloseKey(key);
|
|
} else {
|
|
this->idEdit->SetText("");
|
|
this->passwordEdit->SetText("");
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008AB050
|
|
// FUNCTION: fn_11726
|
|
int sub_8AB050() {
|
|
return 4;
|
|
}
|
|
|
|
// OFFSET: 0x008AB060
|
|
// FUNCTION: fn_11727
|
|
int sub_8AB060() {
|
|
return 6;
|
|
}
|
|
|
|
// OFFSET: 0x008A4220
|
|
// FUNCTION: fn_11666
|
|
UINoticeWnd::UINoticeWnd() : UIFrameWnd(0) {
|
|
this->m_patchFile = "notice_patch.txt";
|
|
for (int i = 0; i < 19; ++i) {
|
|
this->m_texts[i] = new UIStaticText();
|
|
}
|
|
this->lineCount = 20;
|
|
this->padding_010C = 0;
|
|
this->m_noticeCount = 0;
|
|
this->m_index = 0;
|
|
this->m_scrollPositions[0] = 0;
|
|
this->m_bottomPositions[0] = 0;
|
|
this->m_scroll = 0;
|
|
g_windowMgr.SetFocus(this);
|
|
}
|
|
|
|
// OFFSET: 0x008AD190
|
|
// FUNCTION: fn_11737
|
|
void UIBank_NewWnd::OnCreate(int, int) {
|
|
this->AddCloseButton("Exit", 0);
|
|
this->AddBitmapButton(462, 209, 77, "bank\\btn_deposit", LookupMessage(MSI_BANK_7));
|
|
this->AddBitmapButton(463, 209, 102, "bank\\btn_withdraw", LookupMessage(MSI_BANK_MAX));
|
|
this->AddBitmapButton(279, 177, 89, "bank\\btn_upper", LookupMessage(MSI_BANK_NOMSG));
|
|
this->AddBitmapButton(280, 177, 99, "bank\\btn_buttom", LookupMessage(MSI_BANK_0_MINI));
|
|
this->AddBitmapButton(392, 189, 132, "bank\\btn_10mil", "+ 100,000");
|
|
this->AddBitmapButton(391, 141, 132, "bank\\btn_100mil", "+ 1,000,000");
|
|
this->AddBitmapButton(390, 93, 132, "bank\\btn_1000mil", "+ 10,000,000");
|
|
this->AddBitmapButton(389, 45, 132, "bank\\btn_max", LookupMessage(MSI_BANK_1_MINI));
|
|
|
|
this->m_amountEdit = new UIEditCtrl();
|
|
this->m_amountEdit->SetSize(99, 17);
|
|
this->m_amountEdit->maximum = 10;
|
|
this->m_amountEdit->Move(78, 90);
|
|
this->m_amountEdit->Background(247, 247, 247);
|
|
this->m_amountEdit->Border(198, 198, 198);
|
|
this->m_amountEdit->flat = 0;
|
|
this->m_amountEdit->topPadding = 1;
|
|
this->AddChild(this->m_amountEdit);
|
|
g_windowMgr.SetFocus(this->m_amountEdit);
|
|
}
|
|
|
|
// OFFSET: 0x008AD770
|
|
// FUNCTION: fn_11739
|
|
void UICntWnd::OnCreate(int, int) {
|
|
this->m_edit = new UIEditCtrl();
|
|
this->m_edit->SetSize(80, 16);
|
|
this->m_edit->Move(15, 22);
|
|
this->m_edit->maximum = 6;
|
|
this->m_edit->Background(232, 232, 232);
|
|
this->AddChild(this->m_edit);
|
|
g_windowMgr.SetFocus(this->m_edit);
|
|
this->m_edit->SelectAll();
|
|
|
|
this->m_text = new UIStaticText();
|
|
this->m_text->SetSize(this->geometry.width - 30, 15);
|
|
this->m_text->Move(15, 6);
|
|
this->AddChild(this->m_text);
|
|
|
|
{
|
|
const std::string prefix("유저인터페이스\\");
|
|
const int x = this->geometry.width - 55;
|
|
const int y = this->geometry.height - 32;
|
|
UIBitmapButton* button = new UIBitmapButton();
|
|
button->SetBitmap((prefix + "btn_ok" + ".bmp").c_str(), 0, 0);
|
|
button->SetBitmap((prefix + "btn_ok_a" + ".bmp").c_str(), 1, 0);
|
|
button->SetBitmap((prefix + "btn_ok_b" + ".bmp").c_str(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight());
|
|
button->Move(x, y);
|
|
button->SetId(184);
|
|
this->AddChild(button);
|
|
}
|
|
this->m_message0 = 184;
|
|
}
|
|
|
|
// OFFSET: 0x008C0B20
|
|
// FUNCTION: fn_11813
|
|
int UIReplayControlWnd::SendMsg(UIWindow* sender, int message, std::intptr_t argument1, std::intptr_t argument2, std::intptr_t argument3, std::intptr_t argument4) {
|
|
switch (message) {
|
|
case UM_COMMAND:
|
|
switch (argument1) {
|
|
case ID_PAUSE_REPLAY:
|
|
g_modeMgr.gameMode->SendMsg(MM_PAUSE_REPLAY, 0, 0, 0, 0);
|
|
return 0;
|
|
case ID_RESUME_REPLAY:
|
|
g_modeMgr.gameMode->SendMsg(MM_RESUME_REPLAY, 0, 0, 0, 0);
|
|
return 0;
|
|
case ID_RESTART_REPLAY:
|
|
g_modeMgr.gameMode->SendMsg(MM_RESTART_REPLAY, 0, 0, 0, 0);
|
|
Replay::Instance().speed = 1.0f;
|
|
return 0;
|
|
case ID_EXIT_REPLAY:
|
|
g_windowMgr.Schedule(this);
|
|
g_modeMgr.gameMode->SendMsg(MM_EXIT_REPLAY, 0, 0, 0, 0);
|
|
Replay::Instance().speed = 1.0f;
|
|
return 0;
|
|
case ID_DECREASE_REPLAY_SPEED:
|
|
g_modeMgr.gameMode->SendMsg(MM_DECREASE_REPLAY_SPEED, 0, 0, 0, 0);
|
|
this->SendMsg(nullptr, UM_REFRESH, 0, 0, 0, 0);
|
|
return 0;
|
|
case ID_INCREASE_REPLAY_SPEED:
|
|
g_modeMgr.gameMode->SendMsg(MM_INCREASE_REPLAY_SPEED, 0, 0, 0, 0);
|
|
this->SendMsg(nullptr, UM_REFRESH, 0, 0, 0, 0);
|
|
return 0;
|
|
}
|
|
return 0;
|
|
case UM_REFRESHBUTTON:
|
|
if (!this->m_paused) {
|
|
this->m_playButton->Move(-100, -100);
|
|
this->m_pauseButton->Move(5, 89);
|
|
this->m_paused = true;
|
|
} else {
|
|
this->m_playButton->Move(5, 89);
|
|
this->m_pauseButton->Move(-100, -100);
|
|
this->m_paused = false;
|
|
}
|
|
this->Invalidate();
|
|
this->InvalidateChildren();
|
|
return 0;
|
|
case UM_REFRESH:
|
|
this->RefreshInfo();
|
|
return 0;
|
|
case 251:
|
|
return 0;
|
|
default:
|
|
return UIFrameWnd::SendMsg(sender, message, argument1, argument2, argument3, argument4);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008C3110
|
|
// FUNCTION: fn_11822
|
|
bool UIReplayControlWnd::RefreshInfo() {
|
|
const int elapsed = static_cast<int>(Replay::Instance().elapsed) / 1000;
|
|
const int totalMinutes = elapsed / 60;
|
|
const int seconds = elapsed % 60;
|
|
const int hours = totalMinutes / 60;
|
|
const int minutes = totalMinutes % 60;
|
|
const std::uint32_t duration = Replay::Instance().Duration();
|
|
const int durationHours = duration & 0xFFFF;
|
|
const int durationMinutes = static_cast<char>(duration >> 16);
|
|
const int durationSeconds = static_cast<char>(duration >> 24);
|
|
char text[100];
|
|
std::memset(text, 0, sizeof(text));
|
|
std::sprintf(text, LookupMessage(MSI_REPLAY_ELAPSEDTIME), hours, minutes, seconds, durationHours, durationMinutes, durationSeconds);
|
|
this->m_texts[0]->SetTextFitted(text);
|
|
|
|
std::memset(text, 0, sizeof(text));
|
|
const int level = Replay::Instance().SpeedLevel();
|
|
int speedMessage;
|
|
if (level == 1) {
|
|
speedMessage = 1956;
|
|
} else if (level == 2) {
|
|
speedMessage = 1957;
|
|
} else if (level == 3) {
|
|
speedMessage = 1958;
|
|
} else if (level == 4) {
|
|
speedMessage = 1959;
|
|
} else if (level == 5) {
|
|
speedMessage = 1960;
|
|
} else if (level == 6) {
|
|
speedMessage = 1961;
|
|
} else {
|
|
speedMessage = (level != 7) + 1962;
|
|
}
|
|
std::sprintf(text, LookupMessage(speedMessage));
|
|
this->m_texts[1]->SetTextFitted(text);
|
|
|
|
std::string location;
|
|
if (g_modeMgr.gameMode != nullptr) {
|
|
location = static_cast<CGameMode*>(g_modeMgr.gameMode)->LocationText();
|
|
}
|
|
this->m_texts[3]->SetTextFitted(location.c_str());
|
|
this->Invalidate();
|
|
this->InvalidateChildren();
|
|
return true;
|
|
}
|
|
|
|
// OFFSET: 0x008C14F0
|
|
// FUNCTION: fn_11815
|
|
int UISelectReplayDataWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) {
|
|
switch (message) {
|
|
case UM_SETCURITEM:
|
|
this->m_list->SendMsg(nullptr, UM_SETCURITEM, a, 0, 0, 0);
|
|
this->UpdateInfo();
|
|
this->Invalidate();
|
|
return 0;
|
|
case UM_UPPUSH:
|
|
this->m_list->SendMsg(nullptr, UM_UPPUSH, 0, 0, 0, 0);
|
|
this->UpdateInfo();
|
|
this->Invalidate();
|
|
return 0;
|
|
case UM_DOWNPUSH:
|
|
this->m_list->SendMsg(nullptr, UM_DOWNPUSH, 0, 0, 0, 0);
|
|
this->UpdateInfo();
|
|
this->Invalidate();
|
|
return 0;
|
|
case UM_COMMAND:
|
|
switch (a) {
|
|
case ID_CANCEL:
|
|
case ID_SELECT_REPLAY:
|
|
Replay::Instance().SetState(1);
|
|
g_windowMgr.Schedule(this);
|
|
g_modeMgr.gameMode->SendMsg(LMM_REPLAY_SELECT_SERVER, 0, 0, 0, 0);
|
|
return 0;
|
|
case ID_OK:
|
|
if (this->m_list->selected != -1) {
|
|
this->UpdateInfo();
|
|
this->Invalidate();
|
|
if (ReplayFileList::Instance().Open(32, 0, 0) == 1) {
|
|
if (Replay::Instance().MatchesService(g_serviceMode)) {
|
|
g_modeMgr.gameMode->SendMsg(LMM_START_REPLAY, 0, 0, 0, 0);
|
|
g_windowMgr.Schedule(this);
|
|
g_soundMgr->PlayWave("버튼소리.wav", 0.0f, 0.0f, 0.0f, 250, 40, 1.0f, 0);
|
|
return 0;
|
|
}
|
|
Replay::Instance().CloseFile();
|
|
g_windowMgr.Confirm(LookupMessage(MSI_REPLAY_SERVERNOMATCH), 0, true, true, 0, "Message", 280, 120, 0);
|
|
} else {
|
|
g_windowMgr.Confirm(LookupMessage(MSI_REPLAY_NOREPLAYFILE), 0, true, true, 0, "Message", 280, 120, 0);
|
|
}
|
|
}
|
|
break;
|
|
case ID_EXIT:
|
|
if (g_windowMgr.Confirm(LookupMessage(MSI_DO_YOU_REALLY_WANT_TO_QUIT), 2, true, false, 0, "Message", 280, 120, 0) == 187) {
|
|
g_modeMgr.gameMode->SendMsg(MM_QUIT, 0, 0, 0, 0);
|
|
g_windowMgr.Schedule(this);
|
|
return 0;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case UM_SET_TARGET:
|
|
this->UpdateInfo();
|
|
this->Invalidate();
|
|
return 0;
|
|
case 89:
|
|
this->m_serverButton->Move(234, this->m_serverButton->geometry.y);
|
|
break;
|
|
default:
|
|
return UIFrameWnd::SendMsg(sender, message, a, b, c, d);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// OFFSET: 0x008C2460
|
|
// FUNCTION: fn_11820
|
|
bool UISelectReplayDataWnd::UpdateInfo() {
|
|
if (ReplayFileList::Instance().Select(this->m_list->selected)) {
|
|
if (ReplayFileList::Instance().Open(32, 0, 0) == 1) {
|
|
Replay::Instance().CloseFile();
|
|
char buffer[100];
|
|
std::memset(buffer, 0, sizeof(buffer));
|
|
std::string service;
|
|
switch (Replay::Instance().header.serviceType) {
|
|
case 0:
|
|
service = "Primary";
|
|
break;
|
|
case 1:
|
|
service = "Sakray";
|
|
break;
|
|
case 2:
|
|
service = "Local";
|
|
break;
|
|
case 3:
|
|
service = "InstantEvent";
|
|
break;
|
|
case 4:
|
|
service = "PVP";
|
|
break;
|
|
case 5:
|
|
service = "PK";
|
|
break;
|
|
default:
|
|
service = "Data Error";
|
|
this->m_texts[0]->SetTextFitted("");
|
|
this->m_texts[1]->SetTextFitted(LookupMessage(MSI_REPLAY_NOREPLAYFILE));
|
|
this->m_texts[2]->SetTextFitted("");
|
|
this->m_texts[3]->SetTextFitted("");
|
|
this->m_texts[4]->SetTextFitted("");
|
|
return false;
|
|
}
|
|
|
|
std::sprintf(buffer, LookupMessage(MSI_REPLAY_CHRVICEINFO), service.c_str());
|
|
this->m_texts[0]->SetTextFitted(buffer);
|
|
std::memset(buffer, 0, sizeof(buffer));
|
|
|
|
char name[64];
|
|
std::memcpy(name, Replay::Instance().header.characterName, sizeof(name));
|
|
std::sprintf(buffer, LookupMessage(MSI_REPLAY_CHARACTERNAME), name);
|
|
this->m_texts[1]->SetTextFitted(buffer);
|
|
|
|
std::sprintf(buffer, LookupMessage(MSI_REPLAY_MAPNAME), Replay::Instance().header.mapName);
|
|
this->m_texts[2]->SetTextFitted(buffer);
|
|
|
|
const std::uint32_t date = Replay::Instance().header.key0;
|
|
const std::uint32_t time = Replay::Instance().header.key1;
|
|
const int second = static_cast<char>(time >> 24);
|
|
const int minute = static_cast<char>(time >> 16);
|
|
const int hour = static_cast<char>(time >> 8);
|
|
const int day = static_cast<char>(date >> 24);
|
|
const int month = static_cast<char>(date >> 16);
|
|
const int year = date & 0xFFFF;
|
|
const char* recordTimeFormat = LookupMessage(MSI_REPLAY_RECORDTIME);
|
|
std::sprintf(buffer, recordTimeFormat, year, month, day, hour, minute, second);
|
|
this->m_texts[3]->SetTextFitted(buffer);
|
|
|
|
const std::uint32_t duration = Replay::Instance().Duration();
|
|
const int seconds = static_cast<char>(duration >> 24);
|
|
const int minutes = static_cast<char>(duration >> 16);
|
|
const int hours = duration & 0xFFFF;
|
|
const char* playTimeFormat = LookupMessage(MSI_REPLAY_PLAYTIME);
|
|
std::sprintf(buffer, playTimeFormat, hours, minutes, seconds);
|
|
this->m_texts[4]->SetTextFitted(buffer);
|
|
} else {
|
|
this->m_texts[0]->SetTextFitted("");
|
|
this->m_texts[1]->SetTextFitted(LookupMessage(MSI_REPLAY_NOREPLAYFILE));
|
|
this->m_texts[2]->SetTextFitted("");
|
|
this->m_texts[3]->SetTextFitted("");
|
|
this->m_texts[4]->SetTextFitted("");
|
|
}
|
|
} else {
|
|
this->m_texts[0]->SetTextFitted("");
|
|
this->m_texts[1]->SetTextFitted("");
|
|
this->m_texts[2]->SetTextFitted("");
|
|
this->m_texts[3]->SetTextFitted("");
|
|
this->m_texts[4]->SetTextFitted("");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// OFFSET: 0x008C18C0
|
|
// FUNCTION: fn_11816
|
|
int UISelectServerWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) {
|
|
switch (message) {
|
|
case UM_SETCURITEM:
|
|
this->m_serverList->SendMsg(nullptr, UM_SETCURITEM, this->m_selectedServer, 0, 0, 0);
|
|
return 0;
|
|
case UM_UPPUSH:
|
|
this->m_serverList->SendMsg(nullptr, UM_UPPUSH, 0, 0, 0, 0);
|
|
return 0;
|
|
case UM_DOWNPUSH:
|
|
this->m_serverList->SendMsg(nullptr, UM_DOWNPUSH, 0, 0, 0, 0);
|
|
return 0;
|
|
case UM_SET_TARGET: {
|
|
this->m_event = a;
|
|
this->m_valueName = reinterpret_cast<const char*>(b);
|
|
const char* name = this->m_valueName.c_str();
|
|
this->m_selectedServer = g_serviceType;
|
|
HKEY probe;
|
|
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, g_subKey, 0, KEY_QUERY_VALUE, &probe) == ERROR_SUCCESS) {
|
|
RegCloseKey(probe);
|
|
HKEY key;
|
|
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, g_subKey, 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) {
|
|
DWORD type = REG_DWORD;
|
|
DWORD size = 4;
|
|
RegQueryValueExA(key, name, nullptr, &type, reinterpret_cast<BYTE*>(&this->m_selectedServer), &size);
|
|
RegCloseKey(key);
|
|
return 0;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case UM_COMMAND:
|
|
switch (a) {
|
|
case ID_SELECT_REPLAY:
|
|
reinterpret_cast<Replay&>(ReplayFileList::Instance()).SetBaseFrame(reinterpret_cast<std::uint32_t>(&Replay::Instance()));
|
|
ReplayFileList::Instance().selectionState = g_session.m_aid;
|
|
ReplayFileList::Instance().dialogState = g_session.GetCurrentSex();
|
|
g_modeMgr.gameMode->SendMsg(LMM_SELECT_REPLAY_DATA, 0, 0, 0, 0);
|
|
g_windowMgr.Schedule(this);
|
|
return 0;
|
|
case ID_OK:
|
|
if (this->m_serverList->selected != -1) {
|
|
g_windowMgr.Schedule(this);
|
|
g_modeMgr.gameMode->SendMsg(this->m_event, this->m_serverList->selected, 0, 0, 0);
|
|
g_soundMgr->PlayWave("버튼소리.wav", 0.0f, 0.0f, 0.0f, 250, 40, 1.0f, 0);
|
|
const char* name = this->m_valueName.c_str();
|
|
this->m_selectedServer = this->m_serverList->selected;
|
|
HKEY key;
|
|
DWORD disposition = 0;
|
|
if (RegCreateKeyExA(HKEY_LOCAL_MACHINE, g_subKey, 0, nullptr, 0, KEY_ALL_ACCESS, nullptr, &key, &disposition) == ERROR_SUCCESS) {
|
|
RegSetValueExA(key, name, 0, REG_DWORD, reinterpret_cast<const BYTE*>(&this->m_selectedServer), 4);
|
|
RegCloseKey(key);
|
|
return 0;
|
|
}
|
|
}
|
|
break;
|
|
case ID_CANCEL:
|
|
g_windowMgr.Schedule(this);
|
|
g_modeMgr.gameMode->SendMsg(LMM_CANCEL, 0, 0, 0, 0);
|
|
return 0;
|
|
case ID_EXIT:
|
|
if (g_windowMgr.Confirm(LookupMessage(MSI_DO_YOU_REALLY_WANT_TO_QUIT), 2, true, false, 0, "Message", 280, 120, 0) == 187) {
|
|
g_modeMgr.gameMode->SendMsg(MM_QUIT, 0, 0, 0, 0);
|
|
g_windowMgr.Schedule(this);
|
|
return 0;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case 89:
|
|
this->m_okButton->Move(234, this->m_okButton->geometry.y);
|
|
break;
|
|
default:
|
|
return UIFrameWnd::SendMsg(sender, message, a, b, c, d);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// OFFSET: 0x008B99A0
|
|
// FUNCTION: fn_11773
|
|
void UIPetInfoWnd::Paint() {
|
|
unsigned red;
|
|
unsigned green;
|
|
unsigned blue;
|
|
SkinPaletteChannels(ResourceMgr::Instance(), 2, 2, red, green, blue);
|
|
this->ClearSurface(RGB(red, green, blue));
|
|
this->DrawPanelBackground(this->DrawTitleBar(false, "", 0), 0, "");
|
|
|
|
auto* leftCorner = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve("유저인터페이스\\sysboxs_ld.bmp")));
|
|
this->DrawBitmap(0, this->geometry.height - leftCorner->image.height, leftCorner, false);
|
|
auto* rightCorner = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve("유저인터페이스\\sysboxs_rd.bmp")));
|
|
this->DrawBitmap(this->geometry.width - rightCorner->image.width, this->geometry.height - rightCorner->image.height, rightCorner, false);
|
|
|
|
char title[32];
|
|
StringFormat(title, 32, static_cast<std::size_t>(-1), "%s", LookupMessage(MSI_PET_INFO));
|
|
this->DrawTextAt(5, 2, title, 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(100, 24, LookupMessage(MSI_NAME), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(100, 44, LookupMessage(MSI_LEVEL), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(100, 69, LookupMessage(MSI_PET_HUNGRY), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(100, 89, LookupMessage(MSI_PET_FRIENDLY), 0, 0, 12, 0, 0, 0);
|
|
|
|
char level[8];
|
|
char hunger[24];
|
|
if (g_session.petHunger >= 0 && g_session.petHunger <= 10) {
|
|
std::strcpy(hunger, LookupMessage(MSI_VERY_HUNGRY));
|
|
} else if (g_session.petHunger > 10 && g_session.petHunger <= 25) {
|
|
std::strcpy(hunger, LookupMessage(MSI_HUNGRY));
|
|
} else if (g_session.petHunger > 25 && g_session.petHunger <= 75) {
|
|
std::strcpy(hunger, LookupMessage(MSI_NORMAL));
|
|
} else if (g_session.petHunger > 75 && g_session.petHunger <= 90) {
|
|
std::strcpy(hunger, LookupMessage(MSI_REPLETE));
|
|
} else if (g_session.petHunger > 90 && g_session.petHunger <= 100) {
|
|
std::strcpy(hunger, LookupMessage(MSI_VERY_REPLETE));
|
|
} else {
|
|
std::strcpy(hunger, LookupMessage(MSI_UNKNOWN));
|
|
}
|
|
|
|
_itoa(g_session.petLevel, level, 10);
|
|
this->DrawTextAt(135, 44, level, 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(145, 69, hunger, 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(145, 89, this->friendlyText.c_str(), 0, 0, 12, 0, 0, 0);
|
|
|
|
const int job = g_session.petJob;
|
|
|
|
if (job != -1 && ((job > 1000 && job < 3999) || static_cast<unsigned>(job - 20021) < 11979)) {
|
|
char illust[260];
|
|
std::memset(illust, 0, sizeof(illust));
|
|
g_session.GetPetIllustName(job, g_session.petAccessory, illust);
|
|
|
|
if (auto* image = dynamic_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve(illust)))) {
|
|
this->DrawBitmap(5, 21, image, false);
|
|
}
|
|
|
|
char command[] = "< Command >";
|
|
this->FillRegion(160, 44, 110, 18, 0xFAE6E6);
|
|
const int width = this->TextWidth(command, 0, 0, 12, 0, 0);
|
|
this->DrawTextAt(206 - width / 2, 48, command, 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(100, 119, LookupMessage(MSI_PET_ACCESSARY), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(100, 139, LookupMessage(g_session.petAccessory == 0 ? 600 : 598), 0, 0, 12, 0, 0, 0);
|
|
|
|
if (this->autoFeedAvailable == 1) {
|
|
this->DrawTextAt(100, 159, LookupMessage(MSI_PET_AUTO_FEEDING_OFF), 0, 0, 12, 0, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008C2E30
|
|
// FUNCTION: fn_11821
|
|
void UIPetInfoWnd::UpdateFriendlyGauge() {
|
|
const std::string previous = this->friendlyText;
|
|
int low;
|
|
int high;
|
|
if (g_session.m_petFriendly >= 0 && g_session.m_petFriendly <= 100) {
|
|
if (g_session.GetDisplayJob() >= 4050 && g_session.GetDisplayJob() <= 4052) {
|
|
int message;
|
|
if (g_session.m_petFriendly <= 20) {
|
|
low = 0;
|
|
message = 1022;
|
|
high = 100;
|
|
} else if (g_session.m_petFriendly <= 40) {
|
|
low = 20;
|
|
message = 1021;
|
|
high = 40;
|
|
} else {
|
|
low = 40;
|
|
message = 672;
|
|
high = 100;
|
|
}
|
|
this->friendlyText = LookupMessage(message);
|
|
} else {
|
|
this->friendlyText = LookupMessage(MSI_VERY_AWKWARD);
|
|
low = 0;
|
|
high = 100;
|
|
}
|
|
} else if (g_session.m_petFriendly > 100 && g_session.m_petFriendly <= 250) {
|
|
this->friendlyText = LookupMessage(MSI_AWKWARD);
|
|
low = 100;
|
|
high = 250;
|
|
} else if (g_session.m_petFriendly > 250 && g_session.m_petFriendly <= 750) {
|
|
this->friendlyText = LookupMessage(MSI_NORMAL);
|
|
low = 250;
|
|
high = 750;
|
|
} else if (g_session.m_petFriendly > 750 && g_session.m_petFriendly <= 900) {
|
|
this->friendlyText = LookupMessage(MSI_FRIENDLY);
|
|
low = 750;
|
|
high = 900;
|
|
} else if (g_session.m_petFriendly > 900 && g_session.m_petFriendly <= 1000) {
|
|
this->friendlyText = LookupMessage(MSI_VERY_FRIENDLY);
|
|
low = 900;
|
|
high = 1000;
|
|
} else {
|
|
this->friendlyText = LookupMessage(MSI_UNKNOWN);
|
|
low = 0;
|
|
high = 0;
|
|
}
|
|
const float ratio = static_cast<float>(static_cast<unsigned>(g_session.m_petFriendly - low)) / static_cast<float>(static_cast<unsigned>(high - low));
|
|
this->friendlyGauge->SetValue(static_cast<unsigned>(ratio * 100.0f));
|
|
if (!(previous == this->friendlyText)) {
|
|
this->Invalidate();
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008B1240
|
|
// FUNCTION: fn_11745
|
|
void UIMonsterInfoWnd::OnCreate(int, int) {
|
|
const std::string prefix("유저인터페이스\\");
|
|
auto* button = new UIBitmapButton();
|
|
button->SetBitmap((prefix + "btn_ok" + ".bmp").c_str(), 0, 0);
|
|
button->SetBitmap((prefix + "btn_ok_a" + ".bmp").c_str(), 1, 0);
|
|
button->SetBitmap((prefix + "btn_ok_b" + ".bmp").c_str(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight());
|
|
button->Move(this->geometry.width - 46, this->geometry.height - 24);
|
|
button->SetId(184);
|
|
this->AddChild(button);
|
|
this->m_message0 = 184;
|
|
|
|
this->actorId = g_monsterInfoActorId;
|
|
this->name = static_cast<CGameMode*>(g_modeMgr.GetGameMode())->ActorName(g_monsterInfoActorId);
|
|
const std::size_t separator = this->name.find("#");
|
|
if (separator != std::string::npos) {
|
|
this->name.erase(separator, this->name.size());
|
|
}
|
|
this->name = this->FitDisplayText(100, this->name.c_str(), 0, 12, 0);
|
|
}
|
|
|
|
// OFFSET: 0x008A4300
|
|
// FUNCTION: fn_11667
|
|
UIPetInfoWnd::UIPetInfoWnd()
|
|
: UIFrameWnd(0), friendlyGauge(nullptr), friendlyText("") {
|
|
this->autoFeedAvailable = 0;
|
|
this->autoFeedCheck = 0;
|
|
this->nameEdit = nullptr;
|
|
this->saved = nullptr;
|
|
this->renameButton = 0;
|
|
this->statusButton = 0;
|
|
this->feedConfirmationWnd = nullptr;
|
|
}
|
|
|
|
// OFFSET: 0x008A43E0
|
|
// FUNCTION: fn_11668
|
|
UIReplayButton::UIReplayButton() : UIBitmapButton() {
|
|
}
|
|
|
|
// OFFSET: 0x008A4440
|
|
// FUNCTION: fn_11669
|
|
UIReplayControlWnd::UIReplayControlWnd() : UIFrameWnd(0) {
|
|
this->m_paused = false;
|
|
}
|
|
|
|
// OFFSET: 0x008A4500
|
|
// FUNCTION: fn_11670
|
|
UIReplayRECControlWnd::UIReplayRECControlWnd(int mode)
|
|
: UIFrameWnd(0), mode(mode), recordStart(0) {
|
|
for (int i = 0; i < 10; ++i) {
|
|
this->options[i] = nullptr;
|
|
this->recordOptions[i] = 0;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008A45A0
|
|
// FUNCTION: fn_11671
|
|
UISelectReplayDataWnd::UISelectReplayDataWnd() : UIFrameWnd(0) {
|
|
this->m_list = nullptr;
|
|
this->m_serverButton = nullptr;
|
|
this->m_texts[0] = nullptr;
|
|
this->m_texts[1] = nullptr;
|
|
this->m_texts[2] = nullptr;
|
|
this->m_texts[3] = nullptr;
|
|
}
|
|
|
|
// OFFSET: 0x008A4640
|
|
// FUNCTION: fn_11672
|
|
UISelectServerWnd::UISelectServerWnd()
|
|
: UIFrameWnd(0) {
|
|
this->m_serverList = nullptr;
|
|
this->m_okButton = nullptr;
|
|
}
|
|
|
|
// OFFSET: 0x008A46E0
|
|
// FUNCTION: fn_11673
|
|
UITalkboxTrapInputWnd::UITalkboxTrapInputWnd()
|
|
: UIFrameWnd(0) {
|
|
}
|
|
|
|
// OFFSET: 0x008A4E00
|
|
// FUNCTION: fn_11677
|
|
UICntWnd::~UICntWnd() = default;
|
|
|
|
// OFFSET: 0x008A5050
|
|
// FUNCTION: fn_11679
|
|
UILoginWnd::~UILoginWnd() = default;
|
|
|
|
// OFFSET: 0x008A54C0
|
|
// FUNCTION: fn_11681
|
|
UIPetInfoWnd::~UIPetInfoWnd() {
|
|
if (this->feedConfirmationWnd) {
|
|
g_windowMgr.Schedule(this->feedConfirmationWnd);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008A5CC0
|
|
// FUNCTION: fn_11686
|
|
EncryptedName<80, 0xF3CB6F7711A71B6DULL>& HangameJoinUrl::operator()() const {
|
|
constexpr auto sourceText = CRYPT_NAME("http://ro.hangame.com/login/loginstep.asp?prevURL=/NHNCommon/NHN/Memberjoin.asp", 0xF3CB6F7711A71B6DULL);
|
|
const auto& source = sourceText.data;
|
|
thread_local EncryptedName<sizeof(source), 0xF3CB6F7711A71B6DULL> name(source);
|
|
return name;
|
|
}
|
|
|
|
// OFFSET: 0x008BE490
|
|
// FUNCTION: fn_11805
|
|
int UILoginWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) {
|
|
switch (message) {
|
|
case UM_COMBOBOX_SELECTED:
|
|
if (sender == this->loginTypeCombo) {
|
|
if (a == 0) {
|
|
const char source[] = {'\x1A', '\x3D', '\x79', '\xB9', '\xA1'};
|
|
thread_local EncryptedName<sizeof(source), 0x9FED7DA189490D5DULL> name(source);
|
|
this->loginExtra = name.Text();
|
|
} else if (a == 1) {
|
|
const char source[] = {'\x86', '\x77', '\xF5', '\x20', '\xE1'};
|
|
thread_local EncryptedName<sizeof(source), 0xFBD599E117C547C1ULL> name(source);
|
|
this->loginExtra = name.Text();
|
|
} else {
|
|
const char source[] = {'\x10', '\x9D', '\xBC', '\x33', '\xE2', '\x64', '\x01', '\x37', '\x04', '\x90', '\xB4', '\x32', '\xF8', '\x7D', '\x1B',
|
|
'\x37', '\x06', '\x9F', '\xB6', '\x2E', '\xFE', '\x33', '\x09', '\x78', '\x10', '\x9D', '\xB3', '\x7C', '\x8D'};
|
|
thread_local EncryptedName<sizeof(source), 0x176F138D5DD7F365ULL> name(source);
|
|
g_windowMgr.Confirm(name.Text(), 0, false, false, 0, "Message", 280, 120, 0);
|
|
goto quit;
|
|
}
|
|
}
|
|
return 0;
|
|
case UM_COMMAND:
|
|
switch (a) {
|
|
case ID_MAKEACCOUNT:
|
|
if (g_serviceType == 0) {
|
|
if (g_session.m_channelCopId == 1) {
|
|
g_modeMgr.Quit();
|
|
const char* url = HangameJoinUrl()().Text();
|
|
const char verbSource[] = {'\xDC', '\x17', '\x3C', '\xE1', '\xDF'};
|
|
thread_local EncryptedName<sizeof(verbSource), 0x839B27DF8F5967B3ULL> verbName(verbSource);
|
|
ShellExecuteA(hWnd, verbName.Text(), url, nullptr, nullptr, SW_SHOWNORMAL);
|
|
break;
|
|
}
|
|
if (g_windowMgr.Confirm(LookupMessage(MSI_SELECTCHARWND_RESERVE_TO_DEL_CHAR), 2, true, false, 0, "Message", 280, 120, 0) != 187) {
|
|
break;
|
|
}
|
|
}
|
|
g_modeMgr.Quit();
|
|
this->OpenWebPage();
|
|
break;
|
|
case ID_LOGIN: {
|
|
const char soundSource[] = {'\xDC', '\xA3', '\x0F', '\xCF', '\xB1', '\x3D', '\x97', '\xEB', '\x4B', '\x22', '\xA8', '\x09', '\x0D'};
|
|
thread_local EncryptedName<sizeof(soundSource), 0x452FEF0D7FC95565ULL> soundName(soundSource);
|
|
g_soundMgr->PlayWave(soundName.Text(), 0.0f, 0.0f, 0.0f, 250, 40, 1.0f, 0);
|
|
if (this->passwordEdit->Length() >= 6 && this->idEdit->Length() >= 4) {
|
|
g_modeMgr.gameMode->SendMsg(LMM_CONNECT_TO_ACSVR, 0, 0, 0, 0);
|
|
StringFormat(g_launchAccountPassword, 24, static_cast<std::size_t>(-1), "%s", this->idEdit->Text());
|
|
g_modeMgr.gameMode->SendMsg(LMM_PASSWORD, reinterpret_cast<int>(this->passwordEdit->Text()), 0, 0, 0);
|
|
g_modeMgr.gameMode->SendMsg(LMM_ID, reinterpret_cast<int>(this->idEdit->Text()), 0, 0, 0);
|
|
g_modeMgr.gameMode->SendMsg(LMM_SET_LOGIN_EXTRA, reinterpret_cast<int>(this->loginExtra), 0, 0, 0);
|
|
g_windowMgr.CloseWindow(WID_LOGINWND);
|
|
this->SaveLogin();
|
|
} else if (this->idEdit->Length() < 4) {
|
|
g_windowMgr.Confirm(FormatOwnedString(LookupMessage(MSI_BASIC_EXP_MSG2_EXCEPT_PREMIUM), 4).c_str(), 0, true, false, 0, "Message", 280, 120, 0);
|
|
} else {
|
|
g_windowMgr.Confirm(FormatOwnedString(LookupMessage(MSI_SWAP_EQUIPITEM_CANNOT_ADD_ITEM), 6).c_str(), 0, true, false, 0, "Message", 280, 120, 0);
|
|
}
|
|
break;
|
|
}
|
|
case ID_CANCEL:
|
|
g_loginCancelRequested = 1;
|
|
g_modeMgr.gameMode->SendMsg(LMM_GOTOSELECTACCOUNT, 0, 0, 0, 0);
|
|
break;
|
|
case ID_EXIT:
|
|
this->SaveLogin();
|
|
if (g_windowMgr.Confirm(LookupMessage(MSI_DO_YOU_REALLY_WANT_TO_QUIT), 2, true, false, 0, "Message", 280, 120, 0) == 187) {
|
|
goto quit;
|
|
}
|
|
break;
|
|
case ID_CHECK:
|
|
this->saveId = b;
|
|
this->SaveLogin();
|
|
break;
|
|
case ID_CLASSCOMBO: {
|
|
if (g_windowMgr.comboBoxWnd != nullptr) {
|
|
g_windowMgr.CloseWindow(WID_COMBOBOXWND);
|
|
}
|
|
UIWindow* list = g_windowMgr.EnsureWindow(WID_COMBOBOXWND);
|
|
this->accountListOpen = 1;
|
|
const int count = static_cast<int>(this->savedAccounts.size());
|
|
for (unsigned int index = 0; index < this->savedAccounts.size(); ++index) {
|
|
list->SendMsg(nullptr, UM_ADDITEM, reinterpret_cast<std::intptr_t>(this->savedAccounts[index].c_str()), 0, 0, 0);
|
|
}
|
|
list->SendMsg(nullptr, UM_SETCURITEM, 0, 0, 0, 0);
|
|
int height = count * 16;
|
|
if (height > 48) {
|
|
height = 48;
|
|
}
|
|
list->Resize(74, height);
|
|
list->SendMsg(nullptr, UM_SET_CALLER_WID, 3, 0, 0, 0);
|
|
int x = 60;
|
|
int y = 96;
|
|
this->ToScreen(x, y);
|
|
list->Move(x + 1, y);
|
|
break;
|
|
}
|
|
case 359:
|
|
g_session.m_channelCopId = 0;
|
|
this->Invalidate();
|
|
break;
|
|
case 360:
|
|
g_session.m_channelCopId = 2;
|
|
this->Invalidate();
|
|
break;
|
|
}
|
|
return 0;
|
|
case UM_ENABLE_CANCEL:
|
|
return 0;
|
|
default:
|
|
return UIFrameWnd::SendMsg(sender, message, a, b, c, d);
|
|
}
|
|
|
|
quit:
|
|
g_modeMgr.gameMode->SendMsg(MM_QUIT, 0, 0, 0, 0);
|
|
g_windowMgr.Schedule(this);
|
|
return 0;
|
|
}
|
|
|
|
// OFFSET: 0x008BE200
|
|
// FUNCTION: fn_11804
|
|
int UILoginOTPWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) {
|
|
switch (message) {
|
|
case UM_COMMAND: {
|
|
if (a == 185) {
|
|
if (g_windowMgr.Confirm(LookupMessage(MSI_DO_YOU_REALLY_WANT_TO_QUIT), 2, true, false, 0, "Message", 280, 120, 0) == 187) {
|
|
g_modeMgr.gameMode->SendMsg(MM_QUIT, 0, 0, 0, 0);
|
|
g_windowMgr.Schedule(this);
|
|
}
|
|
} else if (a == 382) {
|
|
constexpr auto soundSourceText = CRYPT_NAME("버튼소리.wav", 0x7321C3814F8799E1ULL);
|
|
const auto& soundSource = soundSourceText.data;
|
|
thread_local EncryptedName<sizeof(soundSource), 0x7321C3814F8799E1ULL> soundName(soundSource);
|
|
g_soundMgr->PlayWave(soundName.Text(), 0.0f, 0.0f, 0.0f, 250, 40, 1.0f, 0);
|
|
if (this->authCodeEdit->Length() == 8) {
|
|
g_modeMgr.gameMode->SendMsg(LMM_SET_AUTH_CODE, reinterpret_cast<int>(this->authCodeEdit->Text()), 0, 0, 0);
|
|
g_modeMgr.gameMode->SendMsg(LMM_SEND_LOGIN_AUTH_CODE, 0, 0, 0, 0);
|
|
g_windowMgr.CloseWindow(WID_LOGINOTPWND);
|
|
} else {
|
|
g_windowMgr.Confirm(LookupMessage(MSI_FAIL_SERVICE_CHECKING_ERROR), 0, true, false, 0, "Message", 280, 120, 0);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case UM_REFRESH: {
|
|
this->authCodeEdit->SetText("");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return UIFrameWnd::SendMsg(sender, message, a, b, c, d);
|
|
}
|
|
|
|
// OFFSET: 0x008ADC80
|
|
// FUNCTION: fn_11740
|
|
void UIHomunInfoWnd::OnCreate(int, int) {
|
|
this->AddCloseButton("", 0);
|
|
this->nameEdit = new UIEditCtrl2();
|
|
this->nameEdit->SetSize(80, 16);
|
|
char* const name = reinterpret_cast<char*>(&g_session.spAndHomunculusStats[0x0C]);
|
|
if (std::strcmp(name, "") == 0) {
|
|
std::sprintf(name, g_session.GetJobName(g_session.m_homunJob, -1));
|
|
}
|
|
this->nameEdit->Move(135, 22);
|
|
this->nameEdit->SetText(name);
|
|
this->nameEdit->maximum = 50;
|
|
this->nameEdit->Background(232, 232, 232);
|
|
this->AddChild(this->nameEdit);
|
|
{
|
|
const std::string bitmap("유저인터페이스\\btn_del");
|
|
this->button = new UIBitmapButton();
|
|
this->button->SetBitmap((bitmap + ".bmp").c_str(), 0, 0);
|
|
this->button->SetBitmap((bitmap + "_a.bmp").c_str(), 1, 0);
|
|
this->button->SetBitmap((bitmap + "_b.bmp").c_str(), 2, 0);
|
|
this->button->SetSize(this->button->BitmapWidth(), this->button->BitmapHeight());
|
|
this->button->Move(187, 44);
|
|
this->button->SetId(291);
|
|
this->AddChild(this->button);
|
|
}
|
|
{
|
|
const std::string bitmap("유저인터페이스\\btn_skill");
|
|
this->button = new UIBitmapButton();
|
|
this->button->SetBitmap((bitmap + ".bmp").c_str(), 0, 0);
|
|
this->button->SetBitmap((bitmap + "_a.bmp").c_str(), 1, 0);
|
|
this->button->SetBitmap((bitmap + "_b.bmp").c_str(), 2, 0);
|
|
this->button->SetSize(this->button->BitmapWidth(), this->button->BitmapHeight());
|
|
this->button->Move(232, 44);
|
|
this->button->SetId(289);
|
|
this->AddChild(this->button);
|
|
}
|
|
{
|
|
const std::string bitmap("유저인터페이스\\btn_feed");
|
|
this->button = new UIBitmapButton();
|
|
this->button->SetBitmap((bitmap + ".bmp").c_str(), 0, 0);
|
|
this->button->SetBitmap((bitmap + "_a.bmp").c_str(), 1, 0);
|
|
this->button->SetBitmap((bitmap + "_b.bmp").c_str(), 2, 0);
|
|
this->button->SetSize(this->button->BitmapWidth(), this->button->BitmapHeight());
|
|
this->button->Move(210, 155);
|
|
this->button->SetId(290);
|
|
this->AddChild(this->button);
|
|
this->button->Move(210, 105);
|
|
}
|
|
{
|
|
const std::string bitmap("유저인터페이스\\btn_rewrite");
|
|
this->button = new UIBitmapButton();
|
|
this->button->SetBitmap((bitmap + ".bmp").c_str(), 0, 0);
|
|
this->button->SetBitmap((bitmap + "_a.bmp").c_str(), 1, 0);
|
|
this->button->SetBitmap((bitmap + "_b.bmp").c_str(), 2, 0);
|
|
this->button->SetSize(this->button->BitmapWidth(), this->button->BitmapHeight());
|
|
this->button->Move(232, 21);
|
|
this->button->SetId(184);
|
|
this->AddChild(this->button);
|
|
}
|
|
|
|
this->hpBar = new UIBarGraphHomun();
|
|
this->hpBar->SetValues([]() -> std::int64_t { return g_session.m_homunHp; },
|
|
[]() -> std::int64_t { return *reinterpret_cast<const int*>(g_session.homunMaxHp); });
|
|
this->hpBar->SetSize(157, 9);
|
|
this->hpBar->Move(117, 73);
|
|
this->AddChild(this->hpBar);
|
|
|
|
this->spBar = new UIBarGraphHomun();
|
|
this->spBar->SetValues([]() -> std::int64_t { return g_session.m_homunSp; }, []() -> std::int64_t { return g_session.homunMaxSp; });
|
|
this->spBar->SetSize(157, 9);
|
|
this->spBar->Move(117, 88);
|
|
this->AddChild(this->spBar);
|
|
|
|
this->expBar = new UIINT64BarGraph();
|
|
this->expBar->SetValues(g_session.m_homunExp, g_session.m_homunMaxExp);
|
|
this->expBar->m_plainColor = 1;
|
|
this->expBar->SetSize(102, 6);
|
|
this->expBar->Move(101, 119);
|
|
this->AddChild(this->expBar);
|
|
|
|
this->intimacyBar = new UIBarGraph4();
|
|
this->intimacyBar->m_plainColor = false;
|
|
this->intimacyBar->SetSize(102, 6);
|
|
this->intimacyBar->Move(101, 145);
|
|
this->intimacyBar->SetValues(&g_session.homunHunger, &g_session.homunMaxHunger);
|
|
this->AddChild(this->intimacyBar);
|
|
this->m_message0 = 201;
|
|
|
|
this->autoFeedCheckBox = new UICheckBox();
|
|
this->autoFeedCheckBox->SetSize(12, 12);
|
|
this->autoFeedCheckBox->Move(210, 142);
|
|
this->autoFeedCheckBox->SetBitmaps("유저인터페이스\\checkbox_1.bmp", "유저인터페이스\\checkbox_0.bmp");
|
|
this->autoFeedCheckBox->SetChecked(g_session.m_homunculusAutoFeed);
|
|
this->AddChild(this->autoFeedCheckBox);
|
|
}
|
|
|
|
// OFFSET: 0x008B7DB0
|
|
// FUNCTION: fn_11763
|
|
void UIHomunInfoWnd::Paint() {
|
|
auto* background = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve("유저인터페이스\\basic_interface\\homuninfo_bg.bmp")));
|
|
this->DrawBitmap(0, 0, background, false);
|
|
DrawFilledRoundedBorder(*this, 0, this->geometry.height - 40, this->geometry.width, 40, 0xFFFFFF);
|
|
char title[32];
|
|
std::sprintf(title, LookupMessage(MSI_HOMUN_INFO));
|
|
this->DrawTextAt(5, 2, title, 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(100, 24, LookupMessage(MSI_NAME), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(100, 47, LookupMessage(MSI_LEVEL), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(100, 105, LookupMessage(MSI_HOMUN_EXP), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(100, 131, LookupMessage(MSI_PET_HUNGRY), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(100, 159, LookupMessage(MSI_PET_FRIENDLY), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(140, 159, ":", 0, 0, 12, 0, 0, 0);
|
|
const int* const stats = reinterpret_cast<const int*>(&g_session.spAndHomunculusStats[0x2C]);
|
|
char number[12];
|
|
int bytes = std::sprintf(number, "%d", stats[0]);
|
|
this->DrawRightAlignedText(79, 24, number, bytes, 1, 14, 0, 0);
|
|
bytes = std::sprintf(number, "%d", stats[1]);
|
|
this->DrawRightAlignedText(79, 42, number, bytes, 1, 14, 0, 0);
|
|
bytes = std::sprintf(number, "%d", stats[2]);
|
|
this->DrawRightAlignedText(79, 60, number, bytes, 1, 14, 0, 0);
|
|
bytes = std::sprintf(number, "%d", stats[3]);
|
|
this->DrawRightAlignedText(79, 78, number, bytes, 1, 14, 0, 0);
|
|
bytes = std::sprintf(number, "%d", stats[4]);
|
|
this->DrawRightAlignedText(79, 96, number, bytes, 1, 14, 0, 0);
|
|
bytes = std::sprintf(number, "%d", stats[5]);
|
|
this->DrawRightAlignedText(79, 114, number, bytes, 1, 14, 0, 0);
|
|
bytes = std::sprintf(number, "%d", stats[6]);
|
|
this->DrawRightAlignedText(79, 132, number, bytes, 1, 14, 0, 0);
|
|
bytes = std::sprintf(number, "%d", (2000 - stats[7]) / 10);
|
|
this->DrawRightAlignedText(79, 150, number, bytes, 1, 14, 0, 0);
|
|
char level[12];
|
|
_itoa(*reinterpret_cast<const int*>(g_session.homunLevel), level, 10);
|
|
this->DrawTextAt(135, 47, level, 0, 0, 12, 0, 0, 0);
|
|
if (g_session.m_homunJob == -1) {
|
|
return;
|
|
}
|
|
|
|
char text[24];
|
|
bytes = std::sprintf(text, "%lld", g_session.m_homunMaxExp);
|
|
this->DrawRightAlignedText(205, 104, text, bytes, 1, 14, 0, 0);
|
|
bytes = std::sprintf(text, "%d / %d", g_session.homunHunger, 100);
|
|
this->DrawRightAlignedText(200, 130, text, bytes, 1, 14, 0, 0);
|
|
const int intimacy = g_session.homunFriendly;
|
|
if (intimacy >= 0 && intimacy <= 3) {
|
|
std::strcpy(text, LookupMessage(MSI_VERYHATE));
|
|
} else if (intimacy > 3 && intimacy <= 10) {
|
|
std::strcpy(text, LookupMessage(MSI_HATE));
|
|
} else if (intimacy > 10 && intimacy <= 100) {
|
|
std::strcpy(text, LookupMessage(MSI_VERY_AWKWARD));
|
|
} else if (intimacy > 100 && intimacy <= 250) {
|
|
std::strcpy(text, LookupMessage(MSI_AWKWARD));
|
|
} else if (intimacy > 250 && intimacy <= 750) {
|
|
std::strcpy(text, LookupMessage(MSI_NORMAL));
|
|
} else if (intimacy > 750 && intimacy <= 910) {
|
|
std::strcpy(text, LookupMessage(MSI_FRIENDLY));
|
|
} else if (intimacy > 910 && intimacy <= 1000) {
|
|
std::strcpy(text, LookupMessage(MSI_VERY_FRIENDLY));
|
|
} else {
|
|
std::strcpy(text, LookupMessage(MSI_UNKNOWN));
|
|
}
|
|
this->DrawTextAt(150, 159, text, 0, 0, 12, 0, 0, 0);
|
|
this->DrawWrappedFormattedText(225, 136, std::string(LookupMessage(MSI_HOMUN_SELF_FEEDING_ON)), 0, 0, 0, 0, 12, 0, 0);
|
|
this->DrawWrappedFormattedText(8, 180, std::string(LookupMessage(MSI_HOMUN_TARGET_NOT_EXIST_HOMUN_TARGAT)), 0, 0, 0, 0, 12, 0xFF, 0);
|
|
}
|
|
|
|
// OFFSET: 0x008BDD10
|
|
// FUNCTION: fn_11803
|
|
int UIHomunInfoWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) {
|
|
if (this->feedConfirmation && sender != this->feedConfirmation) {
|
|
return 0;
|
|
}
|
|
|
|
switch (message) {
|
|
case UM_DEFPUSH:
|
|
return 0;
|
|
case UM_COMMAND:
|
|
this->RecordResponse(static_cast<int>(a), b, c, d);
|
|
|
|
switch (a) {
|
|
case ID_OK: {
|
|
char* const name = reinterpret_cast<char*>(&g_session.spAndHomunculusStats[0x0C]);
|
|
if (std::strlen(this->nameEdit->Text()) >= 24) {
|
|
g_windowMgr.Confirm(LookupMessage(MSI_HOMUN_NAME_IN23), 0, true, false, 0, "Message", 280, 120, 0);
|
|
} else if (_mbsstr(reinterpret_cast<const unsigned char*>(this->nameEdit->Text()), reinterpret_cast<const unsigned char*>(s_messageBoxItemLinkOpening.c_str())) ||
|
|
_mbsstr(reinterpret_cast<const unsigned char*>(this->nameEdit->Text()), reinterpret_cast<const unsigned char*>(s_messageBoxItemLinkClosing.c_str()))) {
|
|
g_windowMgr.Confirm(LookupMessage(MSI_STYLING_SHOP_OPEN_COUPON), 0, true, false, 0, "Message", 280, 120, 0);
|
|
} else {
|
|
char text[512];
|
|
std::sprintf(text, LookupMessage(MSI_BLOCK_CALL_NOTIFY), this->nameEdit->Text());
|
|
if (g_windowMgr.Confirm(text, 2, false, false, 0, "Message", 280, 120, 0) != 188) {
|
|
if (g_forbiddenWords.Contains(this->nameEdit->Text()) != true) {
|
|
g_modeMgr.GetGameMode()->SendMsg(MM_MER_RENAME, reinterpret_cast<int>(this->nameEdit->Text()), 0, 0, 0);
|
|
std::sprintf(name, this->nameEdit->Text());
|
|
this->Invalidate();
|
|
return 0;
|
|
}
|
|
|
|
g_windowMgr.Confirm(LookupMessage(MSI_CANNOT_SELL_IN_PRIVATE_TAB), 0, true, false, 0, "Message", 280, 120, 0);
|
|
}
|
|
|
|
this->nameEdit->SetText(name);
|
|
this->nameEdit->Invalidate();
|
|
}
|
|
return 0;
|
|
}
|
|
case ID_CLOSE:
|
|
g_windowMgr.CloseWindow(WID_HOMUNINFOWND);
|
|
return 0;
|
|
case ID_CHECK:
|
|
if (sender == this->autoFeedCheckBox) {
|
|
if (b > 0) {
|
|
g_session.SendHomunculusAutoFeedOption(1);
|
|
} else {
|
|
g_session.SendHomunculusAutoFeedOption(0);
|
|
}
|
|
}
|
|
return 0;
|
|
case ID_OPEN_HOMUNSKILLLIST:
|
|
if (!g_windowMgr.CloseWindow(WID_SKILLLISTWND_SKILLTAB_0)) {
|
|
g_windowMgr.EnsureWindow(WID_SKILLLISTWND_SKILLTAB_0);
|
|
}
|
|
return 0;
|
|
case ID_FEED_TO_HOMUN:
|
|
this->feedConfirmation = new UINormalMB();
|
|
this->feedConfirmation->Create(this, LookupMessage(MSI_SURE_TO_FEED_PET), 2, true, nullptr, 280, 120, nullptr);
|
|
g_windowMgr.AddRendered(this->feedConfirmation);
|
|
return 0;
|
|
case ID_DELETE_HOMUN: {
|
|
CMode* mode = g_modeMgr.GetGameMode();
|
|
if (g_windowMgr.Confirm(LookupMessage(MSI_DELETE_HOMUN), 2, false, false, 0, "Message", 280, 120, 0) == 187) {
|
|
mode->SendMsg(MM_COMMAND_HOMUN, 2, 0, 0, 0);
|
|
g_windowMgr.CloseWindow(WID_HOMUNINFOWND);
|
|
g_windowMgr.CloseWindow(WID_SKILLLISTWND_SKILLTAB_0);
|
|
g_session.ClearHomunStatus();
|
|
g_session.homunAlive = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
case 488: {
|
|
CMode* mode = g_modeMgr.GetGameMode();
|
|
if (sender == this->feedConfirmation && b == 187) {
|
|
if (g_windowMgr.LookupWindow(WID_EXCHANGEUI)) {
|
|
g_windowMgr.SendNotice(UIM_PUSHINTOCHATHISTORY, reinterpret_cast<std::intptr_t>(LookupMessage(MSI_EXCHANGED_FAILED)), 255, 0, 0, 0);
|
|
} else {
|
|
mode->SendMsg(MM_COMMAND_HOMUN, 1, 0, 0, 0);
|
|
}
|
|
}
|
|
g_windowMgr.Schedule(this->feedConfirmation);
|
|
this->feedConfirmation = nullptr;
|
|
return 0;
|
|
}
|
|
default:
|
|
return 0;
|
|
}
|
|
case UM_SETINFO:
|
|
this->saved = reinterpret_cast<HomunInfoWndInfo*>(a);
|
|
if (!this->saved->IsValid()) {
|
|
this->saved->Reset();
|
|
}
|
|
|
|
this->Move(this->saved->x, this->saved->y);
|
|
return 0;
|
|
default:
|
|
return UIFrameWnd::SendMsg(sender, message, a, b, c, d);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008B2820
|
|
// FUNCTION: fn_11747
|
|
void UIPetInfoWnd::OnCreate(int, int) {
|
|
this->AddCloseButton("", 0);
|
|
this->nameEdit = new UIEditCtrl2();
|
|
this->nameEdit->SetSize(80, 16);
|
|
if (std::strcmp(g_session.petName, "") == 0) {
|
|
std::sprintf(g_session.petName, g_session.GetJobName(g_session.petJob, -1));
|
|
}
|
|
this->nameEdit->Move(135, 24);
|
|
this->nameEdit->SetText(g_session.petName);
|
|
this->nameEdit->maximum = 50;
|
|
this->nameEdit->Background(232, 232, 232);
|
|
this->AddChild(this->nameEdit);
|
|
{
|
|
const std::string prefix("유저인터페이스\\");
|
|
this->renameButton = new UIBitmapButton();
|
|
this->renameButton->SetBitmap((prefix + "btn_rewrite" + ".bmp").c_str(), 0, 0);
|
|
this->renameButton->SetBitmap((prefix + "btn_rewrite_a" + ".bmp").c_str(), 1, 0);
|
|
this->renameButton->SetBitmap((prefix + "btn_rewrite_b" + ".bmp").c_str(), 2, 0);
|
|
this->renameButton->SetSize(this->renameButton->BitmapWidth(), this->renameButton->BitmapHeight());
|
|
this->renameButton->Move(230, 21);
|
|
this->renameButton->SetId(184);
|
|
this->AddChild(this->renameButton);
|
|
}
|
|
|
|
const char tooltip[] = "Pet Command";
|
|
this->statusButton = new UINoneVisibleButton();
|
|
this->statusButton->SetSize(120, 18);
|
|
this->statusButton->Move(150, 44);
|
|
this->statusButton->SetId(268);
|
|
this->AddChild(this->statusButton);
|
|
{
|
|
const std::string prefix("유저인터페이스\\basic_interface\\");
|
|
UIBitmapButton* button = new UIBitmapButton();
|
|
button->SetBitmap((prefix + "txtbox_btn_a" + ".bmp").c_str(), 0, 0);
|
|
button->SetBitmap((prefix + "txtbox_btn_b" + ".bmp").c_str(), 1, 0);
|
|
button->SetBitmap((prefix + "txtbox_btn_c" + ".bmp").c_str(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight());
|
|
button->Move(270 - button->BitmapWidth(), 44);
|
|
button->SetTooltip(tooltip);
|
|
button->SetId(268);
|
|
this->AddChild(button);
|
|
}
|
|
|
|
this->friendlyText = LookupMessage(MSI_UNKNOWN);
|
|
this->friendlyGauge = new UIPetInfoBarGraph();
|
|
this->friendlyGauge->SetSize(120, 9);
|
|
this->friendlyGauge->Move(145, 105);
|
|
this->AddChild(this->friendlyGauge);
|
|
this->UpdateFriendlyGauge();
|
|
this->m_message0 = 201;
|
|
|
|
const int petEgg = std::atoi(LookupClientItemByIdentity(g_session.m_inventoryItems, g_session.petEggIndex).itemId.c_str());
|
|
this->autoFeedAvailable = g_petEvolutionMgr->IsAutoFeeding(petEgg);
|
|
if (this->autoFeedAvailable == true) {
|
|
this->autoFeedCheck = new UICheckBox();
|
|
this->autoFeedCheck->SetSize(12, 12);
|
|
this->autoFeedCheck->Move(this->TextWidth(LookupMessage(MSI_PET_AUTO_FEEDING_OFF), 0, 0, 12, 0, 0) + 110, 159);
|
|
this->autoFeedCheck->SetBitmaps("유저인터페이스\\checkbox_1.bmp", "유저인터페이스\\checkbox_0.bmp");
|
|
this->autoFeedCheck->SetChecked(g_petAutoFeed);
|
|
this->AddChild(this->autoFeedCheck);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008BFE80
|
|
// FUNCTION: fn_11812
|
|
int UIPetInfoWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) {
|
|
if (this->feedConfirmationWnd && sender != this->feedConfirmationWnd) {
|
|
return 0;
|
|
}
|
|
|
|
switch (message) {
|
|
case UM_DEFPUSH:
|
|
return 0;
|
|
case UM_COMBOBOX_SELECTED: {
|
|
CMode* mode = g_modeMgr.GetGameMode();
|
|
switch (a) {
|
|
case 467:
|
|
if (g_windowMgr.rodexComposeWnd) {
|
|
g_windowMgr.SendNotice(UIM_PUSHINTOCHATHISTORY, reinterpret_cast<std::intptr_t>(LookupMessage(MSI_REFINING_FAIL_ITEM_DISAPPEAR)), 255, 0, 0, 0);
|
|
break;
|
|
}
|
|
this->feedConfirmationWnd = new UINormalMB();
|
|
this->feedConfirmationWnd->Create(this, LookupMessage(MSI_SURE_TO_FEED_PET), 2, true, nullptr, 280, 120, nullptr);
|
|
g_windowMgr.AddRendered(this->feedConfirmationWnd);
|
|
g_windowMgr.CloseWindow(WID_COMBOBOXIDWND);
|
|
return 0;
|
|
case 468:
|
|
mode->SendMsg(MM_COMMAND_PET, 2, 0, 0, 0);
|
|
g_windowMgr.CloseWindow(WID_COMBOBOXIDWND);
|
|
return 0;
|
|
case 469:
|
|
mode->SendMsg(MM_COMMAND_PET, 4, 0, 0, 0);
|
|
g_windowMgr.CloseWindow(WID_COMBOBOXIDWND);
|
|
return 0;
|
|
case 470:
|
|
mode->SendMsg(MM_COMMAND_PET, 3, 0, 0, 0);
|
|
g_windowMgr.CloseWindow(WID_COMBOBOXIDWND);
|
|
return 0;
|
|
case 471:
|
|
if (g_session.m_petFriendly > 900) {
|
|
g_windowMgr.CloseWindow(WID_COMBOBOXIDWND);
|
|
UIWindow* window = g_windowMgr.EnsureWindow(WID_PETEVOLUTIONWND);
|
|
const int petEgg = LookupClientItemByIdentity(g_session.m_inventoryItems, g_session.petEggIndex).GetItemId();
|
|
window->SendMsg(nullptr, UM_SET_PET_EVOLUTION_MATERIALS, petEgg, b, 0, 0);
|
|
this->SendMsg(nullptr, UM_COMMAND, ID_CLOSE, 0, 0, 0);
|
|
g_windowMgr.CloseWindow(WID_COMBOBOXIDWND);
|
|
return 0;
|
|
}
|
|
g_windowMgr.SendNotice(UIM_PUSHINTOCHATHISTORY, reinterpret_cast<std::intptr_t>(LookupMessage(MSI_PET_AUTO_FEEDING_ON)), 255, 0, 0, 0);
|
|
break;
|
|
}
|
|
g_windowMgr.CloseWindow(WID_COMBOBOXIDWND);
|
|
return 0;
|
|
}
|
|
case UM_COMMAND:
|
|
if (a == 184 || a == 201) {
|
|
this->RecordResponse(static_cast<int>(a), b, c, d);
|
|
}
|
|
|
|
switch (a) {
|
|
case ID_OK:
|
|
if (std::strlen(this->nameEdit->Text()) >= 24) {
|
|
g_windowMgr.Confirm(LookupMessage(MSI_PETNAME_IN23), 0, true, false, 0, "Message", 280, 120, 0);
|
|
} else if (_mbsstr(reinterpret_cast<const unsigned char*>(this->nameEdit->Text()), reinterpret_cast<const unsigned char*>(s_messageBoxItemLinkOpening.c_str())) ||
|
|
_mbsstr(reinterpret_cast<const unsigned char*>(this->nameEdit->Text()), reinterpret_cast<const unsigned char*>(s_messageBoxItemLinkClosing.c_str()))) {
|
|
g_windowMgr.Confirm(LookupMessage(MSI_STYLING_SHOP_OPEN_COUPON), 0, true, false, 0, "Message", 280, 120, 0);
|
|
} else {
|
|
char text[512];
|
|
std::sprintf(text, LookupMessage(MSI_STORE_ASSISTANT_TRADE_CNT), this->nameEdit->Text());
|
|
if (g_windowMgr.Confirm(text, 2, false, false, 0, "Message", 280, 120, 0) != 188) {
|
|
if (g_forbiddenWords.Contains(this->nameEdit->Text()) != true) {
|
|
g_modeMgr.GetGameMode()->SendMsg(MM_PET_RENAME, reinterpret_cast<int>(this->nameEdit->Text()), 0, 0, 0);
|
|
std::sprintf(g_session.petName, this->nameEdit->Text());
|
|
this->Invalidate();
|
|
return 0;
|
|
}
|
|
|
|
g_windowMgr.Confirm(LookupMessage(MSI_CANNOT_SELL_IN_PRIVATE_TAB), 0, true, false, 0, "Message", 280, 120, 0);
|
|
}
|
|
|
|
this->nameEdit->SetText(g_session.petName);
|
|
this->nameEdit->Invalidate();
|
|
}
|
|
return 0;
|
|
case ID_CLOSE:
|
|
g_windowMgr.CloseWindow(WID_PETINFOWND);
|
|
return 0;
|
|
case ID_CHECK:
|
|
if (sender == this->autoFeedCheck) {
|
|
if (b > 0) {
|
|
g_session.SendPetAutoFeedOption(1);
|
|
} else {
|
|
g_session.SendPetAutoFeedOption(0);
|
|
}
|
|
}
|
|
return 0;
|
|
case 268: {
|
|
UIWindow* menu = g_windowMgr.EnsureWindow(WID_COMBOBOXIDWND);
|
|
std::string feed;
|
|
std::string performance;
|
|
std::string returnToEgg;
|
|
std::string unequip;
|
|
feed = LookupMessage(MSI_PET_FEEDING);
|
|
performance = LookupMessage(MSI_PET_PERFORMANCE);
|
|
returnToEgg = LookupMessage(MSI_PET_RETURN_EGG);
|
|
unequip = LookupMessage(MSI_PET_ACC_OFF);
|
|
menu->SendMsg(nullptr, UM_ADDITEM, reinterpret_cast<std::intptr_t>(feed.c_str()), 467, 0, 0);
|
|
menu->SendMsg(nullptr, UM_ADDITEM, reinterpret_cast<std::intptr_t>(performance.c_str()), 468, 0, 0);
|
|
menu->SendMsg(nullptr, UM_ADDITEM, reinterpret_cast<std::intptr_t>(unequip.c_str()), 469, 0, 0);
|
|
menu->SendMsg(nullptr, UM_ADDITEM, reinterpret_cast<std::intptr_t>(returnToEgg.c_str()), 470, 0, 0);
|
|
const int petEgg = LookupClientItemByIdentity(g_session.m_inventoryItems, g_session.petEggIndex).GetItemId();
|
|
const std::pair<bool, std::vector<int>> targets = g_petEvolutionMgr->GetEvolutionTargets(petEgg);
|
|
if (targets.first == true) {
|
|
for (auto it = targets.second.begin(); it != targets.second.end(); ++it) {
|
|
const int job = g_session.GetPetJobByEggItem(*it);
|
|
std::string text;
|
|
const char* name = g_session.GetPetString(job);
|
|
if (name == nullptr) {
|
|
text = static_cast<const std::string&>(FormatOwnedString(LookupMessage(MSI_PET_EVOLUTION_FAIL_UNKNOWN), g_session.GetJobName(job, -1)));
|
|
} else {
|
|
text = static_cast<const std::string&>(FormatOwnedString(LookupMessage(MSI_PET_EVOLUTION_FAIL_UNKNOWN), name));
|
|
}
|
|
menu->SendMsg(nullptr, UM_ADDITEM, reinterpret_cast<std::intptr_t>(text.c_str()), 471, *it, 0);
|
|
}
|
|
}
|
|
menu->SendMsg(nullptr, UM_SETCURITEM, 0, 0, 0, 0);
|
|
menu->Resize(110, (static_cast<int>(targets.second.size()) + 4) * 16);
|
|
menu->SendMsg(nullptr, UM_SET_CALLER_WID, 88, 0, 0, 0);
|
|
int x = 160;
|
|
int y = 44;
|
|
this->ToScreen(x, y);
|
|
menu->Move(x, y);
|
|
return 0;
|
|
}
|
|
case 488: {
|
|
CMode* mode = g_modeMgr.GetGameMode();
|
|
if (sender == this->feedConfirmationWnd && b == 187) {
|
|
if (g_windowMgr.LookupWindow(WID_EXCHANGEUI)) {
|
|
g_windowMgr.SendNotice(UIM_PUSHINTOCHATHISTORY, reinterpret_cast<std::intptr_t>(LookupMessage(MSI_BARTERITEM_NAME_COUNT)), 255, 0, 0, 0);
|
|
this->feedConfirmationWnd = nullptr;
|
|
return 0;
|
|
}
|
|
mode->SendMsg(MM_COMMAND_PET, 1, 0, 0, 0);
|
|
}
|
|
this->feedConfirmationWnd = nullptr;
|
|
return 0;
|
|
}
|
|
default:
|
|
return 0;
|
|
}
|
|
case UM_SETINFO:
|
|
this->saved = reinterpret_cast<PetInfoWndInfo*>(a);
|
|
if (!this->saved->IsValid()) {
|
|
this->saved->Reset();
|
|
}
|
|
|
|
this->Move(this->saved->x, this->saved->y);
|
|
return 0;
|
|
default:
|
|
return UIFrameWnd::SendMsg(sender, message, a, b, c, d);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008B6520
|
|
// FUNCTION: fn_11751
|
|
void UISelectServerWnd::OnCreate(int width, int height) {
|
|
this->m_serverList = new UIServerListBox();
|
|
this->m_serverList->Configure(12, 22, width - 24, height - 55, 0);
|
|
this->m_serverList->backgroundRed = 240;
|
|
this->m_serverList->backgroundGreen = 240;
|
|
this->m_serverList->backgroundBlue = 240;
|
|
this->m_serverList->SetId(184);
|
|
this->AddChild(this->m_serverList);
|
|
|
|
const std::string prefix("유저인터페이스\\");
|
|
const int ids[4] = {184, 185, 221, 400};
|
|
const char* const names[4][3] = {
|
|
{"btn_ok", "btn_ok_a", "btn_ok_b"},
|
|
{"btn_cancel", "btn_cancel_a", "btn_cancel_b"},
|
|
{"login_interface\\btn_exit", "login_interface\\btn_exit_a", "login_interface\\btn_exit_b"},
|
|
{"replay_interface\\btn_replay", "replay_interface\\btn_replay_a", "replay_interface\\btn_replay_b"},
|
|
};
|
|
int positions[4][2] = {{189, height - 24}, {234, height - 24}, {-100, -100}, {130, height - 24}};
|
|
if (g_modeMgr.GetLoginMode()->cursorType == 30) {
|
|
positions[3][0] = -100;
|
|
positions[3][1] = -100;
|
|
}
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
if (!g_launchPassCommandLine && ids[i] == 400) {
|
|
continue;
|
|
}
|
|
|
|
UIBitmapButton* button = new UIBitmapButton();
|
|
button->SetBitmap((prefix + names[i][0] + ".bmp").c_str(), 0, 0);
|
|
button->SetBitmap((prefix + names[i][1] + ".bmp").c_str(), 1, 0);
|
|
button->SetBitmap((prefix + names[i][2] + ".bmp").c_str(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight());
|
|
button->Move(positions[i][0], positions[i][1]);
|
|
button->SetId(ids[i]);
|
|
this->AddChild(button);
|
|
if (ids[i] == 221) {
|
|
this->m_okButton = button;
|
|
}
|
|
}
|
|
|
|
this->m_message0 = 184;
|
|
}
|
|
|
|
// OFFSET: 0x008B31F0
|
|
// FUNCTION: fn_11748
|
|
void UIReplayControlWnd::OnCreate(int, int) {
|
|
const std::string prefix("유저인터페이스\\replay_interface\\");
|
|
const int ids[6] = {403, 404, 405, 406, 401, 402};
|
|
const int positions[6][2] = {{101, 89}, {149, 89}, {53, 89}, {53, 111}, {5, 89}, {-100, -100}};
|
|
const char* const names[6] = {"replay_stop_", "replay_end_", "replay_speedadd_", "replay_speedmin_", "replay_start_", "replay_pause_"};
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
this->m_buttons[i] = new UIBitmapButton();
|
|
UIBitmapButton* button = static_cast<UIBitmapButton*>(this->m_buttons[i]);
|
|
button->SetBitmap((prefix + names[i] + "a.bmp").c_str(), 0, 0);
|
|
button->SetBitmap((prefix + names[i] + "a.bmp").c_str(), 1, 0);
|
|
button->SetBitmap((prefix + names[i] + "b.bmp").c_str(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight());
|
|
button->Move(positions[i][0], positions[i][1]);
|
|
button->SetId(ids[i]);
|
|
this->AddChild(button);
|
|
}
|
|
|
|
this->m_playButton = new UIReplayButton();
|
|
this->m_playButton->SetBitmap((prefix + names[4] + "a.bmp").c_str(), 0, 0);
|
|
this->m_playButton->SetBitmap((prefix + names[4] + "a.bmp").c_str(), 1, 0);
|
|
this->m_playButton->SetBitmap((prefix + names[4] + "b.bmp").c_str(), 2, 0);
|
|
this->m_playButton->SetSize(this->m_playButton->BitmapWidth(), this->m_playButton->BitmapHeight());
|
|
this->m_playButton->Move(positions[4][0], positions[4][1]);
|
|
this->m_playButton->SetId(ids[4]);
|
|
this->AddChild(this->m_playButton);
|
|
|
|
this->m_pauseButton = new UIReplayButton();
|
|
this->m_pauseButton->SetBitmap((prefix + names[5] + "a.bmp").c_str(), 0, 0);
|
|
this->m_pauseButton->SetBitmap((prefix + names[5] + "a.bmp").c_str(), 1, 0);
|
|
this->m_pauseButton->SetBitmap((prefix + names[5] + "b.bmp").c_str(), 2, 0);
|
|
this->m_pauseButton->SetSize(this->m_pauseButton->BitmapWidth(), this->m_pauseButton->BitmapHeight());
|
|
this->m_pauseButton->Move(positions[5][0], positions[5][1]);
|
|
this->m_pauseButton->SetId(ids[5]);
|
|
this->AddChild(this->m_pauseButton);
|
|
|
|
HotkeyInfo hotkey;
|
|
hotkey = GetHotkeyInfo(*g_session.m_hotkeyScript, 1, 39);
|
|
this->m_playButton->SetTooltip(hotkey.text.c_str());
|
|
this->m_pauseButton->SetTooltip(hotkey.text.c_str());
|
|
hotkey = GetHotkeyInfo(*g_session.m_hotkeyScript, 1, 40);
|
|
static_cast<UIButton*>(this->m_buttons[2])->SetTooltip(hotkey.text.c_str());
|
|
hotkey = GetHotkeyInfo(*g_session.m_hotkeyScript, 1, 41);
|
|
static_cast<UIButton*>(this->m_buttons[3])->SetTooltip(hotkey.text.c_str());
|
|
|
|
this->m_progress = new UIBarGraph4();
|
|
this->m_progress->m_plainColor = true;
|
|
this->m_progress->SetSize(188, 11);
|
|
this->m_progress->Move(5, 72);
|
|
this->m_progress->SetValues(reinterpret_cast<const int*>(&Replay::Instance().elapsed), reinterpret_cast<const int*>(&Replay::Instance().header.duration));
|
|
this->AddChild(this->m_progress);
|
|
|
|
const int textPositions[4][2] = {{8, 26}, {8, 40}, {-100, -100}, {8, 54}};
|
|
for (int i = 0; i < 4; ++i) {
|
|
this->m_texts[i] = new UIStaticText();
|
|
this->m_texts[i]->SetSize(188, 14);
|
|
this->m_texts[i]->SetText("", 0);
|
|
this->m_texts[i]->Move(textPositions[i][0], textPositions[i][1]);
|
|
this->m_texts[i]->SetColor(100, 100, 200);
|
|
this->AddChild(this->m_texts[i]);
|
|
}
|
|
|
|
this->RefreshInfo();
|
|
}
|
|
|
|
// OFFSET: 0x008A9D40
|
|
// FUNCTION: fn_11722
|
|
void UIFrameWnd::DrawSkinBox(const char* name, int x, int y, int width, int height, bool tiled) {
|
|
std::string prefix("유저인터페이스\\sysbox_");
|
|
if (name) {
|
|
prefix = name;
|
|
}
|
|
if (width <= 0) {
|
|
width = this->geometry.width;
|
|
}
|
|
if (height <= 0) {
|
|
height = this->geometry.height;
|
|
}
|
|
|
|
const int innerWidth = width - 28;
|
|
const int left = x + 14;
|
|
const int top = y + 14;
|
|
if (tiled == true) {
|
|
const int columns = TileCount(innerWidth, 14);
|
|
const int rows = TileCount(height - 28, 14);
|
|
for (int row = 0; row < rows; ++row) {
|
|
for (int column = 0; column < columns; ++column) {
|
|
auto* bitmap = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve((prefix + "bg.bmp").c_str())));
|
|
this->DrawBitmap(left + column * 14, top + row * 14, bitmap, false);
|
|
}
|
|
}
|
|
} else {
|
|
unsigned red, green, blue;
|
|
SkinPaletteChannels(ResourceMgr::Instance(), 2, 2, red, green, blue);
|
|
this->FillRegion(left, top, innerWidth, height - 28, RGB(red, green, blue));
|
|
}
|
|
|
|
const int columns = TileCount(innerWidth, 14);
|
|
for (int i = 0; i < columns; ++i) {
|
|
auto* bitmap = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve((prefix + "mu.bmp").c_str())));
|
|
this->DrawBitmap(left + i * 14, y, bitmap, false);
|
|
}
|
|
|
|
auto* bitmap = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve((prefix + "lu.bmp").c_str())));
|
|
this->DrawBitmap(x, y, bitmap, false);
|
|
bitmap = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve((prefix + "ru.bmp").c_str())));
|
|
if (bitmap) {
|
|
this->DrawBitmap(x - bitmap->image.width + width, y, bitmap, false);
|
|
}
|
|
|
|
const int rows = TileCount(height - 28, 14);
|
|
for (int i = 0; i < rows; ++i) {
|
|
bitmap = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve((prefix + "lm.bmp").c_str())));
|
|
this->DrawBitmap(x, top + i * 14, bitmap, false);
|
|
}
|
|
for (int i = 0; i < rows; ++i) {
|
|
bitmap = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve((prefix + "rm.bmp").c_str())));
|
|
if (bitmap) {
|
|
this->DrawBitmap(x - bitmap->image.width + width, top + i * 14, bitmap, false);
|
|
}
|
|
}
|
|
for (int i = 0; i < columns; ++i) {
|
|
bitmap = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve((prefix + "md.bmp").c_str())));
|
|
if (bitmap) {
|
|
this->DrawBitmap(left + i * 14, y - bitmap->image.height + height, bitmap, false);
|
|
}
|
|
}
|
|
|
|
bitmap = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve((prefix + "ld.bmp").c_str())));
|
|
if (bitmap) {
|
|
this->DrawBitmap(x, y - bitmap->image.height + height, bitmap, false);
|
|
}
|
|
bitmap = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(Resolve((prefix + "rd.bmp").c_str())));
|
|
if (bitmap) {
|
|
this->DrawBitmap(x - bitmap->image.width + width, y - bitmap->image.height + height, bitmap, false);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008A8280
|
|
// FUNCTION: fn_11714
|
|
void UIMessageBoxAutoreturn::Configure(const char* text, int timeout) {
|
|
this->messageText = text;
|
|
this->format = text;
|
|
this->started = timeGetTime();
|
|
this->deadline = timeGetTime() + static_cast<unsigned>(timeout);
|
|
const unsigned fraction = (this->deadline - this->started) % 1000 ? 1 : 0;
|
|
const unsigned seconds = (this->deadline - this->started) / 1000 + fraction;
|
|
this->remaining = seconds;
|
|
this->seconds = seconds;
|
|
|
|
if (timeout != 0) {
|
|
this->counting = 1;
|
|
char buffer[512];
|
|
std::sprintf(buffer, this->format.c_str(), seconds);
|
|
this->messageText = buffer;
|
|
} else {
|
|
this->counting = 0;
|
|
}
|
|
|
|
this->SetSize(280, 120);
|
|
this->OnCreate(280, 120);
|
|
this->OnSize(280, 120);
|
|
this->Move((g_renderer->viewport.width - 640) / 2 + 185, (g_renderer->viewport.height - 480) / 2 + 180);
|
|
|
|
this->viewer = new UITextViewer();
|
|
this->viewer->Configure(10, 22, 260, 48, 0);
|
|
unsigned red, green, blue;
|
|
SkinPaletteChannels(ResourceMgr::Instance(), 2, 2, red, green, blue);
|
|
this->viewer->backgroundColor = RGB(red, green, blue) | 0xFF000000u;
|
|
this->viewer->Invalidate();
|
|
this->AddChild(this->viewer);
|
|
this->viewer->SendMsg(nullptr, UM_SETTEXT, reinterpret_cast<std::intptr_t>(this->messageText.c_str()), 38, 0, 0);
|
|
|
|
this->gauge = new UIBarGraph2();
|
|
this->gauge->SetSize(240, 15);
|
|
this->gauge->Move(20, this->geometry.height - 50);
|
|
this->gauge->SetValue(0);
|
|
SkinPaletteChannels(ResourceMgr::Instance(), 18, 2, red, green, blue);
|
|
this->gauge->m_backgroundRed = red;
|
|
this->gauge->m_backgroundGreen = green;
|
|
this->gauge->m_backgroundBlue = blue;
|
|
SkinPaletteChannels(ResourceMgr::Instance(), 22, 2, red, green, blue);
|
|
this->gauge->m_fillRed = red;
|
|
this->gauge->m_fillGreen = green;
|
|
this->gauge->m_fillBlue = blue;
|
|
this->AddChild(this->gauge);
|
|
|
|
const std::string root(prefix);
|
|
auto* button = new UIBitmapButton();
|
|
button->SetBitmap((root + "btn_cancel" + ".bmp").c_str(), 0, 0);
|
|
button->SetBitmap((root + "btn_cancel_a" + ".bmp").c_str(), 1, 0);
|
|
button->SetBitmap((root + "btn_cancel_b" + ".bmp").c_str(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight());
|
|
button->Move(234, 96);
|
|
button->SetId(185);
|
|
this->AddChild(button);
|
|
this->m_message0 = 185;
|
|
}
|
|
|
|
// OFFSET: 0x008BEE20
|
|
// FUNCTION: fn_11806
|
|
int UIMakeCharWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) {
|
|
switch (message) {
|
|
case UM_COMMAND:
|
|
switch (a) {
|
|
case ID_OK: {
|
|
if (_mbsstr(reinterpret_cast<const unsigned char*>(this->m_nameEdit->Text()), reinterpret_cast<const unsigned char*>(s_messageBoxItemLinkOpening.c_str())) ||
|
|
_mbsstr(reinterpret_cast<const unsigned char*>(this->m_nameEdit->Text()), reinterpret_cast<const unsigned char*>(s_messageBoxItemLinkClosing.c_str()))) {
|
|
g_windowMgr.Confirm(LookupMessage(MSI_STYLING_SHOP_OPEN_COUPON), 0, true, false, 0, "Message", 280, 120, 0);
|
|
this->m_nameEdit->SetText("");
|
|
return 0;
|
|
}
|
|
|
|
if (this->m_nameEdit->Length() < 4) {
|
|
g_windowMgr.Confirm(LookupMessage(MSI_ENTER_NAME_MORE_THAN_4_CHAR), 0, true, false, 0, "Message", 280, 120, 0);
|
|
} else {
|
|
const bool allowed = g_forbiddenWords.Allows(this->m_nameEdit->Text());
|
|
bool valid = true;
|
|
if (g_serviceType == 1) {
|
|
valid = ValidateCharacterName(this->m_nameEdit->Text());
|
|
}
|
|
|
|
const bool control = g_session.HasControlCharacter(this->m_nameEdit->Text());
|
|
const bool blank = g_session.IsBlankString(this->m_nameEdit->Text());
|
|
if (control || !allowed || !valid || blank) {
|
|
if (control || !allowed) {
|
|
g_windowMgr.Confirm(LookupMessage(MSI_BAD_NAME), 0, true, false, 0, "Message", 280, 120, 0);
|
|
}
|
|
if (!valid) {
|
|
g_windowMgr.Confirm(LookupMessage(MSI_ENGLISHONLY), 0, true, false, 0, "Message", 280, 120, 0);
|
|
}
|
|
if (blank) {
|
|
g_windowMgr.Confirm(LookupMessage(MSI_NO_SPACE_IN_NAME), 0, true, false, 0, "Message", 280, 120, 0);
|
|
}
|
|
} else if (this->m_nameEdit->Length() >= 24) {
|
|
g_windowMgr.Confirm(LookupMessage(MSI_NAMELENGTH_TOO_LONG), 0, true, false, 0, "Message", 280, 120, 0);
|
|
this->m_nameEdit->SetText("");
|
|
return 0;
|
|
} else {
|
|
char name[24] = {};
|
|
std::strcpy(name, this->m_nameEdit->Text());
|
|
std::memcpy(this->m_info.name, name, sizeof(this->m_info.name));
|
|
memcpy_s(&g_charInfo, sizeof(g_charInfo), &this->m_info, sizeof(this->m_info));
|
|
if (std::strstr(g_charInfo.name, "그라비티")) {
|
|
return 0;
|
|
}
|
|
|
|
_strlwr(name);
|
|
if (std::strstr(name, "gravity")) {
|
|
return 0;
|
|
}
|
|
if ((name[0] == '[' && name[1] == 'g' && name[2] == 'm') || (name[1] == '[' && name[2] == 'g' && name[3] == 'm') ||
|
|
(name[2] == '[' && name[3] == 'g' && name[4] == 'm')) {
|
|
return 0;
|
|
}
|
|
|
|
g_modeMgr.gameMode->SendMsg(LMM_SENDCHARINFO, 0, 0, 0, 0);
|
|
g_windowMgr.Schedule(this);
|
|
}
|
|
}
|
|
|
|
g_modeMgr.gameMode->SendMsg(LMM_SET_MAKING_CHAR_NAME, reinterpret_cast<int>(this->m_nameEdit->Text()), 0, 0, 0);
|
|
int values[8];
|
|
values[0] = this->m_info.stats[0];
|
|
values[1] = this->m_info.stats[1];
|
|
values[2] = this->m_info.stats[2];
|
|
values[3] = this->m_info.stats[3];
|
|
values[4] = this->m_info.stats[4];
|
|
values[5] = this->m_info.stats[5];
|
|
values[6] = this->m_info.headPalette;
|
|
values[7] = this->m_info.head;
|
|
g_modeMgr.gameMode->SendMsg(LMM_SET_CHAR_PARAM, reinterpret_cast<int>(values), 0, 0, 0);
|
|
return 0;
|
|
}
|
|
case ID_CANCEL:
|
|
g_windowMgr.Schedule(this);
|
|
g_modeMgr.gameMode->SendMsg(MM_COMMAND, 10004, 0, 0, 0);
|
|
return 0;
|
|
case ID_LEFT: {
|
|
int action = this->m_view.action + 1;
|
|
if (action >= this->m_view.actionBase + 8) {
|
|
action = this->m_view.actionBase;
|
|
}
|
|
this->m_view.action = action;
|
|
this->Invalidate();
|
|
return 0;
|
|
}
|
|
case ID_RIGHT:
|
|
if (--this->m_view.action < this->m_view.actionBase) {
|
|
this->m_view.action = this->m_view.actionBase + 7;
|
|
}
|
|
this->Invalidate();
|
|
return 0;
|
|
default:
|
|
return 0;
|
|
}
|
|
case UM_DEFPUSH: {
|
|
char name[25] = {};
|
|
std::strcpy(name, this->m_nameEdit->Text());
|
|
std::memcpy(this->m_info.name, name, sizeof(this->m_info.name));
|
|
this->SendMsg(nullptr, UM_COMMAND, this->m_message0, 0, 0, 0);
|
|
return 0;
|
|
}
|
|
case UM_SCROLLHORZ:
|
|
case UM_SCROLLHORZPAGEUP:
|
|
case UM_SCROLLHORZPAGEDOWN: {
|
|
const int sex = this->m_info.sex;
|
|
if (sender == this->m_hairStyleBar) {
|
|
const int previous = this->m_hairStyle;
|
|
if (message == UM_SCROLLHORZPAGEUP) {
|
|
this->m_hairStyle = previous - 1;
|
|
} else if (message == UM_SCROLLHORZPAGEDOWN) {
|
|
this->m_hairStyle = previous + 1;
|
|
} else {
|
|
this->m_hairStyle = a + previous;
|
|
}
|
|
if (this->m_hairStyle < 0) {
|
|
this->m_hairStyle = 0;
|
|
} else if (this->m_hairStyle > 22) {
|
|
this->m_hairStyle = 22;
|
|
}
|
|
this->m_hairStyleBar->SetPosition(this->m_hairStyle);
|
|
this->m_hairStyleBar->Invalidate();
|
|
this->Invalidate();
|
|
|
|
this->m_info.head = static_cast<std::int16_t>(this->m_hairStyle + 1);
|
|
int head = this->m_info.head;
|
|
this->m_view.actionNames[1].assign(g_session.GetHeadActName(this->m_info.job, sex, &head));
|
|
this->m_view.spriteNames[1].assign(g_session.GetHeadSprName(this->m_info.job, sex, &head));
|
|
this->m_info.head = static_cast<std::int16_t>(head);
|
|
this->m_view.imfName = GetBodyImfName(this->m_info.job, sex, this->m_info.head, this->m_info.bodyCostume);
|
|
if (this->m_view.headPalette) {
|
|
this->m_view.headPaletteName.assign(g_session.GetHeadPalName(head, this->m_info.job, sex, this->m_view.headPalette));
|
|
}
|
|
return this->m_hairStyle - previous;
|
|
}
|
|
|
|
if (sender == this->m_hairColorBar) {
|
|
const int previous = this->m_hairColor;
|
|
if (message == UM_SCROLLHORZPAGEUP) {
|
|
this->m_hairColor = previous - 1;
|
|
} else if (message == UM_SCROLLHORZPAGEDOWN) {
|
|
this->m_hairColor = previous + 1;
|
|
} else {
|
|
this->m_hairColor = a + previous;
|
|
}
|
|
if (this->m_hairColor < 0) {
|
|
this->m_hairColor = 0;
|
|
} else if (this->m_hairColor > 8) {
|
|
this->m_hairColor = 8;
|
|
}
|
|
this->m_hairColorBar->SetPosition(this->m_hairColor);
|
|
this->m_hairColorBar->Invalidate();
|
|
this->Invalidate();
|
|
|
|
this->m_view.headPalette = this->m_hairColor;
|
|
if (this->m_view.headPalette) {
|
|
this->m_view.headPaletteName = g_session.GetHeadPalName(this->m_info.head, this->m_info.job, sex, this->m_view.headPalette);
|
|
}
|
|
this->m_info.headPalette = static_cast<std::int16_t>(this->m_view.headPalette);
|
|
return this->m_hairColor - previous;
|
|
}
|
|
return 0;
|
|
}
|
|
default:
|
|
return UIFrameWnd::SendMsg(sender, message, a, b, c, d);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x008AF190
|
|
// FUNCTION: fn_11742
|
|
void UILoginWnd::OnCreate(int, int) {
|
|
this->backgroundWindow = g_windowMgr.EnsureWindow(WID_RPIMAGEWND2);
|
|
UIRPImageWnd2* backgroundWindow = static_cast<UIRPImageWnd2*>(this->backgroundWindow);
|
|
const char backgroundSource[] = {'\xA7', '\x04', '\x51', '\x5F', '\x61', '\xF1', '\x26', '\xDE', '\xA1', '\x4F', '\x51', '\x69', '\x1C', '\x85', '\xBF', '\x7F', '\x08', '\xCC', '\xF8',
|
|
'\xCB', '\xFE', '\x56', '\x8D', '\x67', '\x02', '\xD9', '\xF7', '\xC4', '\xC2', '\x5A', '\xBF', '\x71', '\x00', '\xF4', '\xFD', '\xCA', '\xC6', '\x56',
|
|
'\x8D', '\x3D', '\x13', '\xCC', '\xF0', '\xA5'};
|
|
thread_local EncryptedName<sizeof(backgroundSource), 0x13E33FA1A591AB67ULL> backgroundName(backgroundSource);
|
|
backgroundWindow->SetImage(backgroundName.Text(), 5);
|
|
|
|
const char uiPathSource[] = {'\xF7', '\xE8', '\x6D', '\xC3', '\x7F', '\x2B', '\x6C', '\xDA', '\xF1', '\xA3', '\x6D', '\xF5', '\x02', '\x5F', '\xF5', '\x17'};
|
|
thread_local EncryptedName<sizeof(uiPathSource), 0x17A9E5BF39AD4737ULL> uiPathName(uiPathSource);
|
|
const std::string uiPath(uiPathName.Text());
|
|
const char loginPathSource[] = {'\x83', '\x86', '\x93', '\xDD', '\x15', '\x71', '\x8C', '\x54', '\x85', '\xCD', '\x93', '\xEB', '\x68', '\x05', '\x15', '\xF5', '\x2C', '\x4E', '\x3A',
|
|
'\x49', '\x8A', '\xD6', '\x27', '\xED', '\x26', '\x5B', '\x35', '\x46', '\xB6', '\xDA', '\x15', '\x99'};
|
|
thread_local EncryptedName<sizeof(loginPathSource), 0x9949BFD527532943ULL> loginPathName(loginPathSource);
|
|
const std::string loginPath(loginPathName.Text());
|
|
this->passwordPlaceholder = true;
|
|
|
|
UIStaticText* label = new UIStaticText();
|
|
label->SetSize(72, 22);
|
|
label->SetText(LookupMessage(MSI_CREATE_RAG_ACCOUNT), 0);
|
|
label->SetColor(51, 51, 51);
|
|
label->Move(73, 87);
|
|
label->SetFont(0, 11, 0, 0);
|
|
this->AddChild(label);
|
|
|
|
UIBmpTextButton* button;
|
|
button = new UIBmpTextButton();
|
|
const char closeNormalSource[] = {'\xAF', '\xD2', '\x3B', '\xD9', '\xB1', '\xC9', '\x4A', '\x00', '\xA9', '\x99', '\x3B', '\xEF', '\xCC', '\xBD', '\xD3', '\xA1', '\x00', '\x1A', '\x92',
|
|
'\x4D', '\x2E', '\x6E', '\xE1', '\xB9', '\x0A', '\x0F', '\x9D', '\x42', '\x12', '\x62', '\xD3', '\xAF', '\x1B', '\x22', '\x98', '\x4F', '\x1E', '\x74',
|
|
'\xEA', '\x92', '\x01', '\x12', '\x89', '\x4E', '\x10', '\x6B', '\xA1', '\xAF', '\x02', '\x0D', '\xFB'};
|
|
thread_local EncryptedName<sizeof(closeNormalSource), 0xCD8F077123FB7D6FULL> closeNormalName(closeNormalSource);
|
|
button->SetBitmap(closeNormalName.Text(), 0, 0);
|
|
const char closeOverSource[] = {'\xA9', '\xB0', '\xB7', '\xAF', '\x5D', '\x5B', '\xBE', '\xAE', '\xAF', '\xFB', '\xB7', '\x99', '\x20', '\x2F', '\x27', '\x0F', '\x06', '\x78', '\x1E',
|
|
'\x3B', '\xC2', '\xFC', '\x15', '\x17', '\x0C', '\x6D', '\x11', '\x34', '\xFE', '\xF0', '\x27', '\x01', '\x1D', '\x40', '\x14', '\x39', '\xF2', '\xE6',
|
|
'\x1E', '\x3C', '\x06', '\x69', '\x12', '\x27', '\xB3', '\xF7', '\x16', '\x13', '\x69'};
|
|
thread_local EncryptedName<sizeof(closeOverSource), 0x637B959D55771F69ULL> closeOverName(closeOverSource);
|
|
button->SetBitmap(closeOverName.Text(), 1, 0);
|
|
const char closePressSource[] = {'\x91', '\x24', '\x0D', '\xFB', '\x7B', '\xF3', '\x84', '\x1C', '\x97', '\x6F', '\x0D', '\xCD', '\x06', '\x87', '\x1D', '\xBD', '\x3E', '\xEC', '\xA4',
|
|
'\x6F', '\xE4', '\x54', '\x2F', '\xA5', '\x34', '\xF9', '\xAB', '\x60', '\xD8', '\x58', '\x1D', '\xB3', '\x25', '\xD4', '\xAE', '\x6D', '\xD4', '\x4E',
|
|
'\x24', '\x8E', '\x21', '\xF9', '\xA8', '\x72', '\xC8', '\x13', '\x23', '\xBC', '\x21', '\x8B'};
|
|
thread_local EncryptedName<sizeof(closePressSource), 0xD1413DBB01CD8B51ULL> closePressName(closePressSource);
|
|
button->SetBitmap(closePressName.Text(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight() + 2);
|
|
button->Move(13, 104);
|
|
button->SetId(285);
|
|
{
|
|
const std::string text(LookupMessage(MSI_ENST_BLESSING2));
|
|
button->text = text;
|
|
button->Invalidate();
|
|
}
|
|
button->AddTextStyle(0, 12, 0x313131, 1, 1, -1000, -1000);
|
|
button->AddTextStyle(1, 12, 0x313131, 1, 1, -1000, -1000);
|
|
button->AddTextStyle(2, 12, 0x313131, 1, 1, -1000, -1000);
|
|
this->AddChild(button);
|
|
|
|
button = new UIBmpTextButton();
|
|
const char joinNormalSource[] = {'\x79', '\xAA', '\xB7', '\xB5', '\xCB', '\xD3', '\x4A', '\xB8', '\x7F', '\xE1', '\xB7', '\x83', '\xB6', '\xA7', '\xD3', '\x19', '\xD6', '\x62', '\x1E',
|
|
'\x21', '\x54', '\x74', '\xE1', '\x01', '\xDC', '\x77', '\x11', '\x2E', '\x68', '\x78', '\xD3', '\x17', '\xCD', '\x5A', '\x1D', '\x20', '\x62', '\x73',
|
|
'\xD0', '\x1B', '\xD6', '\x77', '\x1A', '\x2E', '\x67', '\x33', '\xED', '\x18', '\xC9', '\x05'};
|
|
thread_local EncryptedName<sizeof(joinNormalSource), 0x758F1D0B4F7705B9ULL> joinNormalName(joinNormalSource);
|
|
button->SetBitmap(joinNormalName.Text(), 0, 0);
|
|
const char joinOverSource[] = {'\xA5', '\xB6', '\x85', '\xF3', '\xED', '\xED', '\xDE', '\x44', '\xA3', '\xFD', '\x85', '\xC5', '\x90', '\x99', '\x47', '\xE5', '\x0A', '\x7E', '\x2C',
|
|
'\x67', '\x72', '\x4A', '\x75', '\xFD', '\x00', '\x6B', '\x23', '\x68', '\x4E', '\x46', '\x47', '\xEB', '\x11', '\x46', '\x2F', '\x66', '\x44', '\x4D',
|
|
'\x44', '\xE6', '\x13', '\x7C', '\x37', '\x27', '\x4F', '\x4E', '\x6B', '\x89'};
|
|
thread_local EncryptedName<sizeof(joinOverSource), 0x891B232D09451965ULL> joinOverName(joinOverSource);
|
|
button->SetBitmap(joinOverName.Text(), 1, 0);
|
|
const char joinPressSource[] = {'\x55', '\x20', '\x21', '\xF7', '\x9D', '\xC7', '\xA4', '\x3C', '\x53', '\x6B', '\x21', '\xC1', '\xE0', '\xB3', '\x3D', '\x9D', '\xFA', '\xE8', '\x88',
|
|
'\x63', '\x02', '\x60', '\x0F', '\x85', '\xF0', '\xFD', '\x87', '\x6C', '\x3E', '\x6C', '\x3D', '\x93', '\xE1', '\xD0', '\x8B', '\x62', '\x34', '\x67',
|
|
'\x3E', '\x81', '\xE7', '\xEA', '\x92', '\x7E', '\x73', '\x6B', '\x0C', '\x81', '\x95'};
|
|
thread_local EncryptedName<sizeof(joinPressSource), 0xF161095D0DE18F95ULL> joinPressName(joinPressSource);
|
|
button->SetBitmap(joinPressName.Text(), 2, 0);
|
|
button->SetSize(button->BitmapWidth(), button->BitmapHeight() + 2);
|
|
button->Move(87, 104);
|
|
button->SetId(267);
|
|
{
|
|
const std::string text(LookupMessage(MSI_ADVENTURER_AGENCY_REGIST_FAILED));
|
|
button->text = text;
|
|
button->Invalidate();
|
|
}
|
|
button->AddTextStyle(0, 12, 0x313131, 1, 1, -1000, -1000);
|
|
button->AddTextStyle(1, 12, 0x313131, 1, 1, -1000, -1000);
|
|
button->AddTextStyle(2, 12, 0x313131, 1, 1, -1000, -1000);
|
|
this->AddChild(button);
|
|
|
|
UIBitmapButton* bitmapButton;
|
|
bitmapButton = new UIBitmapButton();
|
|
const char startNormalSource[] = {'\x2F', '\xDE', '\x1F', '\xE9', '\xAD', '\x81', '\x02', '\x20', '\x29', '\x95', '\x1F', '\xDF', '\xD0', '\xF5', '\x9B', '\x81', '\x80', '\x16', '\xB6',
|
|
'\x7D', '\x32', '\x26', '\xA9', '\x99', '\x8A', '\x03', '\xB9', '\x72', '\x0E', '\x2A', '\x9B', '\x8F', '\x9B', '\x2E', '\xAC', '\x67', '\x0C', '\x3D',
|
|
'\xB3', '\xB2', '\x81', '\x1E', '\xAD', '\x7E', '\x0C', '\x23', '\xE9', '\x8F', '\x82', '\x01', '\xDF'};
|
|
thread_local EncryptedName<sizeof(startNormalSource), 0xEDC74F6D13DF71EFULL> startNormalName(startNormalSource);
|
|
bitmapButton->SetBitmap(startNormalName.Text(), 0, 0);
|
|
const char startOverSource[] = {'\x4F', '\x12', '\x2F', '\x7D', '\xBD', '\x0B', '\x68', '\xB8', '\x49', '\x59', '\x2F', '\x4B', '\xC0', '\x7F', '\xF1', '\x19', '\xE0', '\xDA', '\x86',
|
|
'\xE9', '\x22', '\xAC', '\xC3', '\x01', '\xEA', '\xCF', '\x89', '\xE6', '\x1E', '\xA0', '\xF1', '\x17', '\xFB', '\xE2', '\x9C', '\xF3', '\x1C', '\xB7',
|
|
'\xD9', '\x2A', '\xE0', '\xCB', '\x8A', '\xF5', '\x53', '\xA7', '\xC0', '\x05', '\x8F'};
|
|
thread_local EncryptedName<sizeof(startOverSource), 0x75ADC57D87EFBD8FULL> startOverName(startOverSource);
|
|
bitmapButton->SetBitmap(startOverName.Text(), 1, 0);
|
|
const char startPressSource[] = {'\x19', '\x56', '\x21', '\x19', '\xAD', '\xDB', '\x68', '\xE6', '\x1F', '\x1D', '\x21', '\x2F', '\xD0', '\xAF', '\xF1', '\x47', '\xB6', '\x9E', '\x88',
|
|
'\x8D', '\x32', '\x7C', '\xC3', '\x5F', '\xBC', '\x8B', '\x87', '\x82', '\x0E', '\x70', '\xF1', '\x49', '\xAD', '\xA6', '\x92', '\x97', '\x0C', '\x67',
|
|
'\xD9', '\x74', '\xA9', '\x8B', '\x84', '\x90', '\x1E', '\x3B', '\xCF', '\x46', '\xA9', '\xF9'};
|
|
thread_local EncryptedName<sizeof(startPressSource), 0x2BAD156DE3E1F9D9ULL> startPressName(startPressSource);
|
|
bitmapButton->SetBitmap(startPressName.Text(), 2, 0);
|
|
bitmapButton->SetSize(bitmapButton->BitmapWidth(), bitmapButton->BitmapHeight());
|
|
bitmapButton->Move(192, 32);
|
|
bitmapButton->SetId(186);
|
|
this->AddChild(bitmapButton);
|
|
|
|
bitmapButton = new UIBitmapButton();
|
|
const char exitNormalSource[] = {'\x57', '\x5E', '\x21', '\x27', '\x11', '\x5D', '\x2C', '\xE2', '\x51', '\x15', '\x21', '\x11', '\x6C', '\x29', '\xB5', '\x43', '\xF8', '\x96', '\x88',
|
|
'\xB3', '\x8E', '\xFA', '\x87', '\x5B', '\xF2', '\x83', '\x87', '\xBC', '\xB2', '\xF6', '\xB5', '\x4D', '\xE3', '\xAE', '\x82', '\xB1', '\xBE', '\xE0',
|
|
'\x8C', '\x1D', '\xC8', '\x9F', '\x8E', '\xAF', '\xBC', '\xF2', '\x85', '\x01', '\xF5', '\x9C', '\x91', '\xDD'};
|
|
thread_local EncryptedName<sizeof(exitNormalSource), 0x2FE993D1DDE1F197ULL> exitNormalName(exitNormalSource);
|
|
bitmapButton->SetBitmap(exitNormalName.Text(), 0, 0);
|
|
const char exitOverSource[] = {'\x4F', '\x36', '\x2B', '\xF7', '\x75', '\xB1', '\x3A', '\xF4', '\x49', '\x7D', '\x2B', '\xC1', '\x08', '\xC5', '\xA3', '\x55', '\xE0', '\xFE', '\x82',
|
|
'\x63', '\xEA', '\x16', '\x91', '\x4D', '\xEA', '\xEB', '\x8D', '\x6C', '\xD6', '\x1A', '\xA3', '\x5B', '\xFB', '\xC6', '\x88', '\x61', '\xDA', '\x0C',
|
|
'\x9A', '\x0B', '\xD0', '\xF6', '\x9D', '\x68', '\xC7', '\x51', '\x9D', '\x54', '\xFF', '\x99'};
|
|
thread_local EncryptedName<sizeof(exitOverSource), 0x39FF7FB50DEB998FULL> exitOverName(exitOverSource);
|
|
bitmapButton->SetBitmap(exitOverName.Text(), 1, 0);
|
|
const char exitPressSource[] = {'\xBF', '\xBA', '\x4D', '\xEB', '\xF7', '\xC1', '\x4E', '\xE2', '\xB9', '\xF1', '\x4D', '\xDD', '\x8A', '\xB5', '\xD7', '\x43', '\x10', '\x72', '\xE4',
|
|
'\x7F', '\x68', '\x66', '\xE5', '\x5B', '\x1A', '\x67', '\xEB', '\x70', '\x54', '\x6A', '\xD7', '\x4D', '\x0B', '\x4A', '\xEE', '\x7D', '\x58', '\x7C',
|
|
'\xEE', '\x1D', '\x20', '\x65', '\xFF', '\x74', '\x44', '\x7C', '\xA5', '\x4D', '\x12', '\x65', '\x8D'};
|
|
thread_local EncryptedName<sizeof(exitPressSource), 0x2F8B0F37118D157FULL> exitPressName(exitPressSource);
|
|
bitmapButton->SetBitmap(exitPressName.Text(), 2, 0);
|
|
bitmapButton->SetSize(bitmapButton->BitmapWidth(), bitmapButton->BitmapHeight());
|
|
bitmapButton->Move(273, 15);
|
|
bitmapButton->SetId(221);
|
|
this->AddChild(bitmapButton);
|
|
this->m_message0 = 186;
|
|
|
|
this->passwordEdit = new UIEditCtrl_Custom();
|
|
this->passwordEdit->SetSize(153, 16);
|
|
this->passwordEdit->Move(15, 64);
|
|
this->passwordEdit->labelAlignment = 2;
|
|
this->passwordEdit->Background(255, 255, 255);
|
|
const char placeholderSource[] = {'\x9D', '\xB0', '\xCA', '\xE6', '\xDA', '\x14', '\x55', '\xE9', '\xCD'};
|
|
thread_local EncryptedName<sizeof(placeholderSource), 0xAD075B8DB599F1CDULL> placeholderName(placeholderSource);
|
|
this->passwordEdit->SetText(placeholderName.Text());
|
|
this->passwordEdit->TextColor(156, 156, 156, 0xFFFFFFFF);
|
|
this->passwordEdit->mask = '*';
|
|
this->AddChild(this->passwordEdit);
|
|
|
|
this->idEdit = new UIEditCtrl_Custom();
|
|
this->idEdit->SetSize(153, 16);
|
|
this->idEdit->Move(15, 40);
|
|
this->idEdit->labelAlignment = 2;
|
|
this->idEdit->Background(255, 255, 255);
|
|
this->idEdit->TextColor(156, 156, 156, 0xFFFFFFFF);
|
|
this->AddChild(this->idEdit);
|
|
this->LoadLogin();
|
|
|
|
UICheckBox* saveIdCheck = new UICheckBox();
|
|
const char checkedImageSource[] = {'\x9E', '\xD1', '\xDE', '\x42', '\xF4', '\x9F', '\x2E', '\x31', '\xA2', '\xD6', '\xD5', '\x0F', '\xFD', '\x90', '\x31', '\x49'};
|
|
thread_local EncryptedName<sizeof(checkedImageSource), 0x4941FD9F21BBB9FDULL> checkedImageName(checkedImageSource);
|
|
const std::string checkedImage = loginPath + std::string(checkedImageName.Text());
|
|
const char uncheckedImageSource[] = {'\x16', '\xA5', '\x88', '\x3E', '\x00', '\x07', '\x8A', '\x4D', '\x2A', '\xA2', '\x8B', '\x3B', '\x45', '\x07', '\x88', '\x45', '\x75'};
|
|
thread_local EncryptedName<sizeof(uncheckedImageSource), 0x35E5656B5DEDCD75ULL> uncheckedImageName(uncheckedImageSource);
|
|
const std::string uncheckedImage = loginPath + std::string(uncheckedImageName.Text());
|
|
saveIdCheck->SetBitmaps(checkedImage.c_str(), uncheckedImage.c_str());
|
|
saveIdCheck->SetSize(saveIdCheck->geometry.width, saveIdCheck->geometry.height);
|
|
saveIdCheck->Move(56, 85);
|
|
saveIdCheck->SetChecked(this->saveId);
|
|
this->AddChild(saveIdCheck);
|
|
|
|
this->loginTypeCombo = new UIComboBoxDef2Wnd();
|
|
this->loginTypeCombo->skin = 1;
|
|
this->loginTypeCombo->alignment = 1;
|
|
this->loginTypeCombo->dropdownHeight = 18;
|
|
this->loginTypeCombo->textOffset = 3;
|
|
this->loginTypeCombo->SetSize(160, 22);
|
|
this->loginTypeCombo->Move(13, 10);
|
|
this->AddChild(this->loginTypeCombo);
|
|
this->loginTypeCombo->AddOption(LookupMessage(MSI_ENTER_THE_SEARCH_WORD), 0);
|
|
this->loginTypeCombo->AddOption(LookupMessage(MSI_MOTP), 0);
|
|
this->loginTypeCombo->Clear();
|
|
this->loginTypeCombo->AddOption(LookupMessage(MSI_ENTER_THE_SEARCH_WORD), 0);
|
|
this->loginTypeCombo->Select(0);
|
|
this->SendMsg(this->loginTypeCombo, UM_COMBOBOX_SELECTED, 0, 0, 0, 0);
|
|
this->idEdit->maximum = 24;
|
|
this->passwordEdit->maximum = 24;
|
|
|
|
if (std::strcmp(this->idEdit->Text(), "") != 0 && std::strcmp(this->idEdit->Text(), "ID") != 0) {
|
|
g_windowMgr.SetFocus(this->passwordEdit);
|
|
} else {
|
|
g_windowMgr.SetFocus(this->idEdit);
|
|
}
|
|
}
|