Batch #7063 by Landruca: 0 byte-identical, 1 confirmed by peer review. - fn_17234 UIWindowMgr::sub_AA6B80: logic confirmed by peer review Peer-reviewed-by: eAthena, Snow Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
1489 lines
44 KiB
C++
1489 lines
44 KiB
C++
#include "Render/Renderer.h"
|
|
#include "UI/Chat/UISubChatHisWnd.h"
|
|
#include "Client/Browser/WebBrowser.h"
|
|
#include "Client/Input/Mouse.h"
|
|
#include "Client/Mode/ModeMgr.h"
|
|
#include "Client/Replay.h"
|
|
#include "Client/ReplayPacketRecorder.h"
|
|
#include "Client/Session.h"
|
|
#include "Contents/Configuration/ServiceConfiguration.h"
|
|
#include "Contents/Configuration/ServiceOptions.h"
|
|
#include "Network/Connection/Connection.h"
|
|
#include "Network/Packets/PacketId.h"
|
|
#include "Network/Packets/PacketLengths.h"
|
|
#include "Render/TextureQuad.h"
|
|
#include "Render/Textures/Texture.h"
|
|
#include "Render/Textures/TextureCache.h"
|
|
#include "UI/Dialogs/UIMemorialDunWnd.h"
|
|
#include "UI/Layout/SnapMgr.h"
|
|
#include "UI/Lists/UIDropDownBox.h"
|
|
#include "UI/Chat/ChatSuggestions.h"
|
|
#include "UI/Window/MiniPartyWndAreaMgr.h"
|
|
#include "UI/Window/WindowDialogs.h"
|
|
#include "UI/Window/UIWindow.h"
|
|
#include "UI/Window/UIWindowMgr.h"
|
|
#include "Render/DeviceContext/DCSurface.h"
|
|
#include <algorithm>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <new>
|
|
#include <timeapi.h>
|
|
#include "Render/Textures/Surface.h"
|
|
namespace {
|
|
#pragma pack(push, 1)
|
|
struct AddFriendPacket {
|
|
/* 0000 */ std::int16_t id;
|
|
/* 0002 */ char name[24];
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
static_assert(sizeof(AddFriendPacket) == 26);
|
|
static_assert(offsetof(AddFriendPacket, name) == 2);
|
|
}
|
|
|
|
// GLOBAL: gl_24525
|
|
CMiniPartyWndAreaMgr* g_miniPartyWndAreaMgr = nullptr;
|
|
|
|
// GLOBAL: gl_24366
|
|
UIWindowMgr g_windowMgr;
|
|
|
|
// GLOBAL: gl_25090
|
|
unsigned char g_windowCloseByte;
|
|
|
|
// GLOBAL: gl_24686
|
|
int g_closeWindow137State;
|
|
|
|
// OFFSET: 0x00A94FD0
|
|
// FUNCTION: fn_17179
|
|
void UIWindowMgr::InitializeWindowPolicy() {
|
|
for (WindowPolicyEntry& entry : this->policy) {
|
|
entry = {};
|
|
entry.actions[3] = 1;
|
|
}
|
|
|
|
this->policy[15].actions[3] = 0;
|
|
this->policy[16].actions[3] = 0;
|
|
this->policy[17].actions[3] = 0;
|
|
this->policy[22].actions[3] = 0;
|
|
this->policy[23].actions[3] = 0;
|
|
this->policy[24].actions[3] = 0;
|
|
this->policy[25].actions[3] = 0;
|
|
this->policy[27].actions[3] = 0;
|
|
this->policy[28].actions[3] = 0;
|
|
this->policy[31].actions[3] = 0;
|
|
this->policy[32].actions[3] = 0;
|
|
this->policy[35].actions[3] = 0;
|
|
this->policy[39].actions[3] = 0;
|
|
this->policy[41].actions[3] = 0;
|
|
this->policy[43].actions[3] = 1;
|
|
this->policy[44].actions[3] = 0;
|
|
this->policy[45].actions[3] = 0;
|
|
this->policy[56].actions[3] = 0;
|
|
this->policy[70].actions[3] = 0;
|
|
this->policy[73].actions[3] = 0;
|
|
this->policy[74].actions[3] = 0;
|
|
this->policy[79].actions[3] = 0;
|
|
this->policy[80].actions[3] = 0;
|
|
this->policy[88].actions[3] = 0;
|
|
this->policy[90].actions[3] = 0;
|
|
this->policy[94].actions[3] = 0;
|
|
this->policy[99].actions[3] = 0;
|
|
this->policy[100].actions[3] = 0;
|
|
this->policy[105].actions[3] = 0;
|
|
this->policy[107].actions[3] = 0;
|
|
this->policy[109].actions[3] = 0;
|
|
this->policy[110].actions[3] = 0;
|
|
this->policy[111].actions[3] = 0;
|
|
this->policy[113].actions[3] = 0;
|
|
this->policy[119].actions[3] = 0;
|
|
this->policy[125].actions[3] = 0;
|
|
this->policy[160].actions[3] = 1;
|
|
this->policy[161].actions[3] = 1;
|
|
this->policy[174].actions[3] = 0;
|
|
this->policy[176].actions[3] = 0;
|
|
this->policy[178].actions[3] = 0;
|
|
this->policy[177].actions[3] = 0;
|
|
this->policy[179].actions[3] = 0;
|
|
this->policy[203].actions[3] = 0;
|
|
this->policy[157].actions[3] = 0;
|
|
this->policy[209].actions[3] = 0;
|
|
this->policy[210].actions[3] = 0;
|
|
this->policy[275].actions[3] = 0;
|
|
this->policy[315].actions[3] = 0;
|
|
this->policy[8].actions[5] = 1;
|
|
this->policy[22].actions[5] = 1;
|
|
this->policy[23].actions[5] = 1;
|
|
this->policy[24].actions[5] = 1;
|
|
this->policy[31].actions[5] = 1;
|
|
this->policy[10011].actions[5] = 1;
|
|
this->policy[33].actions[5] = 1;
|
|
this->policy[40].actions[5] = 1;
|
|
this->policy[41].actions[5] = 1;
|
|
this->policy[42].actions[5] = 1;
|
|
this->policy[43].actions[5] = 1;
|
|
this->policy[44].actions[5] = 1;
|
|
this->policy[160].actions[5] = 1;
|
|
this->policy[161].actions[5] = 1;
|
|
this->policy[174].actions[5] = 1;
|
|
this->policy[175].actions[5] = 1;
|
|
this->policy[178].actions[5] = 1;
|
|
this->policy[36].actions[5] = 1;
|
|
this->policy[159].actions[5] = 1;
|
|
this->policy[80].actions[5] = 1;
|
|
this->policy[1].actions[6] = 1;
|
|
this->policy[4].actions[6] = 1;
|
|
this->policy[15].actions[6] = 1;
|
|
this->policy[27].actions[6] = 1;
|
|
this->policy[28].actions[6] = 1;
|
|
this->policy[31].actions[6] = 1;
|
|
this->policy[10011].actions[6] = 1;
|
|
this->policy[41].actions[6] = 1;
|
|
this->policy[55].actions[6] = 1;
|
|
this->policy[56].actions[6] = 1;
|
|
this->policy[84].actions[6] = 1;
|
|
this->policy[88].actions[6] = 1;
|
|
this->policy[100].actions[6] = 1;
|
|
this->policy[101].actions[6] = 1;
|
|
this->policy[113].actions[6] = 1;
|
|
this->policy[116].actions[6] = 1;
|
|
this->policy[120].actions[6] = 1;
|
|
this->policy[121].actions[6] = 1;
|
|
this->policy[128].actions[6] = 1;
|
|
this->policy[125].actions[6] = 1;
|
|
this->policy[130].actions[6] = 1;
|
|
this->policy[145].actions[6] = 1;
|
|
this->policy[168].actions[6] = 1;
|
|
this->policy[169].actions[6] = 1;
|
|
this->policy[174].actions[6] = 1;
|
|
this->policy[181].actions[6] = 1;
|
|
this->policy[191].actions[6] = 1;
|
|
this->policy[203].actions[6] = 1;
|
|
this->policy[16].actions[7] = 1;
|
|
this->policy[17].actions[7] = 1;
|
|
this->policy[23].actions[7] = 1;
|
|
this->policy[24].actions[7] = 1;
|
|
this->policy[25].actions[7] = 1;
|
|
this->policy[28].actions[7] = 1;
|
|
this->policy[31].actions[7] = 1;
|
|
this->policy[10011].actions[7] = 1;
|
|
this->policy[32].actions[7] = 1;
|
|
this->policy[33].actions[7] = 1;
|
|
this->policy[35].actions[7] = 1;
|
|
this->policy[39].actions[7] = 1;
|
|
this->policy[41].actions[7] = 1;
|
|
this->policy[43].actions[7] = 1;
|
|
this->policy[44].actions[7] = 1;
|
|
this->policy[45].actions[7] = 1;
|
|
this->policy[70].actions[7] = 1;
|
|
this->policy[73].actions[7] = 1;
|
|
this->policy[74].actions[7] = 1;
|
|
this->policy[79].actions[7] = 1;
|
|
this->policy[80].actions[7] = 1;
|
|
this->policy[94].actions[7] = 1;
|
|
this->policy[105].actions[7] = 1;
|
|
this->policy[107].actions[7] = 1;
|
|
this->policy[109].actions[7] = 1;
|
|
this->policy[110].actions[7] = 1;
|
|
this->policy[111].actions[7] = 1;
|
|
this->policy[119].actions[7] = 1;
|
|
this->policy[161].actions[7] = 1;
|
|
this->policy[174].actions[7] = 1;
|
|
this->policy[176].actions[7] = 1;
|
|
this->policy[178].actions[7] = 1;
|
|
this->policy[177].actions[7] = 1;
|
|
this->policy[179].actions[7] = 1;
|
|
this->policy[203].actions[7] = 1;
|
|
this->policy[157].actions[7] = 1;
|
|
this->policy[209].actions[7] = 1;
|
|
this->policy[210].actions[7] = 1;
|
|
this->policy[321].actions[7] = 1;
|
|
this->policy[322].actions[7] = 1;
|
|
this->policy[307].actions[7] = 1;
|
|
this->policy[247].actions[7] = 1;
|
|
this->policy[316].actions[7] = 1;
|
|
}
|
|
|
|
// OFFSET: 0x00AA5F70
|
|
// FUNCTION: fn_17227
|
|
UIWindow* UIWindowMgr::LookupWindow(int id) {
|
|
if (g_replayAnimationScaling != 0 && id == 600) {
|
|
return this->window_4F16C;
|
|
}
|
|
|
|
switch (id) {
|
|
case 1:
|
|
return this->window_01C8;
|
|
case 3:
|
|
return this->window_01CC;
|
|
case 27:
|
|
return this->window_0274;
|
|
case 28:
|
|
return this->window_027C;
|
|
case 30:
|
|
return this->window_0278;
|
|
case 33:
|
|
return this->window_0288;
|
|
case 34:
|
|
return this->window_02C8;
|
|
case 37:
|
|
return this->window_02C4;
|
|
case 60:
|
|
return this->window_0320;
|
|
case 61:
|
|
return this->window_0324;
|
|
case 63:
|
|
return this->window_032C;
|
|
case 88:
|
|
return this->window_038C;
|
|
case 103:
|
|
return this->window_0388;
|
|
case 113:
|
|
return this->window_03C0;
|
|
case 114:
|
|
return this->window_03C4;
|
|
case 125:
|
|
return this->window_03C8;
|
|
case 126:
|
|
return this->window_03CC;
|
|
case 180:
|
|
return this->window_01D0;
|
|
case 196:
|
|
return this->window_4F18C;
|
|
case 203:
|
|
return this->window_4F174;
|
|
case 204:
|
|
return this->window_0428;
|
|
case 237:
|
|
return this->window_0444;
|
|
case 253:
|
|
return this->window_044C;
|
|
case 273:
|
|
return this->window_4F1CC;
|
|
case 274:
|
|
return this->window_4F1D0;
|
|
case 275:
|
|
return this->window_0448;
|
|
case 277:
|
|
return this->window_03D4;
|
|
case 284:
|
|
return this->window_4F1E8;
|
|
case 285:
|
|
return this->window_4F1EC;
|
|
case 286:
|
|
return this->window_4F1F0;
|
|
case 287:
|
|
return this->window_4F1F4;
|
|
case 288:
|
|
return this->window_4F1F8;
|
|
case 315:
|
|
return this->window_0468;
|
|
case 325:
|
|
return this->window_4F25C;
|
|
case 359:
|
|
return this->window_4F288;
|
|
case 10024:
|
|
return this->window_4F2AC;
|
|
case 301:
|
|
if (!this->snapExcluded.empty()) {
|
|
return this->snapExcluded.front();
|
|
}
|
|
[[fallthrough]];
|
|
case 318:
|
|
return this->window_4F254;
|
|
default: {
|
|
const auto found = this->windows.find(id);
|
|
return found != this->windows.end() ? found->second : nullptr;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// OFFSET: 0x00AA1800
|
|
// FUNCTION: fn_17209
|
|
void UIWindowMgr::ResetWindows() {
|
|
this->windows.clear();
|
|
this->window_01B8 = nullptr;
|
|
this->inputWindow = nullptr;
|
|
this->hoverWindow = nullptr;
|
|
this->window_01C8 = nullptr;
|
|
this->unknown_01BC = 0;
|
|
this->unknown_01DC = 0;
|
|
this->unknown_01D4 = 0;
|
|
this->unknown_01E0 = 0;
|
|
this->unknown_01E4 = 0;
|
|
this->unknown_01C4 = 0;
|
|
this->unknown_01C0 = 0;
|
|
this->window_01EC = nullptr;
|
|
this->unknown_01F0 = 0;
|
|
this->unknown_01F4 = 0;
|
|
this->unknown_01F8 = 0;
|
|
this->unknown_01FC = 0;
|
|
this->unknown_0208 = 0;
|
|
this->unknown_020C = 0;
|
|
this->unknown_0210 = 0;
|
|
this->unknown_0214 = 0;
|
|
this->unknown_0218 = 0;
|
|
this->unknown_021C = 0;
|
|
this->unknown_0220 = 0;
|
|
this->unknown_0228 = 0;
|
|
this->unknown_022C = 0;
|
|
this->window_0230 = nullptr;
|
|
this->unknown_0234 = 0;
|
|
this->unknown_0238 = 0;
|
|
this->unknown_023C = 0;
|
|
this->unknown_0240 = 0;
|
|
this->unknown_0244 = 0;
|
|
this->unknown_0248 = 0;
|
|
this->unknown_024C = 0;
|
|
this->unknown_0250 = 0;
|
|
this->unknown_0254 = 0;
|
|
this->unknown_0258 = 0;
|
|
this->unknown_025C = 0;
|
|
this->unknown_0260 = 0;
|
|
this->unknown_0264 = 0;
|
|
this->unknown_0268 = 0;
|
|
this->unknown_026C = 0;
|
|
this->window_0274 = nullptr;
|
|
this->window_0278 = nullptr;
|
|
this->window_027C = nullptr;
|
|
this->unknown_0280 = 0;
|
|
this->unknown_0284 = 0;
|
|
this->window_0288 = nullptr;
|
|
this->unknown_028C = 0;
|
|
this->unknown_0290 = 0;
|
|
this->unknown_0294 = 0;
|
|
this->unknown_0298 = 0;
|
|
this->unknown_029C = 0;
|
|
this->unknown_02A0 = 0;
|
|
this->unknown_02A4 = 0;
|
|
this->unknown_02A8 = 0;
|
|
this->unknown_02AC = 0;
|
|
this->window_02C4 = nullptr;
|
|
this->window_02C8 = nullptr;
|
|
this->unknown_02CC = 0;
|
|
this->unknown_02D0 = 0;
|
|
this->unknown_02D4 = 0;
|
|
this->unknown_02D8 = 0;
|
|
this->unknown_02DC = 0;
|
|
this->unknown_02E0 = 0;
|
|
this->unknown_02E4 = 0;
|
|
this->unknown_02E8 = 0;
|
|
this->unknown_02EC = 0;
|
|
this->window_01E8 = nullptr;
|
|
this->unknown_02F0 = 0;
|
|
this->unknown_02F4 = 0;
|
|
this->unknown_02F8 = 0;
|
|
this->unknown_02FC = 0;
|
|
this->unknown_0300 = 0;
|
|
this->unknown_0308 = 0;
|
|
this->unknown_0304 = 0;
|
|
this->window_03A4 = 0;
|
|
this->unknown_03A8 = 0;
|
|
this->window_03AC = 0;
|
|
this->unknown_030C = 0;
|
|
this->unknown_0310 = 0;
|
|
this->unknown_0314 = 0;
|
|
this->unknown_0318 = 0;
|
|
this->unknown_031C = 0;
|
|
this->window_0320 = nullptr;
|
|
this->window_0324 = nullptr;
|
|
this->unknown_0328 = 0;
|
|
this->window_032C = nullptr;
|
|
this->unknown_0330 = 0;
|
|
this->unknown_0334 = 0;
|
|
this->unknown_0338 = 0;
|
|
this->unknown_033C = 0;
|
|
this->unknown_0340 = 0;
|
|
this->unknown_0344 = 0;
|
|
this->unknown_0348 = 0;
|
|
this->unknown_034C = 0;
|
|
this->unknown_0350 = 0;
|
|
this->unknown_0354 = 0;
|
|
this->unknown_0358 = 0;
|
|
this->unknown_035C = 0;
|
|
this->unknown_0360 = 0;
|
|
this->unknown_0364 = 0;
|
|
this->unknown_0368 = 0;
|
|
this->unknown_036C = 0;
|
|
this->unknown_0370 = 0;
|
|
this->window_038C = nullptr;
|
|
this->unknown_0390 = 0;
|
|
this->unknown_0394 = 0;
|
|
this->unknown_0200 = 0;
|
|
this->unknown_0398 = 0;
|
|
this->unknown_039C = 0;
|
|
this->unknown_0380 = 0;
|
|
this->unknown_0384 = 0;
|
|
this->unknown_03B0 = 0;
|
|
this->unknown_03B4 = 0;
|
|
this->window_03C0 = nullptr;
|
|
this->window_03C4 = nullptr;
|
|
this->window_03C8 = nullptr;
|
|
this->window_03CC = nullptr;
|
|
this->unknown_03D0 = 0;
|
|
this->unknown_03B8 = 0;
|
|
this->unknown_03BC = 0;
|
|
this->window_03D4 = nullptr;
|
|
this->window_03D8 = nullptr;
|
|
this->unknown_03E0 = 0;
|
|
this->unknown_03E4 = 0;
|
|
this->unknown_03E8 = 0;
|
|
this->unknown_03F0 = 0;
|
|
this->unknown_03EC = 0;
|
|
this->unknown_03F8 = 0;
|
|
this->unknown_03FC = 0;
|
|
this->modal = 0;
|
|
this->unknown_0404 = 0;
|
|
this->unknown_0408 = 0;
|
|
this->unknown_040C = 0;
|
|
this->unknown_0410 = 0;
|
|
this->unknown_0414 = 0;
|
|
this->unknown_0418 = 0;
|
|
this->unknown_041C = 0;
|
|
this->unknown_0424 = 0;
|
|
this->retainedWindows.clear();
|
|
this->unknown_02B0 = 0;
|
|
this->unknown_02B4 = 0;
|
|
this->unknown_02B8 = 0;
|
|
this->unknown_02BC = 0;
|
|
this->unknown_02C0 = 0;
|
|
this->window_4F18C = nullptr;
|
|
this->window_4F164 = nullptr;
|
|
this->unknown_01D8 = 0;
|
|
this->window_0428 = nullptr;
|
|
this->window_4F174 = nullptr;
|
|
this->unknown_0440 = 0;
|
|
this->window_0444 = nullptr;
|
|
this->window_0448 = nullptr;
|
|
this->messageBoxes.clear();
|
|
this->window_044C = nullptr;
|
|
this->unknown_0204 = 0;
|
|
this->unknown_0378 = 0;
|
|
this->unknown_0374 = 0;
|
|
this->window_4F170 = nullptr;
|
|
this->unknown_0450 = 0;
|
|
this->unknown_0454 = 0;
|
|
this->unknown_0458 = 0;
|
|
this->unknown_045C = 0;
|
|
this->unknown_0430 = 0;
|
|
this->unknown_0434 = 0;
|
|
this->unknown_0438 = 0;
|
|
this->unknown_0460 = 0;
|
|
this->unknown_0464 = 0;
|
|
this->hiddenWindows.clear();
|
|
const bool hadWindow0270 = this->window_0270 != nullptr;
|
|
this->unknown_0508 = 0;
|
|
this->window_4F1CC = nullptr;
|
|
this->window_4F1D0 = nullptr;
|
|
this->window_4F1D4 = nullptr;
|
|
this->window_4F1E8 = nullptr;
|
|
this->window_4F1F0 = nullptr;
|
|
this->window_4F1F4 = nullptr;
|
|
this->window_4F1FC = nullptr;
|
|
this->window_4F250 = nullptr;
|
|
this->window_4F254 = nullptr;
|
|
this->window_4F258 = nullptr;
|
|
this->window_01CC = nullptr;
|
|
this->window_0468 = nullptr;
|
|
this->window_4F25C = nullptr;
|
|
this->unknown_042C = 0;
|
|
this->window_4F260 = nullptr;
|
|
this->window_4F264 = nullptr;
|
|
this->window_4F268 = nullptr;
|
|
this->window_4F26C = nullptr;
|
|
this->window_4F270 = nullptr;
|
|
this->window_4F274 = nullptr;
|
|
this->window_4F278 = nullptr;
|
|
this->window_4F27C = nullptr;
|
|
this->unknown_0420 = 0;
|
|
this->unknown_043C = 0;
|
|
this->window_01D0 = nullptr;
|
|
this->unknown_0224 = 0;
|
|
if (hadWindow0270) {
|
|
if (CMode* mode = g_modeMgr.GetGameMode()) {
|
|
mode->SendMsg(292, 0, 0, 0, 0);
|
|
}
|
|
}
|
|
const bool hadWindow276 = this->window_4F1E4 != nullptr;
|
|
this->window_0270 = nullptr;
|
|
this->unknown_037C = 0;
|
|
this->window_0388 = nullptr;
|
|
this->unknown_03A0 = 0;
|
|
if (hadWindow276) {
|
|
this->visible_276 = 0;
|
|
this->window_4F1E4 = nullptr;
|
|
}
|
|
this->window_4F1F8 = nullptr;
|
|
this->window_0A30 = nullptr;
|
|
this->window_4F2AC = nullptr;
|
|
}
|
|
|
|
// OFFSET: 0x00A88490
|
|
// FUNCTION: fn_17086
|
|
UIWindowMgr::UIWindowMgr()
|
|
: activeWindowId(0), retainedPersistentWindow(false), window_03DC(nullptr), unknown_046C(-1), unknown_0470(-1), unknown_0526(true),
|
|
window_0A30(nullptr), unknown_4F210(false), unknown_4F211(false), window_4F2AC(nullptr) {
|
|
this->ResetWindows();
|
|
this->unknown_0478 = nullptr;
|
|
this->unknown_047C = 0;
|
|
this->unknown_0480 = 0;
|
|
this->unknown_04DC.assign("", 0);
|
|
this->unknown_004C = 1;
|
|
this->unknown_0038 = 98;
|
|
this->unknown_0030 = 0;
|
|
this->unknown_0034 = 0;
|
|
this->unknown_003C = 1;
|
|
this->unknown_0050 = 1.0f;
|
|
this->unknown_0054 = 1;
|
|
this->unknown_005C = 0xAAFFFFFFu;
|
|
this->unknown_0060 = 1;
|
|
this->unknown_04F8 = 0;
|
|
this->unknown_04F4 = 0;
|
|
this->unknown_04FC = 0;
|
|
this->unknown_03F4 = 1;
|
|
this->unknown_03F6 = 0;
|
|
this->unknown_0068 = g_language == 2;
|
|
this->unknown_0048 = 0;
|
|
this->unknown_049C = 0;
|
|
this->unknown_049E = g_serviceType != 0 ? 0 : -25;
|
|
this->unknown_04A0 = {};
|
|
this->unknown_04A4 = {};
|
|
this->unknown_04A8 = {};
|
|
this->unknown_04AC = {};
|
|
this->unknown_04B0 = 0;
|
|
this->unknown_04B4 = 203;
|
|
this->unknown_04B8 = 115;
|
|
this->unknown_04BC = 0;
|
|
this->unknown_04C0 = 0;
|
|
this->windowHistory.clear();
|
|
this->lastWindowId = -1;
|
|
this->unknown_0024 = 0;
|
|
this->unknown_0026 = 1;
|
|
this->unknown_0508 = 0;
|
|
this->window_4F168 = nullptr;
|
|
this->window_4F164 = nullptr;
|
|
this->window_4F16C = nullptr;
|
|
this->InitializeWindowPolicy();
|
|
this->window_4F174 = nullptr;
|
|
this->unknown_09CC = 0;
|
|
this->browser_09D0 = nullptr;
|
|
this->currentHitUid = 0;
|
|
this->previousHitUid = 0;
|
|
this->visible_276 = 0;
|
|
this->window_4F1EC = nullptr;
|
|
this->window_4F250 = nullptr;
|
|
this->unknown_0058 = 0;
|
|
this->unknown_4F238 = 151;
|
|
this->unknown_4F23C = 37;
|
|
}
|
|
|
|
// OFFSET: 0x007375E0
|
|
// FUNCTION: fn_07649
|
|
CMiniPartyWndAreaMgr::CMiniPartyWndAreaMgr() {
|
|
SetRect(&this->area, 0, 0, g_windowMgr.unknown_047C, g_windowMgr.unknown_0480);
|
|
}
|
|
|
|
// OFFSET: 0x00AA66D0
|
|
// FUNCTION: fn_17233
|
|
void UIWindowMgr::Shutdown() {
|
|
if (!this->modalWindows.empty() && this->modalWindows.back()) {
|
|
this->activeWindowId = 185;
|
|
}
|
|
|
|
if (this->window_0A30 && this->window_0A30->geometry.visible) {
|
|
static_cast<CUIDropDownBox*>(this->window_0A30)->Detach();
|
|
this->window_0A30->Show(0);
|
|
}
|
|
|
|
for (UIWindow*& window : this->rendered) {
|
|
if (!this->modalWindows.empty() && this->modalWindows.back() && this->persistentWindows.find(window) != this->persistentWindows.end()) {
|
|
this->retainedPersistentWindow = true;
|
|
} else if (this->modalWindows.empty() || !this->modalWindows.back() ||
|
|
std::find(this->modalWindows.begin(), this->modalWindows.end(), window) == this->modalWindows.end()) {
|
|
this->persistentWindows.erase(window);
|
|
window->Slot11();
|
|
delete window;
|
|
window = nullptr;
|
|
}
|
|
}
|
|
|
|
for (auto& entry : this->browsers) {
|
|
delete entry.second;
|
|
entry.second = nullptr;
|
|
}
|
|
this->browsers.clear();
|
|
if (this->browser_09D0) {
|
|
delete this->browser_09D0;
|
|
this->browser_09D0 = nullptr;
|
|
}
|
|
|
|
for (auto entry = this->overlays.begin(); entry != this->overlays.end();) {
|
|
delete entry->second;
|
|
entry = this->overlays.erase(entry);
|
|
}
|
|
this->rendered.clear();
|
|
this->retired.clear();
|
|
this->snapRectangles.clear();
|
|
this->messageBoxes.clear();
|
|
this->ResetWindows();
|
|
|
|
for (UIWindow*& window : this->snapExcluded) {
|
|
this->Destroy(window);
|
|
window = nullptr;
|
|
}
|
|
this->snapExcluded.clear();
|
|
}
|
|
|
|
// OFFSET: 0x00AA6B80
|
|
// FUNCTION: fn_17234
|
|
void UIWindowMgr::sub_AA6B80() {
|
|
if (!this->modalWindows.empty() && this->modalWindows.back()) {
|
|
this->activeWindowId = 185;
|
|
}
|
|
|
|
this->SaveVisibleWindowIds();
|
|
if (!this->window_01C8) {
|
|
this->Shutdown();
|
|
return;
|
|
}
|
|
|
|
if (this->window_0A30 && this->window_0A30->geometry.visible) {
|
|
static_cast<CUIDropDownBox*>(this->window_0A30)->Detach();
|
|
this->window_0A30->Show(0);
|
|
}
|
|
|
|
for (auto entry = this->rendered.begin(); entry != this->rendered.end();) {
|
|
bool unregistered = true;
|
|
for (unsigned index = 0; index < this->retainedWindows.size(); ++index) {
|
|
if (*entry == this->retainedWindows[static_cast<int>(index)]) {
|
|
unregistered = false;
|
|
}
|
|
}
|
|
if (!unregistered) {
|
|
++entry;
|
|
continue;
|
|
}
|
|
|
|
UIWindow* window = *entry;
|
|
if (this->window_01C8 == window || window == this->window_4F1EC || window->geometry.id == 67) {
|
|
++entry;
|
|
continue;
|
|
}
|
|
|
|
if (window == reinterpret_cast<UIWindow*>(this->unknown_03F8) && g_closeWindow137State != 0) {
|
|
g_memorialDunWndX = window->geometry.x;
|
|
g_memorialDunWndY = window->geometry.y;
|
|
}
|
|
|
|
if (!this->modalWindows.empty() && this->modalWindows.back()) {
|
|
if (this->persistentWindows.find(window) != this->persistentWindows.end()) {
|
|
this->retainedPersistentWindow = true;
|
|
++entry;
|
|
continue;
|
|
}
|
|
if (std::find(this->modalWindows.begin(), this->modalWindows.end(), window) != this->modalWindows.end()) {
|
|
++entry;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
this->persistentWindows.erase(window);
|
|
window->Slot11();
|
|
delete window;
|
|
entry = this->rendered.erase(entry);
|
|
}
|
|
|
|
for (auto entry = this->retired.begin(); entry != this->retired.end();) {
|
|
bool unregistered = true;
|
|
for (unsigned index = 0; index < this->retainedWindows.size(); ++index) {
|
|
if (*entry == this->retainedWindows[static_cast<int>(index)]) {
|
|
unregistered = false;
|
|
}
|
|
}
|
|
if (!unregistered || this->window_01C8 == *entry) {
|
|
++entry;
|
|
continue;
|
|
}
|
|
|
|
entry = this->retired.erase(entry);
|
|
}
|
|
|
|
for (auto entry = this->snapRectangles.begin(); entry != this->snapRectangles.end();) {
|
|
if (this->window_01C8 == entry->first) {
|
|
++entry;
|
|
} else {
|
|
entry = this->snapRectangles.erase(entry);
|
|
}
|
|
}
|
|
|
|
std::uint32_t saved03E4 = 0;
|
|
if (this->unknown_03E4) {
|
|
saved03E4 = this->unknown_03E4;
|
|
}
|
|
std::uint32_t saved03E8 = 0;
|
|
if (this->unknown_03E8) {
|
|
saved03E8 = this->unknown_03E8;
|
|
}
|
|
std::uint32_t saved03F0 = 0;
|
|
if (this->unknown_03F0) {
|
|
saved03F0 = this->unknown_03F0;
|
|
}
|
|
UIWindow* saved01C8 = nullptr;
|
|
if (this->window_01C8) {
|
|
saved01C8 = this->window_01C8;
|
|
}
|
|
|
|
std::map<int, UIWindow*> savedWindows(this->retainedWindows);
|
|
this->ResetWindows();
|
|
this->window_01C8 = saved01C8;
|
|
this->unknown_03E4 = saved03E4;
|
|
this->unknown_03F0 = saved03F0;
|
|
this->unknown_03E8 = saved03E8;
|
|
this->retainedWindows = savedWindows;
|
|
|
|
for (UIWindow*& window : this->snapExcluded) {
|
|
this->Destroy(window);
|
|
window = nullptr;
|
|
}
|
|
this->snapExcluded.clear();
|
|
}
|
|
|
|
// OFFSET: 0x00A8A1C0
|
|
// FUNCTION: fn_17099
|
|
UIWindowMgr::~UIWindowMgr() {
|
|
if (!g_miniPartyWndAreaMgr) {
|
|
g_miniPartyWndAreaMgr = new (std::nothrow) CMiniPartyWndAreaMgr;
|
|
}
|
|
if (g_miniPartyWndAreaMgr) {
|
|
delete g_miniPartyWndAreaMgr;
|
|
g_miniPartyWndAreaMgr = nullptr;
|
|
}
|
|
|
|
this->Shutdown();
|
|
if (this->unknown_0478) {
|
|
delete this->unknown_0478;
|
|
this->unknown_0478 = nullptr;
|
|
}
|
|
for (auto& entry : this->savedRectangles) {
|
|
delete entry.second;
|
|
}
|
|
this->savedRectangles.clear();
|
|
}
|
|
|
|
// OFFSET: 0x00A8B0A0
|
|
// FUNCTION: fn_17121
|
|
void UIWindowMgr::SelectWhisperName(const char* name) {
|
|
if (!name || !this->window_01C8) {
|
|
return;
|
|
}
|
|
|
|
char* list = *reinterpret_cast<char**>(reinterpret_cast<char*>(this->window_01C8) + 0xC0);
|
|
std::vector<std::string>& names = *reinterpret_cast<std::vector<std::string>*>(list + 0x11C);
|
|
int index = 0;
|
|
bool found = false;
|
|
for (const std::string& entry : names) {
|
|
if (entry == name) {
|
|
found = true;
|
|
break;
|
|
}
|
|
++index;
|
|
}
|
|
|
|
if (!found) {
|
|
names.push_back(std::string(name));
|
|
}
|
|
|
|
UIWindow* field = *reinterpret_cast<UIWindow**>(reinterpret_cast<char*>(this->window_01C8) + 0xC0);
|
|
*reinterpret_cast<int*>(reinterpret_cast<char*>(field) + 0x128) = index;
|
|
this->window_01C8->SendMsg(field, 0x27, index, 0, 0, 0);
|
|
}
|
|
|
|
// OFFSET: 0x00A8B240
|
|
// FUNCTION: fn_17122
|
|
void UIWindowMgr::AddWhisperName(const char* name) {
|
|
if (!this->window_01C8) {
|
|
return;
|
|
}
|
|
|
|
char* list = *reinterpret_cast<char**>(reinterpret_cast<char*>(this->window_01C8) + 0xC0);
|
|
std::vector<std::string>& names = *reinterpret_cast<std::vector<std::string>*>(list + 0x11C);
|
|
for (const std::string& entry : names) {
|
|
if (entry == name) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
names.push_back(std::string(name));
|
|
const unsigned count = static_cast<unsigned>(names.size());
|
|
unsigned& current = *reinterpret_cast<unsigned*>(*reinterpret_cast<char**>(reinterpret_cast<char*>(this->window_01C8) + 0xC0) + 0x128);
|
|
if (count - 1 <= current) {
|
|
current = count;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00A8B840
|
|
// FUNCTION: fn_17124
|
|
void UIWindowMgr::RegisterNamedWindow(std::string name, UIWindow* window) {
|
|
if (this->namedWindows.find(name) == this->namedWindows.end()) {
|
|
this->namedWindows[name] = window;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00AA9B00
|
|
// FUNCTION: fn_17254
|
|
void UIWindowMgr::NotifyMode() {
|
|
if (CMode* mode = g_modeMgr.GetGameMode()) {
|
|
mode->SendMsg(292, 0, 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00A8AD60
|
|
// FUNCTION: fn_17116
|
|
void UIWindowMgr::ShowTransient(UIWindow* window) {
|
|
if (this->window_4F250) {
|
|
this->Schedule(this->window_4F250);
|
|
}
|
|
|
|
this->window_4F250 = window;
|
|
window->geometry.targetAlpha = 128;
|
|
window->geometry.alphaStart = timeGetTime();
|
|
this->rendered.push_back(this->window_4F250);
|
|
}
|
|
|
|
// OFFSET: 0x00A8ADB0
|
|
// FUNCTION: fn_17117
|
|
void UIWindowMgr::RequestAddFriend(const char* name) {
|
|
AddFriendPacket packet;
|
|
packet.id = ID_CZ_ADD_FRIENDS;
|
|
std::memcpy(packet.name, name, sizeof(packet.name));
|
|
GetRagConnection().Send(g_packetLengths.FixedLength(packet.id), &packet);
|
|
}
|
|
|
|
// OFFSET: 0x00A8AE20
|
|
// FUNCTION: fn_17118
|
|
void UIWindowMgr::AddOverlay(int id, UIWindow* window) {
|
|
this->overlays.emplace(id, window);
|
|
}
|
|
|
|
// OFFSET: 0x00A8B9F0
|
|
// FUNCTION: fn_17126
|
|
void UIWindowMgr::AddRenderedFront(UIWindow* window) {
|
|
this->rendered.push_front(window);
|
|
}
|
|
|
|
// OFFSET: 0x00A8C150
|
|
// FUNCTION: fn_17129
|
|
void UIWindowMgr::ShowWindows189(unsigned char show) {
|
|
for (auto it = this->rendered.begin(); it != this->rendered.end(); ++it) {
|
|
if ((*it)->geometry.id != 189) {
|
|
continue;
|
|
}
|
|
|
|
if (show == 1) {
|
|
(*it)->Show(g_serviceOptions.Get(250) ? 1 : 0);
|
|
} else {
|
|
(*it)->Show(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00A8C310
|
|
// FUNCTION: fn_17131
|
|
void UIWindowMgr::DestroyPersistentWindows() {
|
|
while (!this->modalWindows.empty()) {
|
|
UIWindow* window = this->modalWindows.back();
|
|
this->persistentWindows.erase(window);
|
|
delete window;
|
|
this->modalWindows.pop_back();
|
|
}
|
|
|
|
for (UIWindow* window : this->persistentWindows) {
|
|
delete window;
|
|
}
|
|
this->persistentWindows.clear();
|
|
}
|
|
|
|
// OFFSET: 0x00A8CD70
|
|
// FUNCTION: fn_17140
|
|
void UIWindowMgr::RemoveSnapRectangle(UIWindow* window) {
|
|
if (g_serviceOptions.Get(141)) {
|
|
const auto entry = this->snapRectangles.find(window);
|
|
if (entry != this->snapRectangles.end()) {
|
|
this->snapRectangles.erase(entry);
|
|
}
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00A8CDE0
|
|
// FUNCTION: fn_17141
|
|
void UIWindowMgr::ReleaseRetainedWindow(int id) {
|
|
const auto entry = this->retainedWindows.find(id);
|
|
if (entry != this->retainedWindows.end()) {
|
|
this->Schedule(entry->second);
|
|
this->retainedWindows.erase(entry);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00A8CE50
|
|
// FUNCTION: fn_17142
|
|
void UIWindowMgr::UnregisterNamedWindow(std::string name) {
|
|
const auto entry = this->namedWindows.find(name);
|
|
if (entry != this->namedWindows.end()) {
|
|
this->namedWindows.erase(entry);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00AAD8E0
|
|
// FUNCTION: fn_17285
|
|
void UIWindowMgr::SendMsgToNamedWindow(const char* name) {
|
|
if (this->namedWindows.find(name) != this->namedWindows.end()) {
|
|
this->namedWindows[name]->SendMsg(nullptr, 48, 0, 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00AAA280
|
|
// FUNCTION: fn_17267
|
|
void UIWindowMgr::SetWindows189Visible(unsigned char show) {
|
|
for (auto it = this->rendered.begin(); it != this->rendered.end(); ++it) {
|
|
if ((*it)->geometry.id == 189) {
|
|
(*it)->Show(show);
|
|
}
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00AAA2D0
|
|
// FUNCTION: fn_17268
|
|
void UIWindowMgr::ShowWindowsWithId(int id, unsigned char show) {
|
|
for (UIWindow* window : this->rendered) {
|
|
if (id == window->geometry.id) {
|
|
window->Show(show);
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace {
|
|
|
|
#pragma pack(push, 1)
|
|
struct ReplaySettingHeader {
|
|
/* 0000 */ std::int16_t tag;
|
|
/* 0002 */ int size;
|
|
|
|
ReplaySettingHeader() : tag(0), size(0) {
|
|
}
|
|
|
|
~ReplaySettingHeader() {
|
|
this->tag = 0;
|
|
this->size = 0;
|
|
}
|
|
|
|
void Read(const unsigned char* source) {
|
|
this->size = 0;
|
|
this->tag = 0;
|
|
std::memcpy(this, source, sizeof(*this));
|
|
}
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
static_assert(sizeof(ReplaySettingHeader) == 6);
|
|
|
|
}
|
|
|
|
// OFFSET: 0x00AA80A0
|
|
// FUNCTION: fn_17240
|
|
void UIWindowMgr::CenterSurface0478() {
|
|
this->unknown_04FC = 0;
|
|
if (this->unknown_0478) {
|
|
int x = static_cast<int>(GetRenderSystemHolder()->Width() - this->unknown_047C) / 2;
|
|
int height = this->unknown_0480;
|
|
int y = static_cast<int>(GetRenderSystemHolder()->Height() - height) / 2;
|
|
reinterpret_cast<CSurface*>(this->unknown_0478)->Stretch(x, y, this->unknown_047C, height);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00AA8130
|
|
// FUNCTION: fn_17242
|
|
std::vector<unsigned char> UIWindowMgr::SaveReplaySettings() {
|
|
std::vector<unsigned char> data;
|
|
{
|
|
std::vector<unsigned char> chunk(6);
|
|
*reinterpret_cast<std::int16_t*>(&chunk[0]) = 25000;
|
|
*reinterpret_cast<int*>(&chunk[2]) = 0;
|
|
data.insert(data.end(), chunk.begin(), chunk.end());
|
|
}
|
|
{
|
|
std::vector<unsigned char> chunk(10);
|
|
*reinterpret_cast<std::int16_t*>(&chunk[0]) = 25010;
|
|
*reinterpret_cast<int*>(&chunk[2]) = 4;
|
|
*reinterpret_cast<int*>(&chunk[6]) = this->unknown_0064;
|
|
data.insert(data.end(), chunk.begin(), chunk.end());
|
|
}
|
|
{
|
|
std::vector<unsigned char> chunk(6);
|
|
*reinterpret_cast<std::int16_t*>(&chunk[0]) = 25001;
|
|
*reinterpret_cast<int*>(&chunk[2]) = 0;
|
|
data.insert(data.end(), chunk.begin(), chunk.end());
|
|
}
|
|
return data;
|
|
}
|
|
|
|
// OFFSET: 0x00AA8440
|
|
// FUNCTION: fn_17243
|
|
std::vector<unsigned char> UIWindowMgr::SaveReplayReserved() {
|
|
std::vector<unsigned char> data;
|
|
{
|
|
std::vector<unsigned char> chunk(6);
|
|
*reinterpret_cast<std::int16_t*>(&chunk[0]) = 26000;
|
|
*reinterpret_cast<int*>(&chunk[2]) = 0;
|
|
data.insert(data.end(), chunk.begin(), chunk.end());
|
|
}
|
|
{
|
|
std::vector<unsigned char> chunk(6);
|
|
*reinterpret_cast<std::int16_t*>(&chunk[0]) = 26001;
|
|
*reinterpret_cast<int*>(&chunk[2]) = 0;
|
|
data.insert(data.end(), chunk.begin(), chunk.end());
|
|
}
|
|
return data;
|
|
}
|
|
|
|
// OFFSET: 0x00AA8980
|
|
// FUNCTION: fn_17245
|
|
void UIWindowMgr::ApplyReplayOptions(const ReplayOptions& options) {
|
|
this->unknown_05A4 = 0;
|
|
this->unknown_0588 = 0;
|
|
this->unknown_0568 = 0;
|
|
this->unknown_054C = 0;
|
|
this->unknown_073C = 0;
|
|
this->unknown_077C = 0;
|
|
this->unknown_05BC = 0;
|
|
this->unknown_05D0 = 0;
|
|
this->unknown_0758 = options.unknown_0007;
|
|
this->unknown_003C = options.recordRestricted;
|
|
}
|
|
|
|
// OFFSET: 0x00AA8B20
|
|
// FUNCTION: fn_17247
|
|
int UIWindowMgr::LoadReplaySettings(const std::vector<unsigned char>& data) {
|
|
if (data.empty()) {
|
|
return -1;
|
|
}
|
|
|
|
ReplaySettingHeader header;
|
|
unsigned offset = 6;
|
|
header.Read(data.data());
|
|
if (header.tag != 25000) {
|
|
offset = static_cast<unsigned>(-1);
|
|
} else {
|
|
while (offset < data.size()) {
|
|
header.Read(data.data() + offset);
|
|
offset += 6;
|
|
if (header.tag == 25001) {
|
|
break;
|
|
}
|
|
if (header.tag == 25010) {
|
|
std::memcpy(&this->unknown_0064, data.data() + offset, header.size);
|
|
}
|
|
offset += header.size;
|
|
}
|
|
}
|
|
return static_cast<int>(offset);
|
|
}
|
|
|
|
// OFFSET: 0x00AA8C30
|
|
// FUNCTION: fn_17248
|
|
int UIWindowMgr::LoadReplayReserved(const std::vector<unsigned char>& data) {
|
|
if (data.empty()) {
|
|
return -1;
|
|
}
|
|
|
|
ReplaySettingHeader header;
|
|
unsigned offset = 6;
|
|
header.Read(data.data());
|
|
if (header.tag != 26000) {
|
|
offset = static_cast<unsigned>(-1);
|
|
} else {
|
|
while (offset < data.size()) {
|
|
header.Read(data.data() + offset);
|
|
offset += 6;
|
|
if (header.tag == 26001) {
|
|
break;
|
|
}
|
|
offset += header.size;
|
|
}
|
|
}
|
|
return static_cast<int>(offset);
|
|
}
|
|
|
|
// OFFSET: 0x00AA8F50
|
|
// FUNCTION: fn_17252
|
|
void UIWindowMgr::BroadcastMessage21() {
|
|
UIWindow* window = this->window_03DC;
|
|
if (window || (window = this->unknown_03B0) != nullptr) {
|
|
window->SendMsg(nullptr, 21, 0, 0, 0, 0);
|
|
return;
|
|
}
|
|
|
|
for (UIWindow* rendered : this->rendered) {
|
|
if (rendered->Slot02()) {
|
|
rendered->SendMsg(nullptr, 21, 0, 0, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00AB1120
|
|
// FUNCTION: fn_17332
|
|
bool UIWindowMgr::IsHoverOnWindow01C8Button() {
|
|
const UIWindow* window = this->window_01C8;
|
|
if (window) {
|
|
UIWindow* const* buttons = reinterpret_cast<UIWindow* const*>(reinterpret_cast<const char*>(window) + 0xBC);
|
|
if (this->hoverWindow == buttons[0] || this->hoverWindow == buttons[1]) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// OFFSET: 0x007D5250
|
|
// FUNCTION: fn_09589
|
|
bool UIWindowMgr::HasModalWindow() {
|
|
UIWindow* top = this->modalWindows.empty() ? nullptr : this->modalWindows.back();
|
|
return top != nullptr;
|
|
}
|
|
|
|
// OFFSET: 0x00A8BC00
|
|
|
|
// OFFSET: 0x00AA8660
|
|
// FUNCTION: fn_17244
|
|
std::vector<unsigned char> UIWindowMgr::SaveReplayWindows() {
|
|
std::vector<unsigned char> data;
|
|
{
|
|
std::vector<unsigned char> chunk(6);
|
|
*reinterpret_cast<std::int16_t*>(&chunk[0]) = 20000;
|
|
*reinterpret_cast<int*>(&chunk[2]) = 0;
|
|
data.insert(data.end(), chunk.begin(), chunk.end());
|
|
}
|
|
for (UIWindow* window : this->rendered) {
|
|
const unsigned id = static_cast<unsigned>(window->geometry.id);
|
|
if (id <= 10040 && this->policy[id].actions[7]) {
|
|
std::vector<std::uint32_t> state = window->Slot44();
|
|
const int tag = window->geometry.id + 20100;
|
|
std::vector<unsigned char> chunk(state.size() * sizeof(std::uint32_t) + 6, 0);
|
|
*reinterpret_cast<std::int16_t*>(&chunk[0]) = static_cast<std::int16_t>(tag);
|
|
*reinterpret_cast<int*>(&chunk[2]) = static_cast<int>(state.size() * sizeof(std::uint32_t));
|
|
if (state.size() * sizeof(std::uint32_t)) {
|
|
std::memcpy(&chunk[6], state.data(), state.size() * sizeof(std::uint32_t));
|
|
}
|
|
data.insert(data.end(), chunk.begin(), chunk.end());
|
|
}
|
|
}
|
|
{
|
|
std::vector<unsigned char> chunk(6);
|
|
*reinterpret_cast<std::int16_t*>(&chunk[0]) = 20001;
|
|
*reinterpret_cast<int*>(&chunk[2]) = 0;
|
|
data.insert(data.end(), chunk.begin(), chunk.end());
|
|
}
|
|
return data;
|
|
}
|
|
|
|
void __fastcall sub_DFF150(CSession* session);
|
|
|
|
// OFFSET: 0x00A8C4B0
|
|
// FUNCTION: fn_17132
|
|
void UIWindowMgr::sub_A8C4B0(int id) {
|
|
g_session.EraseRecord0734(id);
|
|
this->unknown_4F248.push_back(id);
|
|
sub_DFF150(&g_session);
|
|
}
|
|
|
|
__forceinline void RecordEditTextsNoArg(UIWindow* window) {
|
|
union {
|
|
int (UIWindow::*method)(WindowReplayRecorder&);
|
|
void (__thiscall* call)(UIWindow*);
|
|
} convert;
|
|
convert.method = &UIWindow::RecordEditTexts;
|
|
convert.call(window);
|
|
}
|
|
|
|
// OFFSET: 0x00A8CA20
|
|
// FUNCTION: fn_17139
|
|
bool UIWindowMgr::sub_A8CA20() {
|
|
if (g_replayAnimationScaling != 0) {
|
|
return false;
|
|
}
|
|
|
|
bool handled = true;
|
|
if (!this->modalWindows.empty() && this->modalWindows.back() != nullptr) {
|
|
reinterpret_cast<const WindowDialogs*>(this)->Top()->SendMsg(nullptr, 0, 0, 0, 0, 0);
|
|
return true;
|
|
}
|
|
|
|
UIWindow* window = reinterpret_cast<UIWindow*>(static_cast<std::uintptr_t>(this->unknown_0234));
|
|
if (window == nullptr) {
|
|
window = reinterpret_cast<UIWindow*>(static_cast<std::uintptr_t>(this->unknown_0314));
|
|
if (window != nullptr) {
|
|
if (Replay::Instance().state == 2) {
|
|
RecordEditTextsNoArg(window);
|
|
}
|
|
window->SendMsg(nullptr, 0, 0, 0, 0, 0);
|
|
return true;
|
|
}
|
|
window = reinterpret_cast<UIWindow*>(static_cast<std::uintptr_t>(this->unknown_0318));
|
|
if (window != nullptr) {
|
|
if (Replay::Instance().state == 2) {
|
|
RecordEditTextsNoArg(window);
|
|
}
|
|
window->SendMsg(nullptr, 0, 0, 0, 0, 0);
|
|
return true;
|
|
}
|
|
window = this->unknown_01F8;
|
|
if (window == nullptr) {
|
|
window = this->unknown_01F0;
|
|
}
|
|
if (window == nullptr) {
|
|
window = this->unknown_01F4;
|
|
}
|
|
if (window == nullptr) {
|
|
window = this->unknown_0214;
|
|
}
|
|
if (window == nullptr) {
|
|
window = this->unknown_021C;
|
|
if (window != nullptr) {
|
|
window->SendMsg(nullptr, 0x13, 0, 0, 0, 0);
|
|
return true;
|
|
}
|
|
window = this->unknown_020C;
|
|
if (window == nullptr) {
|
|
window = this->unknown_0374;
|
|
}
|
|
if (window == nullptr) {
|
|
window = reinterpret_cast<UIWindow*>(static_cast<std::uintptr_t>(this->unknown_0378));
|
|
}
|
|
if (window == nullptr) {
|
|
window = reinterpret_cast<UIWindow*>(static_cast<std::uintptr_t>(this->unknown_030C));
|
|
}
|
|
if (window == nullptr) {
|
|
if (this->hoverWindow != nullptr) {
|
|
if (this->window_01C8 != nullptr && this->hoverWindow->parent == this->window_01C8) {
|
|
if (reinterpret_cast<const ChatSuggestions*>(this->window_01C8)->Visible()) {
|
|
UIWindow* child = *reinterpret_cast<UIWindow**>(reinterpret_cast<unsigned char*>(this->window_01C8) + 0x13C);
|
|
if (child != nullptr) {
|
|
child->SendMsg(nullptr, 0xB0, 0xD, 0, 0, 0);
|
|
return true;
|
|
}
|
|
}
|
|
handled = false;
|
|
}
|
|
if (Replay::Instance().state == 2 && handled) {
|
|
RecordEditTextsNoArg(this->hoverWindow->Root());
|
|
}
|
|
if (g_windowCloseByte == 0) {
|
|
handled = true;
|
|
} else if (!handled) {
|
|
return false;
|
|
}
|
|
this->hoverWindow->SendMsg(nullptr, 0, 0, 0, 0, 0);
|
|
return handled;
|
|
}
|
|
window = this->window_03D4;
|
|
if (window == nullptr) {
|
|
if (this->window_01C8 != nullptr && reinterpret_cast<const unsigned char*>(&g_windowCloseByte)[-2] == 1) {
|
|
handled = false;
|
|
RecordEditTextsNoArg(this->window_01C8);
|
|
window = this->window_01C8;
|
|
} else {
|
|
for (UIWindow* item : this->rendered) {
|
|
if (!item->Slot02()) {
|
|
continue;
|
|
}
|
|
if (g_replayAnimationScaling == 0) {
|
|
RecordEditTextsNoArg(item->Root());
|
|
}
|
|
item->SendMsg(nullptr, 0, 0, 0, 0, 0);
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
window->SendMsg(nullptr, 0, 0, 0, 0, 0);
|
|
return handled;
|
|
}
|
|
|
|
// OFFSET: 0x00A97580
|
|
// FUNCTION: fn_17205
|
|
UIWindow* UIWindowMgr::sub_A97580(int id, int x, int y, int width, int height) {
|
|
if (x == -1 && y == -1) {
|
|
x = (id + 10) * 10;
|
|
y = (id + 5) * 20;
|
|
}
|
|
if (width == 0 || width > g_renderer->viewport.width) {
|
|
width = 300;
|
|
}
|
|
if (height == 0 || height > g_renderer->viewport.height) {
|
|
height = 0x5F;
|
|
}
|
|
int posX = g_renderer->viewport.width - width;
|
|
if (x <= g_renderer->viewport.width) {
|
|
posX = x;
|
|
}
|
|
int posY = y;
|
|
if (y > g_renderer->viewport.height) {
|
|
posY = 100;
|
|
}
|
|
|
|
UIWindow* window = this->retainedWindows[id];
|
|
if (window == nullptr) {
|
|
UISubChatHisWnd* created = new UISubChatHisWnd();
|
|
created->m_index = id;
|
|
created->SetSize(width, height);
|
|
created->Move(posX, posY);
|
|
this->rendered.push_back(created);
|
|
this->retainedWindows[id] = created;
|
|
window = created;
|
|
}
|
|
window->Show(1);
|
|
return window;
|
|
}
|
|
|
|
// OFFSET: 0x00AA76F0
|
|
// FUNCTION: fn_17239
|
|
void UIWindowMgr::DrawLoginOverlay() {
|
|
const short quarter = static_cast<short>(g_renderer->viewport.width / 4);
|
|
const short third = static_cast<short>(g_renderer->viewport.height / 3);
|
|
char name[256];
|
|
|
|
if (CTexture* grade = g_texMgr.Load("유저인터페이스\\\0_GameGrade.tga", 0, false, true, false)) {
|
|
this->unknown_04B4 = grade->Width();
|
|
this->unknown_04B8 = grade->Height();
|
|
}
|
|
|
|
int gradeLeft = this->unknown_04BC;
|
|
if (gradeLeft == 0) {
|
|
gradeLeft = g_renderer->viewport.width - this->unknown_04B4 - 10;
|
|
this->unknown_04BC = gradeLeft;
|
|
}
|
|
|
|
int gradeTop = this->unknown_04C0;
|
|
if (gradeTop == 0) {
|
|
this->unknown_04C0 = 10;
|
|
gradeTop = 10;
|
|
}
|
|
|
|
if (g_mouse.buttons[0] == 1) {
|
|
if (!this->inputWindow) {
|
|
this->unknown_04B0 = 0;
|
|
if (g_mouse.x > gradeLeft && g_mouse.x < this->unknown_04B4 + gradeLeft && g_mouse.y > gradeTop && g_mouse.y < this->unknown_04B8 + gradeTop) {
|
|
this->unknown_04B0 = 3;
|
|
}
|
|
|
|
const float columns = static_cast<float>(quarter);
|
|
const float mouseX = static_cast<float>(g_mouse.x);
|
|
if (mouseX > columns * 3.3f + this->unknown_04A8.x && mouseX < columns * 3.9f + this->unknown_04A8.x &&
|
|
static_cast<float>(g_mouse.y) > static_cast<float>(third) * 2.4f + this->unknown_04A8.y &&
|
|
static_cast<float>(g_mouse.y) < static_cast<float>(third) * 2.8f + this->unknown_04A8.y) {
|
|
this->unknown_04B0 = 2;
|
|
}
|
|
|
|
if (static_cast<float>(g_mouse.x) > columns * 0.1f + this->unknown_049C && static_cast<float>(g_mouse.x) < columns * 1.8f + this->unknown_049C &&
|
|
static_cast<float>(g_mouse.y) > static_cast<float>(third) * 0.3f + this->unknown_049E &&
|
|
static_cast<float>(g_mouse.y) < static_cast<float>(third) * 1.2f + this->unknown_049E) {
|
|
this->unknown_04B0 = 1;
|
|
}
|
|
|
|
if (g_serviceType != 0 && static_cast<signed char>(g_startupSecondPhase) > 0 && static_cast<float>(g_mouse.x) > columns * 2.2f + this->unknown_04A0.x &&
|
|
static_cast<float>(g_mouse.x) < columns * 3.5f + this->unknown_04A0.x && g_mouse.y > this->unknown_04A0.y &&
|
|
g_mouse.y < this->unknown_04A0.y + third * 3) {
|
|
this->unknown_04B0 = 5;
|
|
}
|
|
|
|
if (static_cast<float>(g_mouse.y) > static_cast<float>(third) * 2.7f + this->unknown_04A4.x &&
|
|
static_cast<float>(g_mouse.y) < static_cast<float>(third) * 3.0f + this->unknown_04A4.x) {
|
|
this->unknown_04B0 = 4;
|
|
}
|
|
}
|
|
} else if (g_mouse.buttons[0] == 2 && !this->inputWindow) {
|
|
if (this->unknown_04B0 == 1) {
|
|
this->unknown_049C += static_cast<short>(g_mouse.deltaX);
|
|
this->unknown_049E += static_cast<short>(g_mouse.deltaY);
|
|
} else if (this->unknown_04B0 == 2) {
|
|
this->unknown_04A8.x += static_cast<short>(g_mouse.deltaX);
|
|
this->unknown_04A8.y += static_cast<short>(g_mouse.deltaY);
|
|
} else if (this->unknown_04B0 == 3) {
|
|
this->unknown_04BC += g_mouse.deltaX;
|
|
this->unknown_04C0 += g_mouse.deltaY;
|
|
} else if (this->unknown_04B0 == 6) {
|
|
this->unknown_04AC.x += static_cast<short>(g_mouse.deltaX);
|
|
this->unknown_04AC.y += static_cast<short>(g_mouse.deltaY);
|
|
} else if (this->unknown_04B0 == 4) {
|
|
if (this->unknown_04A4.x + g_mouse.deltaY >= 0) {
|
|
this->unknown_04A4.x += static_cast<short>(g_mouse.deltaY);
|
|
}
|
|
} else if (this->unknown_04B0 == 5) {
|
|
if (g_serviceType != 0 || this->unknown_04A0.x + g_mouse.deltaX >= 0) {
|
|
this->unknown_04A0.x += static_cast<short>(g_mouse.deltaX);
|
|
}
|
|
}
|
|
}
|
|
|
|
RECT rect = {0, 0, g_renderer->viewport.width, g_renderer->viewport.height};
|
|
const TextureRegion region = {0.0f, 0.0f, 1.0f, 1.0f};
|
|
if (CTexture* login = g_texMgr.Load("유저인터페이스\\t_login.jpg", 0, false, true, false)) {
|
|
g_modeMgr.GetGameMode()->DrawTexture(rect, 0, 0.0999f, 0xFFFFFFFF, login, region);
|
|
}
|
|
|
|
const int step = quarter;
|
|
const float rows = static_cast<float>(third);
|
|
char tape = 0;
|
|
for (int x = 0; x < step * 4;) {
|
|
++tape;
|
|
rect.left = x;
|
|
x += step;
|
|
rect.right = x;
|
|
rect.bottom = static_cast<int>(this->unknown_04A4.x + rows * 3.0f);
|
|
rect.top = static_cast<int>(this->unknown_04A4.x + rows * 2.5f);
|
|
this->unknown_04A4.y = static_cast<short>(rect.top);
|
|
std::sprintf(name, "유저인터페이스\\\0_테입%d.tga", tape);
|
|
g_modeMgr.GetGameMode()->DrawTexture(rect, 0, 0.0999f, 0xFFFFFFFF, g_texMgr.Load(name, 0, false, true, false), region);
|
|
}
|
|
|
|
rect.left = this->unknown_04BC;
|
|
rect.top = this->unknown_04C0;
|
|
rect.right = this->unknown_04B4 + this->unknown_04BC;
|
|
rect.bottom = this->unknown_04B8 + this->unknown_04C0;
|
|
g_modeMgr.GetGameMode()->DrawTexture(rect, 0, 0.0999f, 0xFFFFFFFF, g_texMgr.Load("유저인터페이스\\\0_GameGrade.tga", 0, false, true, false), region);
|
|
|
|
rect.left = static_cast<int>(this->unknown_04A8.x + static_cast<float>(step) * 3.1f);
|
|
rect.right = step + rect.left;
|
|
rect.top = static_cast<int>(this->unknown_04A8.y + rows * 2.4f);
|
|
const float half = rows * 0.5f;
|
|
rect.bottom = static_cast<int>(static_cast<float>(rect.top) + half);
|
|
g_modeMgr.GetGameMode()->DrawTexture(rect, 0, 0.0999f, 0xFFFFFFFF, g_texMgr.Load("유저인터페이스\\\0_중력성인.tga", 0, false, true, false), region);
|
|
|
|
char row = -2;
|
|
for (int column = this->unknown_049C; column < this->unknown_049C + step * 2; column += step) {
|
|
++row;
|
|
int y = static_cast<int>(this->unknown_049E + rows * 0.1f);
|
|
if (this->unknown_049E + (rows + rows) > static_cast<float>(y)) {
|
|
const int left = static_cast<int>(static_cast<float>(step) * 0.05f + column);
|
|
char index = row;
|
|
do {
|
|
index += 2;
|
|
rect.left = left;
|
|
rect.top = y;
|
|
rect.right = step + left;
|
|
if (index <= 2) {
|
|
y += third;
|
|
rect.bottom = y;
|
|
} else {
|
|
rect.bottom = static_cast<int>(static_cast<float>(y) + half);
|
|
y += third;
|
|
}
|
|
std::sprintf(name, "유저인터페이스\\\0_R%d.tga", index);
|
|
g_modeMgr.GetGameMode()->DrawTexture(rect, 0, 0.0999f, 0xFFFFFFFF, g_texMgr.Load(name, 0, false, true, false), region);
|
|
} while (this->unknown_049E + (rows + rows) > static_cast<float>(y));
|
|
}
|
|
}
|
|
}
|