diff --git a/Source/UI/Shop/ItemDrawing.cpp b/Source/UI/Shop/ItemDrawing.cpp index 73f7c715..c3817738 100644 --- a/Source/UI/Shop/ItemDrawing.cpp +++ b/Source/UI/Shop/ItemDrawing.cpp @@ -8,6 +8,8 @@ #include +// OFFSET: 0x008A8D30 + // OFFSET: 0x008A8EE0 // FUNCTION: fn_11717 void DrawItemIcon(UIWindow& window, ResourceMgr& resources, ItemDescriptions& descriptions, int x, int y, const ITEM_INFO& item, unsigned char identified) { diff --git a/Source/UI/Shop/ItemDrawing.h b/Source/UI/Shop/ItemDrawing.h index 128d8d21..e172a40e 100644 --- a/Source/UI/Shop/ItemDrawing.h +++ b/Source/UI/Shop/ItemDrawing.h @@ -15,5 +15,9 @@ void DrawItemWithQuantity( UIWindow& window, ResourceMgr& resources, ItemDescriptions& descriptions, FontCache& fonts, const TextLocale& locale, int x, int y, const ITEM_INFO& item, unsigned char identified, unsigned char plain ); +void DrawItemWithQuantityAuxiliary( + UIWindow& window, ItemDescriptions& descriptions, FontCache& fonts, const TextLocale& locale, int mode, int x, int y, const ITEM_INFO& item, + unsigned char identified, unsigned char plain +); #endif diff --git a/Source/UI/Text/UIStaticText.cpp b/Source/UI/Text/UIStaticText.cpp index 207750cb..73207beb 100644 --- a/Source/UI/Text/UIStaticText.cpp +++ b/Source/UI/Text/UIStaticText.cpp @@ -24,6 +24,57 @@ void UIStaticText::SetText(const char* value, int outlineValue) { this->Invalidate(); } +// OFFSET: 0x008685B0 +// FUNCTION: fn_10961 +void UIStaticText::SetColor(int redValue, int greenValue, int blueValue) { + this->red = redValue; + this->green = greenValue; + this->blue = blueValue; + this->Invalidate(); +} + +// OFFSET: 0x00868880 +// FUNCTION: fn_10965 +void UIStaticText::SetTextFitted(const char* value) { + this->tooltip = value; + this->tooltipEnabled = 0; + + if (this->geometry.surface == nullptr) { + this->text = value; + this->Invalidate(); + return; + } + + int width = this->TextWidth(this->m_controls->fonts, this->m_controls->locale, value, 0, this->fontFamily, this->fontHeight, this->bold, 0); + this->TextWidth(this->m_controls->fonts, this->m_controls->locale, "...", 0, this->fontFamily, this->fontHeight, this->bold, 0); + + if (this->geometry.width >= width) { + this->text = value; + this->Invalidate(); + return; + } + + this->tooltipEnabled = 1; + this->text = value; + std::string truncated = value; + while (this->geometry.width < width) { + if (truncated.size() <= 1) { + this->text = truncated + "..."; + break; + } + + if (truncated.size() >= 2) { + const std::size_t size = truncated.size(); + truncated.resize(truncated[size - 2] < 0 && truncated[size - 1] < 0 ? size - 2 : size - 1); + } + + this->text = truncated + "..."; + width = this->TextWidth(this->m_controls->fonts, this->m_controls->locale, this->text.c_str(), 0, this->fontFamily, this->fontHeight, this->bold, 0); + } + + this->Invalidate(); +} + // OFFSET: 0x0085DE70 // FUNCTION: fn_10820 void UIStaticText::Paint() { diff --git a/Source/UI/Text/UIStaticText.h b/Source/UI/Text/UIStaticText.h index 9a3cc2dd..af2cd792 100644 --- a/Source/UI/Text/UIStaticText.h +++ b/Source/UI/Text/UIStaticText.h @@ -22,6 +22,8 @@ public: void Slot33(int x, int y) override; void Slot35(int value) override; void SetText(const char* value, int outline); + void SetColor(int redValue, int greenValue, int blueValue); + void SetTextFitted(const char* value); /* 007C */ int red; /* 0080 */ int green; diff --git a/Source/UI/Window/UIRoulletteWnd.cpp b/Source/UI/Window/UIRoulletteWnd.cpp index 2b94c278..fd927e33 100644 --- a/Source/UI/Window/UIRoulletteWnd.cpp +++ b/Source/UI/Window/UIRoulletteWnd.cpp @@ -1,15 +1,247 @@ #include "UI/Window/UIRoulletteWnd.h" +#include "Client/Mode/CMode.h" +#include "Client/Mode/ModeMgr.h" +#include "Contents/MessageTable.h" #include "Contents/RouletteMgr.h" +#include "Network/Connection/Connection.h" +#include "Network/Packets/PacketId.h" +#include "Network/Packets/PacketLengths.h" +#include "Resource/Bitmap/BitmapResource.h" +#include "Resource/ResourceMgr.h" +#include "Resource/TextureNames.h" +#include "UI/Buttons/UIBitmapButton.h" +#include "UI/Buttons/UIButton.h" +#include "UI/Buttons/UISpriteButton.h" +#include "UI/Window/UIWindowMgr.h" +#include "UI/Window/WindowManagerWindows.h" + +#include + +// GLOBAL: gl_24881 +int g_effectDetailLevel; + +namespace { +#pragma pack(push, 1) +struct RouletteGeneratePacket { + /* 0000 */ std::int16_t id; +}; + +struct RouletteReceiveItemPacket { + /* 0000 */ std::int16_t id; + /* 0002 */ unsigned char condition; +}; +#pragma pack(pop) +} // OFFSET: 0x0080BAF0 // FUNCTION: fn_10084 UIRoulletteWnd::~UIRoulletteWnd() = default; +// OFFSET: 0x0080BBB0 +// FUNCTION: fn_10085 +ITEM_INFO UIRoulletteWnd::ItemAt(int x, int y) { + this->m_row = 0; + this->m_column = 0; + + int row = 0; + for (int top = 344; top > 64; top -= 40, ++row) { + if (top + 26 < y || top > y) { + continue; + } + + this->m_row = row; + const int count = 9 - row; + int right = row * 36 + 185; + for (int column = 0; column < count; ++column, right += 36) { + if (right - 27 > x || right < x) { + continue; + } + + this->m_column = column; + for (auto it = g_rouletteMgr->m_items.begin(); it != g_rouletteMgr->m_items.end(); ++it) { + if (row == it->first.row && column == it->first.column) { + return it->second; + } + } + return ITEM_INFO(0); + } + break; + } + + return ITEM_INFO(0); +} + // OFFSET: 0x0080C490 // FUNCTION: fn_10088 void UIRoulletteWnd::Slot25(int, int) { } +// OFFSET: 0x0080C730 +// FUNCTION: fn_10090 +void UIRoulletteWnd::Slot19() { + if (g_effectDetailLevel != 2) { + if (this->m_startButton->geometry.unknown_0030 == 1 && this->m_enabled == 1) { + if (g_rouletteMgr->m_spinning == 0) { + CBitmapRes* arrow = + static_cast(ResourceMgr::Instance().Load(Resolve("유저인터페이스\\basic_interface\\roullette\\stageArrow.bmp"))); + this->DrawBitmap(480, 337 - (this->CoinType() + g_rouletteMgr->m_stage) * 40, &arrow->image, true); + } + if (g_rouletteMgr->m_resultShown == 1 && g_rouletteMgr->m_bonus == 0) { + CBitmapRes* arrow = + static_cast(ResourceMgr::Instance().Load(Resolve("유저인터페이스\\basic_interface\\roullette\\stageArrow.bmp"))); + this->DrawBitmap(480, 297 - g_rouletteMgr->m_stage * 40, &arrow->image, true); + } + this->m_startButton->SetState(0); + } + return; + } + + if (this->m_startButton->geometry.unknown_0030 == 1 && this->m_enabled == 1) { + if (g_rouletteMgr->m_spinning == 0) { + this->m_startSprite->Move(339, 398); + this->m_startSprite->SetTooltip(LookupMessage(2684)); + this->m_stageArrow->Move(480, 337 - (this->CoinType() + g_rouletteMgr->m_stage) * 40); + } + if (g_rouletteMgr->m_resultShown == 1 && g_rouletteMgr->m_bonus == 0) { + this->m_stageArrow->Move(480, 297 - g_rouletteMgr->m_stage * 40); + } + this->m_startButton->SetState(0); + } + + if (this->m_startSprite->geometry.unknown_0030 == 2) { + this->m_startSprite->SetState(3); + this->m_startSprite->Move(-100, -100); + this->m_startSprite->SetTooltip(""); + this->SendMsg(nullptr, 6, 409, 0, 0, 0); + this->m_startButton->SetState(2); + } + + if (this->m_prizeButton->geometry.unknown_0030 == 1) { + this->m_prizeSprite->Move(203, 398); + this->m_prizeSprite->SetTooltip(LookupMessage(2683)); + this->m_prizeButton->SetState(0); + } + + if (this->m_prizeSprite->geometry.unknown_0030 == 2) { + this->m_prizeSprite->SetState(3); + this->m_prizeSprite->Move(-100, -100); + this->m_prizeSprite->SetTooltip(""); + this->SendMsg(nullptr, 6, 410, 0, 0, 0); + this->m_prizeButton->SetState(2); + } + + if (g_modeMgr.gameMode->cursorAction != 2 || g_rouletteMgr->m_spinning == 1) { + this->m_startSprite->Move(-100, -100); + this->m_prizeSprite->Move(-100, -100); + this->m_stageArrow->Move(-100, -100); + this->Invalidate(); + } + + if (g_rouletteMgr->m_resultShown == 1) { + this->m_prizeSprite->Invalidate(); + } + + if (g_rouletteMgr->m_spinning == 0) { + this->m_startSprite->Invalidate(); + this->m_stageArrow->Invalidate(); + } +} + +// OFFSET: 0x0080CA70 +// FUNCTION: fn_10091 +void UIRoulletteWnd::Slot32(int x, int y) { + ITEM_INFO item = this->ItemAt(x, y); + + if (static_cast(y - 143) < 31 && static_cast(x - 186) < 31 && g_rouletteMgr->m_resultShown == 1) { + item = g_rouletteMgr->m_resultItem; + } + + if (static_cast(y - 133) < 31 && static_cast(x - 60) < 29) { + item = g_rouletteMgr->m_additionItem; + } + + if (item.quantity != 0) { + this->m_frameContext->windows.EnsureWindow(12)->SendMsg(nullptr, 24, reinterpret_cast(&item), 0, 0, 0); + } +} + +// OFFSET: 0x0080CB90 +// FUNCTION: fn_10092 +int UIRoulletteWnd::SendMsg(UIWindow* sender, int message, std::intptr_t argument1, std::intptr_t argument2, std::intptr_t argument3, std::intptr_t argument4) { + if (message == 6) { + if (argument1 == 201) { + if (g_rouletteMgr->m_spinning == 0) { + if (g_windowMgr.unknown_0464 != nullptr) { + this->m_frameContext->windows.CloseWindow(269); + return 0; + } + } else { + g_windowMgr.SendNotice(1, reinterpret_cast(LookupMessage(2640)), 0x6464FF, 0, 0, 0); + } + } else if (argument1 == 409) { + if (this->m_enabled == 1) { + RouletteGeneratePacket packet; + packet.id = ID_CZ_REQ_GENERATE_ROULETTE; + GetRagConnection().Send(g_packetLengths.FixedLength(packet.id), &packet); + this->m_enabled = 0; + return 0; + } + } else if (argument1 == 410 && g_rouletteMgr->m_resultShown == 1) { + RouletteReceiveItemPacket packet; + packet.id = ID_CZ_RECV_ROULETTE_ITEM; + packet.condition = static_cast(argument2); + GetRagConnection().Send(g_packetLengths.FixedLength(packet.id), &packet); + return 0; + } + return 0; + } + + if (message == 60) { + this->Invalidate(); + return 0; + } + + return UIFrameWnd::SendMsg(sender, message, argument1, argument2, argument3, argument4); +} + +// OFFSET: 0x0080CCE0 +// FUNCTION: fn_10093 +void UIRoulletteWnd::UpdateButtons() { + if (g_effectDetailLevel == 2) { + if (g_rouletteMgr->m_stage != 6 && + (g_rouletteMgr->m_bronzePoint > 0 || g_rouletteMgr->m_silverPoint >= 10 || g_rouletteMgr->m_goldPoint >= 10)) { + this->m_startButton->Move(339, 398); + } + if (g_rouletteMgr->m_spinning != 0) { + this->m_startButton->Move(-100, -100); + this->m_stageArrow->Move(-100, -100); + } + if (g_rouletteMgr->m_resultShown != 1) { + this->m_prizeSprite->Move(-100, -100); + this->m_prizeButton->Move(-100, -100); + return; + } + this->m_prizeButton->Move(203, 398); + } else { + if (g_rouletteMgr->m_stage != 6 && + (g_rouletteMgr->m_bronzePoint > 0 || g_rouletteMgr->m_silverPoint >= 10 || g_rouletteMgr->m_goldPoint >= 10)) { + this->m_startButton->Move(339, 398); + } + if (g_rouletteMgr->m_spinning != 0) { + this->m_startButton->Move(-100, -100); + } + if (g_rouletteMgr->m_resultShown != 1) { + this->m_prizeButton->Move(-100, -100); + return; + } + this->m_prizeButton->Move(203, 398); + } + + if (g_rouletteMgr->m_stage != 6) { + this->m_startButton->Move(339, 398); + } +} + // OFFSET: 0x0080CE40 // FUNCTION: fn_10094 int UIRoulletteWnd::CoinType() const { diff --git a/Source/UI/Window/UIRoulletteWnd.h b/Source/UI/Window/UIRoulletteWnd.h index 3f84d72e..faca31d1 100644 --- a/Source/UI/Window/UIRoulletteWnd.h +++ b/Source/UI/Window/UIRoulletteWnd.h @@ -6,30 +6,45 @@ #include +class UIBitmapButton; +class UISpriteButton; +class UIStaticText; + +extern int g_effectDetailLevel; + class UIRoulletteWnd : public UIFrameWnd { public: ~UIRoulletteWnd() override; + void Slot19() override; void Slot25(int x, int y) override; + void Slot32(int x, int y) override; + int SendMsg(UIWindow* sender, int message, std::intptr_t argument1, std::intptr_t argument2, std::intptr_t argument3, std::intptr_t argument4) override; int CoinType() const; + ITEM_INFO ItemAt(int x, int y); + void UpdateButtons(); - /* 00BC */ std::uint32_t unknown_00BC; - /* 00C0 */ std::uint32_t unknown_00C0; - /* 00C4 */ std::uint32_t unknown_00C4; + /* 00BC */ UIBitmapButton* m_prizeButton; + /* 00C0 */ UISpriteButton* m_prizeSprite; + /* 00C4 */ UISpriteButton* m_stageArrow; /* 00C8 */ unsigned char m_enabled; + /* 00B4 */ UIBitmapButton* m_startButton; /* 00D0 */ ITEM_INFO m_item; /* 01C8 */ std::list m_items; - /* 01D0 */ UIWindow* unknown_01D0; - /* 01D4 */ UIWindow* unknown_01D4; - /* 01D8 */ UIWindow* unknown_01D8; - /* 01DC */ UIWindow* unknown_01DC; - /* 01E0 */ UIWindow* unknown_01E0; + /* 01D0 */ int m_column; + /* 01D4 */ int m_row; + /* 01D8 */ UIStaticText* m_goldText; + /* 01DC */ UIStaticText* m_silverText; + /* 01E0 */ UIStaticText* m_bronzeText; + /* 00B8 */ UISpriteButton* m_startSprite; }; #if defined(_WIN32) && !defined(_WIN64) +static_assert(offsetof(UIRoulletteWnd, m_prizeButton) == 0xBC); static_assert(offsetof(UIRoulletteWnd, m_enabled) == 0xC8); static_assert(offsetof(UIRoulletteWnd, m_item) == 0xD0); static_assert(offsetof(UIRoulletteWnd, m_items) == 0x1C8); -static_assert(offsetof(UIRoulletteWnd, unknown_01E0) == 0x1E0); +static_assert(offsetof(UIRoulletteWnd, m_column) == 0x1D0); +static_assert(offsetof(UIRoulletteWnd, m_bronzeText) == 0x1E0); static_assert(sizeof(UIRoulletteWnd) == 0x1E8); #endif