Batch #8567 by youko: 0 byte-identical, 1 confirmed by peer review. - fn_12911 UIQuestDisplay::Paint: logic confirmed by peer review Peer-reviewed-by: eAthena, gordaoprogramas, superintelligence, KWDev Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
279 lines
9.8 KiB
C++
279 lines
9.8 KiB
C++
#include "UI/Quest/UIQuestDisplay.h"
|
|
#include "Client/Input/Mouse.h"
|
|
#include "Contents/MessageTable.h"
|
|
#include "Contents/RenewQuestMgr.h"
|
|
#include "Contents/UserData/NormalItemSlots.h"
|
|
#include "Network/Connection/Connection.h"
|
|
#include "Network/Packets/PacketLengths.h"
|
|
#include "Render/Renderer.h"
|
|
#include "UI/Window/UIWindowMgr.h"
|
|
#include "UI/Window/WindowManagerWindows.h"
|
|
#include "UI/Text/ColoredText.h"
|
|
#include "UI/Text/NavigationLink.h"
|
|
#include "UI/Text/TextMarkup.h"
|
|
#include "UI/Text/UITextViewer.h"
|
|
#include "Utility/Text/FormatString.h"
|
|
|
|
#include <algorithm>
|
|
#include <cstring>
|
|
|
|
#pragma pack(push, 1)
|
|
struct PACKET_CZ_ACTIVE_QUEST {
|
|
short packetType;
|
|
unsigned int questId;
|
|
unsigned char active;
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
// OFFSET: 0x00948D10
|
|
// FUNCTION: fn_12881
|
|
void UIQuestDisplay::Create(int width, int height) {
|
|
this->SetSize(width, height);
|
|
}
|
|
|
|
// OFFSET: 0x0094A400
|
|
// FUNCTION: fn_12887
|
|
bool UIQuestDisplay::Slot08() {
|
|
return true;
|
|
}
|
|
|
|
// OFFSET: 0x0094D910
|
|
// FUNCTION: fn_12911
|
|
void UIQuestDisplay::Paint() {
|
|
this->ClearSurface(0xFF00FF);
|
|
|
|
CRenewQuestMgr* manager = g_renewQuestMgr;
|
|
int none = 0;
|
|
int multiple = 0;
|
|
int single = 0;
|
|
for (auto it = manager->m_ongoingQuests.begin(); it != manager->m_ongoingQuests.end(); ++it) {
|
|
const unsigned int questId = it->first;
|
|
const RenewQuestOngoingInfo& info = it->second;
|
|
if (info.m_active != true || info.m_simpleView != true) {
|
|
continue;
|
|
}
|
|
|
|
const int top = single * 50 + (none + multiple * 2) * 40;
|
|
std::string title = info.m_title.size() == 0 ? FormatOwnedString("Unknown Quest, ID = %d", questId) : info.m_title;
|
|
if (questId == reinterpret_cast<std::uintptr_t>(this->m_context)) {
|
|
this->FillRegion(-12, top - 2, this->geometry.width - 10, 40, 0);
|
|
}
|
|
this->DrawShadowedText(0, top, title.c_str(), 0, 0xD6E1, 0, 0, 12, 0);
|
|
|
|
std::string description = info.m_descriptions.size() == 0 ? std::string() : info.unknown_004C;
|
|
description = StripColorCodes(description.c_str(), description.size());
|
|
description = static_cast<const std::string&>(DisplayUrlTextTag(description));
|
|
description = static_cast<const std::string&>(DisplayNavigationTextTag(description));
|
|
description = static_cast<const std::string&>(DisplayTipBoxTextTag(description));
|
|
description = static_cast<const std::string&>(DisplayItemTextTag(description));
|
|
description = static_cast<const std::string&>(RemoveTextLinkInfo(description));
|
|
if (this->m_context->chatConverter) {
|
|
description = this->m_context->chatConverter->ConvertChat(description);
|
|
}
|
|
std::string navigation;
|
|
DisplayNavigationLink(navigation, description);
|
|
description = std::move(navigation);
|
|
description = static_cast<const std::string&>(DisplayQuestTextTag(description));
|
|
|
|
if (std::strlen(description.c_str()) > 30) {
|
|
description = this->TruncateText(description.c_str(), 30);
|
|
description += std::string("...");
|
|
}
|
|
if (std::strlen(description.c_str()) != 0) {
|
|
this->DrawShadowedText(0, top + 15, description.c_str(), 0, 0xFFFFFF, 0, 0, 12, 0);
|
|
}
|
|
|
|
if (info.m_huntCount == 0 || info.m_huntCount > 3) {
|
|
++none;
|
|
} else {
|
|
for (int index = 0; index < info.m_huntCount; ++index) {
|
|
std::string hunt;
|
|
if (info.m_huntUnknown00D4[index] == 31999) {
|
|
hunt = static_cast<const std::string&>(
|
|
g_renewQuestMgr->GetMonsterConditionText(info.m_huntUnknown01A0[index], info.m_huntUnknown01AC[index], info.m_huntUnknown01B2[index])
|
|
);
|
|
} else {
|
|
const short minLevel = info.m_huntUnknown01AC[index];
|
|
const short maxLevel = info.m_huntUnknown01B2[index];
|
|
const char* name = info.m_huntName[index];
|
|
if (minLevel < 0 || maxLevel < 0 || (minLevel == 0 && maxLevel == 0)) {
|
|
hunt = static_cast<const std::string&>(FormatOwnedString("%s", name));
|
|
} else if (minLevel == 0) {
|
|
hunt = static_cast<const std::string&>(FormatOwnedString("%s Lv.%d▼", name, maxLevel));
|
|
} else if (maxLevel == 0) {
|
|
hunt = static_cast<const std::string&>(FormatOwnedString("%s Lv.%d▲", name, minLevel));
|
|
} else {
|
|
hunt = static_cast<const std::string&>(FormatOwnedString("%s Lv.%d~Lv.%d", name, minLevel, maxLevel));
|
|
}
|
|
}
|
|
|
|
hunt = StripColorCodes(hunt.c_str(), hunt.size());
|
|
description = static_cast<const std::string&>(DisplayUrlTextTag(description));
|
|
description = static_cast<const std::string&>(DisplayNavigationTextTag(description));
|
|
description = static_cast<const std::string&>(DisplayTipBoxTextTag(description));
|
|
description = static_cast<const std::string&>(DisplayItemTextTag(description));
|
|
description = static_cast<const std::string&>(RemoveTextLinkInfo(description));
|
|
if (this->m_context->chatConverter) {
|
|
description = this->m_context->chatConverter->ConvertChat(description);
|
|
}
|
|
std::string huntNavigation;
|
|
DisplayNavigationLink(huntNavigation, description);
|
|
description = std::move(huntNavigation);
|
|
description = static_cast<const std::string&>(DisplayQuestTextTag(description));
|
|
|
|
const short goal = info.m_huntUnknown0180[index];
|
|
if (goal > 0) {
|
|
const short count = info.m_huntUnknown00E0[index];
|
|
if (count == goal) {
|
|
hunt = static_cast<const std::string&>(FormatOwnedString("%s ( %s )", hunt.c_str(), LookupMessage(0x7EE)));
|
|
} else {
|
|
hunt = static_cast<const std::string&>(FormatOwnedString("%s ( %d / %d )", hunt.c_str(), count, goal));
|
|
}
|
|
|
|
const int y = index * 13 + top;
|
|
this->DrawTextAt(this->m_context->fonts, this->m_context->locale, 11, y + 29, hunt.c_str(), 0, 0, 12, 0, 0, 0);
|
|
this->DrawTextAt(this->m_context->fonts, this->m_context->locale, 10, y + 28, hunt.c_str(), 0, 0, 12, 0xFFFFFF, 0, 0);
|
|
}
|
|
}
|
|
|
|
if (info.m_huntCount > 1) {
|
|
++multiple;
|
|
} else {
|
|
++single;
|
|
}
|
|
}
|
|
|
|
if (single + multiple + none >= 5) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x0094F1D0
|
|
// FUNCTION: fn_12934
|
|
void UIQuestDisplay::Slot33(int x, int y) {
|
|
const int previous = this->m_selectedIndex;
|
|
int selected = -1;
|
|
int single = 0;
|
|
int none = 0;
|
|
int multiple = 0;
|
|
int index = 0;
|
|
const auto end = g_renewQuestMgr->m_ongoingQuests.end();
|
|
for (auto it = g_renewQuestMgr->m_ongoingQuests.begin(); it != end; ++it, ++index) {
|
|
if (single + multiple + none >= 5) {
|
|
break;
|
|
}
|
|
|
|
const int top = single * 50 + (none + multiple * 2) * 40;
|
|
const RenewQuestOngoingInfo& info = it->second;
|
|
if (info.m_active && info.m_simpleView) {
|
|
if (top <= y && y <= top + 10) {
|
|
selected = index;
|
|
break;
|
|
}
|
|
|
|
if (info.m_huntCount == 0) {
|
|
++none;
|
|
} else if (info.m_huntCount > 1) {
|
|
++multiple;
|
|
} else {
|
|
++single;
|
|
}
|
|
}
|
|
}
|
|
|
|
this->m_selectedIndex = selected;
|
|
if (previous != this->m_selectedIndex) {
|
|
this->Invalidate();
|
|
}
|
|
|
|
if (this->m_selectedIndex != -1) {
|
|
this->SendMsg(nullptr, 49, 0, 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x009515D0
|
|
// FUNCTION: fn_12953
|
|
void UIQuestDisplay::Slot11() {
|
|
if (this->m_visibleSetting) {
|
|
*this->m_visibleSetting = this->geometry.visible;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00950BC0
|
|
// FUNCTION: fn_12947
|
|
int UIQuestDisplay::SendMsg(UIWindow* sender, int message, std::intptr_t argument1, std::intptr_t argument2, std::intptr_t argument3, std::intptr_t argument4) {
|
|
switch (message) {
|
|
case 34: {
|
|
this->m_visibleSetting = reinterpret_cast<int*>(argument1);
|
|
QuestDisplayInfo* info = reinterpret_cast<QuestDisplayInfo*>(argument1);
|
|
if (!info->IsValid()) {
|
|
info->Reset();
|
|
}
|
|
this->Show(*this->m_visibleSetting);
|
|
break;
|
|
}
|
|
case 48: {
|
|
int index = 0;
|
|
for (auto it = g_renewQuestMgr->m_ongoingQuests.begin(); it != g_renewQuestMgr->m_ongoingQuests.end(); ++it, ++index) {
|
|
if (index == this->m_selectedIndex) {
|
|
int command = this->m_menuItems[argument1].command;
|
|
if (command == 48) {
|
|
PACKET_CZ_ACTIVE_QUEST packet;
|
|
packet.packetType = 0x2B6;
|
|
packet.questId = it->first;
|
|
packet.active = !it->second.m_active;
|
|
GetRagConnection().Send(reinterpret_cast<const PacketLengths&>(GetRagConnection()).FixedLength(packet.packetType), &packet);
|
|
this->Invalidate();
|
|
} else if (command == 49) {
|
|
g_renewQuestMgr->sub_67B620(it->first);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 49: {
|
|
this->m_menuItems.clear();
|
|
if (g_windowMgr.unknown_0210 != 0) {
|
|
this->Show(0);
|
|
}
|
|
if (this->m_selectedIndex != -1) {
|
|
std::string text1 = LookupMessage(1622);
|
|
this->m_menuItems.push_back({text1.c_str(), 49});
|
|
std::string text2 = LookupMessage(351);
|
|
this->m_menuItems.push_back({text2.c_str(), 48});
|
|
}
|
|
if (!this->m_menuItems.empty()) {
|
|
UIWindow* menu = reinterpret_cast<WindowManagerWindows*>(&g_windowMgr)->EnsureWindow(18);
|
|
for (size_t i = 0; i < this->m_menuItems.size(); ++i) {
|
|
menu->SendMsg(nullptr, 31, reinterpret_cast<std::intptr_t>(this->m_menuItems[i].text.c_str()), 0, 0, 0);
|
|
}
|
|
menu->SendMsg(nullptr, 83, 204, 0, 0, 0);
|
|
menu->SendMsg(nullptr, 30, 0, 0, 0, 0);
|
|
|
|
int x = std::max(1, g_mouse.x + 1);
|
|
int maxX = g_renderer->viewport.width - menu->geometry.width;
|
|
if (x > maxX) {
|
|
x = maxX;
|
|
}
|
|
int y = std::max(1, g_mouse.y + 1);
|
|
int maxY = g_renderer->viewport.height - menu->geometry.height;
|
|
if (y > maxY) {
|
|
y = maxY;
|
|
}
|
|
menu->Move(x, y);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
return this->UIWindow::SendMsg(sender, message, argument1, argument2, argument3, argument4);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// OFFSET: 0x00946EA0
|
|
// FUNCTION: fn_12855
|
|
UIQuestDisplay::UIQuestDisplay(UIWindowContext& windows) : UIWindow(windows, 0) {
|
|
}
|