Maintenance: Link-completeness fixes so the whole client links into one executable (all units in data/compile.json plus exe-only thir

Batch #13186 by ragnarok-clanker: forced by an admin (40 lower score(s), 206 changed function(s)); checked with 620 compiled unit(s), including every includer of Source/Archive/GPak.h, Source/Client/Mode/CGameMode.h, Source/Client/Mode/CLoginMode.h, Source/Client/Session.h, Source/Client/Stove/StoveMgr.h, Source/Client/Stove/StovePCSDK.h, Source/Client/Timer.h, Source/Contents/Actors/GameActor.h, Source/Contents/Actors/RenderObject.h, Source/Contents/CashEmotionMgr.h, Source/Contents/Configuration/ServiceOptions.h, Source/Contents/Skills/SkillTreeScript.h, Source/Render/DX9/D3DX9Runtime.h, Source/Resource/GifResource.h, Source/UI/AdventureGuide/UIAdventureGuide.h, Source/UI/Cooldowns/CooldownOwner.h, Source/UI/Edit/UIEditBoxEx.h, Source/UI/Lists/UIListBoxTemplate.h, Source/UI/Quest/UIRenewQuestUI.h, Source/UI/Rodex/UIRodexComposeWnd.h, Source/UI/Text/UITextViewerControl.h, Source/UI/UIBroadcastBalloon.h, Source/UI/UICaptchaRegisterWnd.h, Source/UI/UIMacroDetectorWnd.h, Source/UI/UIReputeWnd.h, Source/UI/Window/UIRegisterMgr.h, Source/UI/Window/UISecondCostumeWnd.h, Source/UI/Window/UISelCharForUServerWnd.h, Source/UI/Window/UIWindow.h, Source/UI/Window/UIWindowMgr.h, Source/Utility/EncryptedName.h.
This commit is contained in:
ragnarok-clanker 2026-11-06 10:56:48 +00:00
commit fec919b88e
110 changed files with 1184 additions and 940 deletions

View file

@ -524,7 +524,6 @@ unsigned int Triple32Hash(unsigned int value) {
void sub_6468C0(void* first, void* last, const void* val);
void sub_646930(void* first, void* last, const void* val);
[[noreturn]] void sub_4F9440();
struct VectorUint32_654D10 {
unsigned int* first;
@ -543,7 +542,7 @@ __declspec(noinline) void VectorUint32_654D10::AssignFill(unsigned int count, un
return;
}
if (count > 0x3fffffff) {
sub_4F9440();
std::_Throw_bad_array_new_length();
}
unsigned int bytes = count * sizeof(unsigned int);
unsigned int* new_ptr;
@ -555,7 +554,7 @@ __declspec(noinline) void VectorUint32_654D10::AssignFill(unsigned int count, un
}
} else {
if (bytes + 0x23 <= bytes) {
sub_4F9440();
std::_Throw_bad_array_new_length();
}
void* raw = ::operator new(bytes + 0x23);
if (!raw) {
@ -601,7 +600,7 @@ __declspec(noinline) void VectorInt32_654E00::AssignFill(unsigned int count, int
return;
}
if (count > 0x3fffffff) {
sub_4F9440();
std::_Throw_bad_array_new_length();
}
unsigned int bytes = count * sizeof(int);
int* new_ptr;
@ -613,7 +612,7 @@ __declspec(noinline) void VectorInt32_654E00::AssignFill(unsigned int count, int
}
} else {
if (bytes + 0x23 <= bytes) {
sub_4F9440();
std::_Throw_bad_array_new_length();
}
void* raw = ::operator new(bytes + 0x23);
if (!raw) {
@ -997,19 +996,19 @@ HashNode_655340* HashTable_655340::EraseRange(HashNode_655340* first, HashNode_6
return last;
}
void sub_6563E0(void*, void*, void*);
struct PakUniformRandom {
/* 0000 */ std::mt19937 m_engine;
/* 1388 */ std::uniform_int_distribution<int> m_distribution;
PakUniformRandom(int minimum, int maximum, unsigned int seed);
};
#if defined(_WIN32) && !defined(_WIN64)
static_assert(offsetof(PakUniformRandom, m_distribution) == 0x1388);
#endif
// OFFSET: 0x006563E0
// FUNCTION: fn_05073
__declspec(noinline) void FillRandomBytes(char* first, char* last, PakUniformRandom& random) {
for (; first != last; ++first) {
*first = static_cast<char>(random.m_distribution(random.m_engine));
}
}
struct PakKeyBlock48 {
/* 0000 */ std::uint8_t bytes[48];
};
@ -1039,7 +1038,7 @@ short* PakCipherBlock_655900::Encode(const short* in, const int* src) {
unsigned int seed = std::_Random_device();
PakUniformRandom rng(1, 0xfe, seed);
sub_6563E0(key_ptr, payload, &rng);
FillRandomBytes(reinterpret_cast<char*>(key_ptr), payload, rng);
const unsigned char* in_bytes = reinterpret_cast<const unsigned char*>(src);
unsigned char* out_bytes = reinterpret_cast<unsigned char*>(out);
@ -1139,9 +1138,16 @@ HashSearchResult_655D70 HashTable_655340::FindLast(const short* key, unsigned in
struct SeedGen_657C30 {
unsigned int seed;
unsigned int sub_657C30();
__declspec(noinline) unsigned int sub_657C30();
};
// OFFSET: 0x00657C30
// FUNCTION: fn_05095
__declspec(noinline) unsigned int SeedGen_657C30::sub_657C30() {
this->seed = static_cast<unsigned int>(static_cast<unsigned __int64>(this->seed) * 40014u % 0x7fffffabu);
return this->seed;
}
struct RanluxEngine_655F00 {
void Seed(const unsigned int* seed_ptr, char flag, int unused);
};
@ -1844,33 +1850,6 @@ namespace GPakEx {
return this;
}
class BlockCipherStub {
public:
/* 0000 */ void* m_vftable;
void sub_642A60();
};
class CipherModeStub {
public:
/* 0000 */ void* m_vftable;
/* 0004 */ BlockCipherStub* m_cipher;
/* 0008 */ std::uint8_t* m_register[3];
/* 0014 */ std::uint8_t* m_buffer[3];
void sub_642A70();
std::size_t CiphertextLength(std::size_t length, bool padding) const;
std::size_t Process(std::span<const std::uint8_t> input, std::span<std::uint8_t> output, bool final);
void SetKeyWithIV(std::span<const std::uint8_t> key, std::span<const std::uint8_t> iv);
};
template<std::size_t StateSize>
class FixedStateBlockCipher : public BlockCipherStub {
public:
/* 0004 */ std::uint8_t m_state[StateSize];
};
// OFFSET: 0x006434B0
// FUNCTION: fn_04838
__declspec(noinline) void XorBuffers(std::uint8_t* output, const std::uint8_t* input, const std::uint8_t* mask, std::size_t length) {
@ -3314,25 +3293,6 @@ namespace GPakEx {
static_assert(offsetof(GostCfbDecryption, m_blockCipher) == 0x2C);
class CipherModeFinal_6470D0 : public CipherModeStub {
public:
/* 0020 */ FixedStateBlockCipher<0xD0> m_blockCipher;
// INLINED
CipherModeFinal_6470D0() {
this->sub_6470D0();
}
// INLINED
~CipherModeFinal_6470D0() {
SecureWipe(this->m_blockCipher.m_state, sizeof(this->m_blockCipher.m_state));
this->m_blockCipher.sub_642A60();
this->sub_642A70();
}
void sub_6470D0();
};
}
using PakBlockTransform = void (*)(std::span<const std::uint8_t>, std::span<const std::uint8_t, 60>, std::span<const std::uint8_t, 16>, std::span<std::uint8_t, 16>);
@ -3342,7 +3302,7 @@ __forceinline void EncryptBlockWithDataHash(std::span<const std::uint8_t> data,
std::span<const std::uint8_t, 16> input, std::span<std::uint8_t, 16> output) {
const auto iv = keyData.subspan(Deobfuscate<0x53F9360C, 0x4CC36824>(ivOffset), Deobfuscate<0x53F9360C, 0x4CC36824>(8));
XXH128_hash_t key = XXH3_128bits(data.data(), data.size());
GPakEx::CipherModeFinal_6470D0 cipher;
GPakEx::IdeaCbcEncryption cipher;
cipher.SetKeyWithIV(std::span<const std::uint8_t>(reinterpret_cast<const std::uint8_t*>(&key), sizeof(key)), iv);
cipher.Process(input, output, false);
SecureWipe(&key, sizeof(key));
@ -3353,7 +3313,7 @@ __forceinline void EncryptDataHash(std::span<const std::uint8_t> data, std::span
std::span<const std::uint8_t, 16> key, std::span<std::uint8_t, 16> output) {
const auto iv = keyData.subspan(Deobfuscate<0x53F9360C, 0x4CC36824>(ivOffset), Deobfuscate<0x53F9360C, 0x4CC36824>(8));
XXH128_hash_t hash = XXH3_128bits(data.data(), data.size());
GPakEx::CipherModeFinal_6470D0 cipher;
GPakEx::IdeaCbcEncryption cipher;
cipher.SetKeyWithIV(key, iv);
cipher.Process(std::span<const std::uint8_t>(reinterpret_cast<const std::uint8_t*>(&hash), sizeof(hash)), output, false);
SecureWipe(&hash, sizeof(hash));

View file

@ -8,8 +8,18 @@
#include <cstdint>
#include <span>
#include <string_view>
#include <random>
#include <vector>
struct PakUniformRandom {
/* 0000 */ std::mt19937 m_engine;
/* 1388 */ std::uniform_int_distribution<int> m_distribution;
PakUniformRandom(int minimum, int maximum, unsigned int seed);
};
void FillRandomBytes(char* first, char* last, PakUniformRandom& random);
namespace myGPack {
struct PakEntry {

View file

@ -78,11 +78,11 @@ LRESULT CALLBACK sub_E5C430(HWND window, UINT message, WPARAM wParam, LPARAM lPa
for (int i = 0; i < count; ++i) {
candidates[i] = g_serverLanguage->Candidate(first + i);
}
g_windowMgr.sub_A978D0(0x33)->SendMsg(nullptr, 0x41, reinterpret_cast<std::intptr_t>(candidates), reinterpret_cast<std::intptr_t>(info), 0, 0);
g_windowMgr.EnsureWindow(0x33)->SendMsg(nullptr, 0x41, reinterpret_cast<std::intptr_t>(candidates), reinterpret_cast<std::intptr_t>(info), 0, 0);
}
if (g_serverLanguage->DisplayLength()) {
g_windowMgr.sub_A978D0(0x55)->Invalidate();
g_windowMgr.EnsureWindow(0x55)->Invalidate();
} else {
g_windowMgr.CloseWindow(0x55);
}

View file

@ -1,4 +1,5 @@
#include "Client/Application/Launcher.h"
#include "Utility/EncryptedName.h"
#include "Utility/Cipher/XorBytes.h"
#include "Utility/Text/FormatString.h"
#include "Contents/Configuration/ServiceConfiguration.h"
@ -109,41 +110,6 @@ HINSTANCE g_instance;
// GLOBAL: gl_24584
char g_applicationDirectory[0x80];
template <std::size_t Length, std::uint64_t Key>
class EncryptedName {
public:
// INLINED
template <typename Source>
explicit EncryptedName(const Source (&source)[Length]) : m_encrypted(true) {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = source[index];
}
}
~EncryptedName() {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = 0;
}
}
bool Encrypted() const {
return this->m_encrypted;
}
const char* Text() {
if (this->m_encrypted) {
utility::XorBytes(this->m_text, Length, Key);
this->m_encrypted = false;
}
return reinterpret_cast<const char*>(this->m_text);
}
private:
/* 0000 */ std::uint8_t m_text[Length];
bool m_encrypted;
};
// INLINED
template <std::uint64_t Key, typename Source, std::size_t Length>
EncryptedName<Length, Key>& ThreadLocalName(const Source (&source)[Length]) {
@ -931,7 +897,7 @@ public:
virtual ~CEquipmentPropertiesMgr();
static CEquipmentPropertiesMgr* GetInstance();
void sub_6AD910();
bool InitializeLua();
};
}
@ -941,7 +907,7 @@ void sub_E198F0();
void __fastcall sub_81FE50(CSignBoardMgr* manager);
LRESULT CALLBACK sub_E5C430(HWND window, UINT message, WPARAM wParam, LPARAM lParam);
int sub_E59030();
void sub_AEA780();
int RemoveProtectionTools();
void sub_3DE90E0(char* buffer);
void IgnoreNull();
LSTATUS SaveDisplayDeviceSettings();
@ -1403,9 +1369,9 @@ std::pair<bool, std::string> InitializeManagers() {
Singleton<CEnchantMgr>::GetInstance()->Init();
GetMapSkyMgr()->LoadData();
Singleton<CSelectPackageItemMgr>::GetInstance()->LoadScript();
Singleton<CUIRegisterMgr>::GetInstance()->sub_9EB920();
Singleton<CUIRegisterMgr>::GetInstance()->Load();
Singleton<CJobCodeForItem>::GetInstance()->Init();
EquipmentProperties::CEquipmentPropertiesMgr::GetInstance()->sub_6AD910();
EquipmentProperties::CEquipmentPropertiesMgr::GetInstance()->InitializeLua();
if (!CAdventureGuideMgr::Create()) {
return std::make_pair(false, std::string(AdventureGuideCreateInstanceName()().Text()));
}
@ -1838,7 +1804,7 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE previous, LPSTR commandLine, in
CoUninitialize();
DestroyWindow(hWnd);
sub_AEA780();
RemoveProtectionTools();
ShutdownManagers();
CSoundMgr::Destroy();
CoUninitialize();

View file

@ -264,7 +264,6 @@ public:
bool HasResurrectionItem();
void SendMousePointerState(int value);
void ShowSpecialPopup(int popupId);
void ReceiveNpcAckMapmove(const unsigned char* packet);
void ReceiveZoneServerChange(const unsigned char* packet);
void ReceiveZoneServerChange(const char* mapName, std::int16_t x, std::int16_t y, int ip, std::int16_t port);
void RequestLocalMapMove(const char* mapName, std::uint16_t x, std::uint16_t y);
@ -465,7 +464,6 @@ public:
void ReceiveEnchantSimulation(const unsigned char* packet);
void ReceivePackageSimulation(const unsigned char* packet);
void ReceiveSimulationResult(const unsigned char* packet);
void sub_D606B0(const unsigned char* packet);
void ReceiveWindow154Result(std::int16_t value);
void ReceivePlayerDuration(const unsigned char* packet);
void ReceiveFailureNotice(const unsigned char* packet);
@ -574,12 +572,6 @@ public:
__declspec(noinline) unsigned sub_CEBF30(const std::vector<unsigned char>& data);
unsigned sub_CEC100(const std::vector<unsigned char>& data);
unsigned sub_CEC6A0(const std::vector<unsigned char>& data);
void sub_D2DB80(const unsigned char* record);
void sub_D3D2F0(const unsigned char* record);
void sub_D3F130(const unsigned char* record);
void sub_D24430(const unsigned char* record);
void sub_D350A0(const unsigned char* record);
void sub_D37A10(const unsigned char* record);
void sub_D40730(const unsigned char* record);
void ReceiveGroundSkill8(const unsigned char* record);
void ReceiveGroundSkill32(const unsigned char* record);
@ -600,25 +592,13 @@ public:
void sub_D1A330(const unsigned char* data);
void sub_D1A520(int unknown_0004, std::string name, std::string text, bool flag);
void SpawnGroundSkill(std::uint32_t aid, std::uint32_t owner, int value, std::int16_t x, std::int16_t y, int type, signed char level, unsigned char visible, unsigned char flags);
void sub_D60D70(std::uint32_t aid, std::uint32_t owner, std::int16_t x, std::int16_t y);
void sub_D41250(const unsigned char* record);
void sub_D51A90(const unsigned char* record);
void sub_D61390(const unsigned char* record);
void sub_D616B0(const unsigned char* record);
void sub_D619E0(const unsigned char* record);
void sub_D63720(const unsigned char* record);
void sub_D63A40(const unsigned char* record);
void sub_D63D70(const unsigned char* record);
void sub_D41250(const unsigned char* record);
void sub_D65FC0(const unsigned char* record);
void ReceiveBroadcastBalloonNotice(const unsigned char* packet);
void ReceiveUnknownD65870(const unsigned char* packet);
void ReceiveStatusChangeEffect2(const unsigned char* packet);
void ReceiveActorStatusValuePacket2(const unsigned char* packet);
void ReceiveWindow95Data(const unsigned char* packet);
void sub_D7B170(
int first, int second, int third, int fourth, int fifth, int sixth, int seventh, int eighth, int ninth, int tenth,
int eleventh, int twelfth, int thirteenth, int fourteenth, std::string text, int fifteenth
);
int Run() override;
void Initialize(const char* name) override;
void End() override;
@ -1031,6 +1011,13 @@ void SendPacketHeader2(std::uint16_t packetType);
void sub_D73A10(const unsigned char* packet);
void sub_D6E440();
struct MiniMapEffectMarker {
/* 0000 */ int count;
/* 0004 */ int x;
/* 0008 */ int y;
};
extern std::map<int, MiniMapEffectMarker> g_miniMapEffectMarkers;
extern char g_pendingWhisperCount;
extern int g_whisperRecord;
extern int g_timeAttackStart;

View file

@ -72,6 +72,19 @@ struct CharacterSlotExtension {
};
#pragma pack(pop)
struct LoginStringRecord {
/* 0000 */ std::string unknown_0000;
/* 0018 */ std::string unknown_0018;
/* 0030 */ std::string unknown_0030;
/* 0048 */ std::string unknown_0048;
/* 0060 */ std::string unknown_0060;
/* 0078 */ unsigned char unknown_0078[8];
};
#if defined(_WIN32) && !defined(_WIN64)
static_assert(sizeof(LoginStringRecord) == 0x80);
#endif
struct MapStateData {
/* 0000 */ std::uint32_t values[4];
};
@ -111,7 +124,7 @@ public:
/* 6F1C */ std::vector<int> unknown_6F1C;
/* 6F28 */ int unknown_6F28;
/* 6F2C */ std::vector<int> unknown_6F2C;
/* 6F38 */ std::vector<int> unknown_6F38;
/* 6F38 */ std::vector<LoginStringRecord> unknown_6F38;
/* 6F44 */ unsigned char savedInlineCharset;
/* 6F45 */ unsigned char unknown_6F45[0x3];
/* 6F48 */ int unknown_6F48;

View file

@ -1364,10 +1364,10 @@ int CGameMode::SendMsg(int event, int argument1, int argument2, int argument3, i
return 0;
}
case 0x105:
g_windowMgr.sub_A978D0(0xA8);
g_windowMgr.EnsureWindow(0xA8);
return 0;
case 0x10D:
g_windowMgr.sub_A978D0(0xA9);
g_windowMgr.EnsureWindow(0xA9);
return 0;
case 0x103: {
const GameModePacketDwordByteByte packet{
@ -2423,7 +2423,7 @@ int CGameMode::SendMsg(int event, int argument1, int argument2, int argument3, i
if (argument2 == 0) {
g_session.unknown_54C4.clear();
} else {
g_windowMgr.sub_A978D0(0x22);
g_windowMgr.EnsureWindow(0x22);
}
const GameModePacketDwordByte packet{0x2C7, static_cast<std::uint32_t>(argument1), static_cast<std::uint8_t>(argument2 != 0)};
GetRagConnection().Send(g_packetLengths.FixedLength(packet.packetId), &packet);
@ -2589,7 +2589,7 @@ int CGameMode::SendMsg(int event, int argument1, int argument2, int argument3, i
if (actor != nullptr && actor->unknown_0314 == 0) {
return 0;
}
g_windowMgr.sub_A978D0(0x5B)->SendMsg(nullptr, 0x50, 0, argument2, 0, 0);
g_windowMgr.EnsureWindow(0x5B)->SendMsg(nullptr, 0x50, 0, argument2, 0, 0);
return 0;
}
if (argument1 == 20000) {
@ -2607,7 +2607,7 @@ int CGameMode::SendMsg(int event, int argument1, int argument2, int argument3, i
}
if (argument1 == 40000) {
if (static_cast<std::uint32_t>(argument2) != g_session.unknown_1010) {
g_windowMgr.sub_A978D0(0xC4)->SendMsg(nullptr, 0x50, 0, argument2, 0, 0);
g_windowMgr.EnsureWindow(0xC4)->SendMsg(nullptr, 0x50, 0, argument2, 0, 0);
}
return 0;
}
@ -2650,7 +2650,7 @@ int CGameMode::SendMsg(int event, int argument1, int argument2, int argument3, i
return 0;
}
if (argument1 == 154) {
g_windowMgr.sub_A978D0(0x5F);
g_windowMgr.EnsureWindow(0x5F);
}
}
const std::uint16_t id = static_cast<std::uint16_t>(argument1);
@ -2962,7 +2962,7 @@ int CGameMode::SendMsg(int event, int argument1, int argument2, int argument3, i
}
const ITEM_INFO item = LookupClientItemByIdentity(g_session.m_inventoryItems, static_cast<std::uint32_t>(argument1));
if (item.unknown_0064 == 1) {
UIWindow* window = g_windowMgr.sub_A978D0(0x8A);
UIWindow* window = g_windowMgr.EnsureWindow(0x8A);
*reinterpret_cast<std::uint32_t*>(&this->unknown_0100[4]) = timeGetTime();
window->SendMsg(nullptr, 0x5B, argument1, argument2, 0, 0);
} else {
@ -3257,7 +3257,7 @@ int CGameMode::SendMsg(int event, int argument1, int argument2, int argument3, i
}
case 0xAF: {
if (argument3 != 0) {
g_windowMgr.sub_A978D0(0x22)->SendMsg(nullptr, 6, 0xD7, 1, 0, 0);
g_windowMgr.EnsureWindow(0x22)->SendMsg(nullptr, 6, 0xD7, 1, 0, 0);
}
const GameModePacketDwordDwordDword packet{
0x208, static_cast<std::uint32_t>(argument1), static_cast<std::uint32_t>(argument2),
@ -3410,7 +3410,7 @@ int CGameMode::SendMsg(int event, int argument1, int argument2, int argument3, i
return 0;
}
g_windowMgr.CloseWindow(0x35);
g_windowMgr.sub_A978D0(0x35);
g_windowMgr.EnsureWindow(0x35);
g_session.unknown_54AC = name;
return 0;
}
@ -5023,7 +5023,7 @@ unsigned CGameMode::sub_CEBF30(const std::vector<unsigned char>& data) {
std::vector<unsigned char> record(0x13);
std::memcpy(record.data(), data.data() + offset, header.size);
offset += header.size;
this->sub_D2DB80(record.data());
this->ReceiveItemFallEntry(record.data());
} else if (header.type == 15001) {
break;
} else {
@ -5066,68 +5066,68 @@ unsigned CGameMode::sub_CEC100(const std::vector<unsigned char>& data) {
case 0xC9:
std::memcpy(record.data(), data.data() + offset, header.size);
offset += header.size;
this->sub_D3F130(record.data());
this->ReceiveActorMessage32(record.data());
break;
case 0xCA:
std::memcpy(record.data(), data.data() + offset, header.size);
offset += header.size;
this->sub_D51A90(record.data());
this->ReceiveActorTitle(record.data());
break;
case 0xCB:
std::memcpy(record.data(), data.data() + offset, header.size);
offset += header.size;
this->sub_D3D2F0(record.data());
this->ReceivePlayerMessage82(record.data());
break;
case 0xCC:
std::memcpy(record.data(), data.data() + offset, header.size);
offset += header.size;
this->sub_D24430(record.data());
this->ReceiveActorText(record.data());
break;
case 0xD0:
std::memcpy(record.data(), data.data() + offset, header.size);
offset += header.size;
this->sub_D350A0(record.data());
this->ReceiveActorMoveEntryNamed(record.data());
break;
case 0xD2:
std::memcpy(record.data(), data.data() + offset, header.size);
offset += header.size;
this->sub_D37A10(record.data());
this->ReceiveActorStateEntryNamedOld(record.data());
break;
case 0xD4:
std::memcpy(record.data(), data.data() + offset, header.size);
offset += header.size;
this->sub_D619E0(record.data());
this->ReceiveActorMoveEntryLegacy(record.data());
break;
case 0xD5:
std::memcpy(record.data(), data.data() + offset, header.size);
offset += header.size;
this->sub_D61390(record.data());
this->ReceiveActorMoveEntry(record.data());
break;
case 0xD6:
std::memcpy(record.data(), data.data() + offset, header.size);
offset += header.size;
this->sub_D616B0(record.data());
this->ReceiveActorMoveEntryBody(record.data());
break;
case 0xD7:
std::memcpy(record.data(), data.data() + offset, header.size);
offset += header.size;
this->sub_D63D70(record.data());
this->ReceiveActorStateEntryLegacy(record.data());
break;
case 0xD8:
std::memcpy(record.data(), data.data() + offset, header.size);
offset += header.size;
this->sub_D63720(record.data());
this->ReceiveActorStateEntryNamed(record.data());
break;
case 0xD9:
std::memcpy(record.data(), data.data() + offset, header.size);
offset += header.size;
this->sub_D63A40(record.data());
this->ReceiveActorStateEntryNamedBody(record.data());
break;
case 0xDA: {
std::memcpy(record.data(), data.data() + offset, header.size);
offset += header.size;
const auto* stored = reinterpret_cast<const GameModeStoredRecord00DA*>(record.data());
this->sub_D7B170(
this->SpawnStandingPc2(
stored->value0002, stored->value0006, stored->value000A, stored->value000C, stored->value000E, stored->value000F,
stored->value0011, stored->value0015, stored->value0019, stored->value001B, stored->value001D, stored->value001F,
stored->value0021, stored->value0023, stored->text, stored->value003D
@ -7905,7 +7905,7 @@ void CGameMode::Initialize(const char* name) {
this->noticeBalloon = nullptr;
g_windowMgr.HideWindow01C8();
g_windowMgr.ShowWindowsWithId(0x43, 0);
g_windowMgr.sub_A978D0(7);
g_windowMgr.EnsureWindow(7);
g_windowMgr.SendNotice(4, 0, 0, 0, 0, 0);
g_windowMgr.CenterSurface0478();
g_windowMgr.DrawWindows();
@ -8805,8 +8805,6 @@ struct StatusPointRequestPacket {
static_assert(sizeof(StatusPointRequestPacket) == 5);
int sub_C7F5A0();
// GLOBAL: gl_25463
std::uint32_t g_spriteAtlasClearTick;
@ -8932,7 +8930,7 @@ void CGameMode::Update() {
return;
}
if (sub_C7F5A0()) {
if (ShouldRenderFrame()) {
g_renderer->ClearWorld();
g_actorPickNode.Clear();
this->camera->Render();
@ -9482,7 +9480,7 @@ void CGameMode::ExecuteTalkType(int talkType, std::string* arguments) {
g_windowToggleFlag = !g_windowToggleFlag;
g_windowMgr.SendNotice(3, 0, 0, 0, 0, 0);
if (g_windowToggleFlag) {
g_windowMgr.sub_A978D0(0x74);
g_windowMgr.EnsureWindow(0x74);
} else {
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(LookupMessage(0x3AF)), 0x64FFFF, 0, 0, 0);
}
@ -9579,7 +9577,7 @@ void CGameMode::ExecuteTalkType(int talkType, std::string* arguments) {
}
case 42:
if (!g_windowMgr.CloseWindow(0x13B)) {
g_windowMgr.sub_A978D0(0x13B);
g_windowMgr.EnsureWindow(0x13B);
}
break;
case 29:
@ -9983,7 +9981,7 @@ void CGameMode::ExecuteTalkType(int talkType, std::string* arguments) {
break;
}
case 217:
g_windowMgr.sub_A978D0(0xCB);
g_windowMgr.EnsureWindow(0xCB);
break;
case 207: {
char text[1024];
@ -10084,7 +10082,7 @@ void CGameMode::ExecuteTalkType(int talkType, std::string* arguments) {
}
case 237:
if (!g_windowMgr.CloseWindow(0x144)) {
g_windowMgr.sub_A978D0(0x144);
g_windowMgr.EnsureWindow(0x144);
}
break;
case 254:

View file

@ -395,7 +395,7 @@ void CGameMode::ReceiveGroundSkillExtended(const unsigned char* record) {
return;
}
case 0x126:
this->sub_D60D70(packet.aid, packet.owner, packet.x, packet.y);
this->SpawnMirrorActor(packet.aid, packet.owner, packet.x, packet.y);
return;
}
@ -441,7 +441,7 @@ void CGameMode::ReceiveGroundSkillExtended(const unsigned char* record) {
// FUNCTION: fn_21824
void CGameMode::SpawnGroundSkill(std::uint32_t aid, std::uint32_t owner, int value, std::int16_t x, std::int16_t y, int type, signed char level, unsigned char visible, unsigned char flags) {
if (type == 0x126) {
this->sub_D60D70(aid, owner, x, y);
this->SpawnMirrorActor(aid, owner, x, y);
return;
}
GroundSkillArgumentData data;
@ -2560,7 +2560,7 @@ void CGameMode::ReceiveSimulationResult(const unsigned char* packet) {
this->ReceivePackageSimulation(packet);
break;
case 2:
this->sub_D606B0(packet);
this->ReceiveRandomOptionSimulation(packet);
break;
case 3:
this->ReceiveEnchantSimulation(packet);

View file

@ -84,14 +84,6 @@ __forceinline const char* TimeFontSpriteName() {
// GLOBAL: gl_25107
CFile g_whisperFile;
struct MiniMapEffectMarker {
/* 0000 */ int count;
/* 0004 */ int x;
/* 0008 */ int y;
};
// GLOBAL: gl_25132
std::map<std::uint32_t, MiniMapEffectMarker> g_miniMapEffectMarkers;
// OFFSET: 0x00CCFCE0
// FUNCTION: fn_21246

View file

@ -5225,7 +5225,7 @@ void CGameMode::RequestLocalMapMove(const char* mapName, std::uint16_t x, std::u
strcpy_s(packet.mapName, sizeof(packet.mapName), mapName);
packet.x = x;
packet.y = y;
this->ReceiveNpcAckMapmove(reinterpret_cast<const unsigned char*>(&packet));
this->ReceiveMapMove(reinterpret_cast<const unsigned char*>(&packet));
}
#pragma pack(push, 1)

View file

@ -2511,7 +2511,7 @@ __declspec(noinline) void CGameMode::ReceiveLapineBoxIngredient(const unsigned c
return;
}
if (UIWindow* window = g_windowMgr.sub_A978D0(0x122)) {
if (UIWindow* window = g_windowMgr.EnsureWindow(0x122)) {
static_cast<UILapineBoxWnd*>(window)->SetIngredient(static_cast<int>(reinterpret_cast<std::intptr_t>(packet)));
}
}
@ -7502,12 +7502,6 @@ struct MiniMapEffectMarkerPacket {
};
#pragma pack(pop)
struct MiniMapEffectMarker {
/* 0000 */ int unknown_0000;
/* 0004 */ int x;
/* 0008 */ int y;
};
// GLOBAL: gl_25132
std::map<int, MiniMapEffectMarker> g_miniMapEffectMarkers;
@ -7519,7 +7513,7 @@ __declspec(noinline) void CGameMode::AddMiniMapEffectMarker(const unsigned char*
if (found != g_miniMapEffectMarkers.end()) {
found->second.x = marker->x;
found->second.y = marker->y;
found->second.unknown_0000 = 0x78;
found->second.count = 0x78;
return;
}
@ -20100,7 +20094,7 @@ void CGameMode::HandleCameraInfo(const unsigned char* data) {
if (packet->action == 1) {
UIWindow* window = g_windowMgr.LookupWindow(289);
if (window == nullptr) {
window = g_windowMgr.sub_A978D0(289);
window = g_windowMgr.EnsureWindow(289);
}
g_session.unknown_61B1 = g_session.unknown_61B1 == 0;
g_windowMgr.SendNotice(3, 0, 0, 0, 0, 0);
@ -21739,7 +21733,7 @@ void CGameMode::sub_D08910() {
break;
}
case 0xA5: {
g_windowMgr.sub_A978D0(33);
g_windowMgr.EnsureWindow(33);
const int count = static_cast<unsigned int>(*reinterpret_cast<const std::int16_t *>(g_gameModePacketBuffer + 2) - 4) / sizeof(NormalItemRecord);
const NormalItemRecord *record = reinterpret_cast<const NormalItemRecord *>(g_gameModePacketBuffer + 4);
for (int i = 0; i < count; ++i, ++record) {
@ -21760,7 +21754,7 @@ void CGameMode::sub_D08910() {
break;
}
case 0xA6: {
g_windowMgr.sub_A978D0(33);
g_windowMgr.EnsureWindow(33);
const int count = static_cast<unsigned int>(*reinterpret_cast<const std::int16_t *>(g_gameModePacketBuffer + 2) - 4) / sizeof(EquipItemRecord);
const EquipItemRecord *record = reinterpret_cast<const EquipItemRecord *>(g_gameModePacketBuffer + 4);
for (int i = 0; i < count; ++i, ++record) {
@ -21864,7 +21858,7 @@ void CGameMode::sub_D08910() {
this->unknown_024C = 1;
this->unknown_02DC = *reinterpret_cast<const int *>(packet + 4);
unsigned int length = *reinterpret_cast<const std::uint16_t *>(packet + 2) - 8;
UIWindow *window = g_windowMgr.sub_A978D0(16);
UIWindow *window = g_windowMgr.EnsureWindow(16);
char text[0x803];
if (g_serviceType == 10) {
sprintf(text, "|%02x", LanguageCharset(31));
@ -21880,7 +21874,7 @@ void CGameMode::sub_D08910() {
case 0xB5:
this->unknown_024C = 1;
this->unknown_02DC = *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2);
g_windowMgr.sub_A978D0(16)->SendMsg(nullptr, 25, 0, 0, 0, 0);
g_windowMgr.EnsureWindow(16)->SendMsg(nullptr, 25, 0, 0, 0, 0);
break;
case 0xC0: {
const std::uint32_t aid = *reinterpret_cast<const std::uint32_t *>(g_gameModePacketBuffer + 2);
@ -21910,7 +21904,7 @@ void CGameMode::sub_D08910() {
}
case 0xC4:
this->unknown_024C = 1;
g_windowMgr.sub_A978D0(25)->SendMsg(nullptr, 28, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2), 0, 0, 0);
g_windowMgr.EnsureWindow(25)->SendMsg(nullptr, 28, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2), 0, 0, 0);
g_windowMgr.CloseWindow(22);
g_windowMgr.CloseWindow(23);
g_windowMgr.CloseWindow(24);
@ -21931,10 +21925,10 @@ void CGameMode::sub_D08910() {
g_session.AddItem1718(item, 0);
}
UIWindow *buyWindow = g_windowMgr.sub_A978D0(22);
UIWindow *buyWindow = g_windowMgr.EnsureWindow(22);
buyWindow->SendMsg(nullptr, 36, 0, 0, 0, 0);
buyWindow->SendMsg(nullptr, 23, 0, 0, 0, 0);
UIWindow *sellWindow = g_windowMgr.sub_A978D0(23);
UIWindow *sellWindow = g_windowMgr.EnsureWindow(23);
sellWindow->SendMsg(nullptr, 36, 0, 0, 0, 0);
sellWindow->SendMsg(nullptr, 23, 0, 0, 0, 0);
break;
@ -22008,7 +22002,7 @@ void CGameMode::sub_D08910() {
case 0: {
g_windowMgr.SendNotice(3, 0, 0, 0, 0, 0);
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(LookupMessage(64)), 0xFFFF00, 0, 0, 0);
UIWindow *window = g_windowMgr.sub_A978D0(28);
UIWindow *window = g_windowMgr.EnsureWindow(28);
this->unknown_03FC = 1;
window->SendMsg(nullptr, 34, reinterpret_cast<std::intptr_t>(&this->unknown_03C8), 0, 0, 0);
window->SendMsg(nullptr, 43, 0, 0, 0, 0);
@ -22041,7 +22035,7 @@ void CGameMode::sub_D08910() {
std::memcpy(name, g_gameModePacketBuffer + 4, 24);
name[24] = '\0';
g_session.DecodePlayerName();
UIChatRoomWnd *window = static_cast<UIChatRoomWnd *>(g_windowMgr.sub_A978D0(28));
UIChatRoomWnd *window = static_cast<UIChatRoomWnd *>(g_windowMgr.EnsureWindow(28));
ChatRoomMemberUpdateInfo info{window->title, window->unknown_00CC, window->roomStatus.roomType, window->roomStatus.memberCount,
window->roomStatus.memberLimit, window->roomStatus.roomId};
info.memberCount = *reinterpret_cast<const std::int16_t *>(g_gameModePacketBuffer + 2);
@ -22062,7 +22056,7 @@ void CGameMode::sub_D08910() {
break;
}
UIChatRoomWnd *window = static_cast<UIChatRoomWnd *>(g_windowMgr.sub_A978D0(28));
UIChatRoomWnd *window = static_cast<UIChatRoomWnd *>(g_windowMgr.EnsureWindow(28));
ChatRoomMemberUpdateInfo info{window->title, window->unknown_00CC, window->roomStatus.roomType, window->roomStatus.memberCount,
window->roomStatus.memberLimit, window->roomStatus.roomId};
info.memberCount = *reinterpret_cast<const std::int16_t *>(g_gameModePacketBuffer + 2);
@ -22082,7 +22076,7 @@ void CGameMode::sub_D08910() {
break;
}
case 0xE1: {
UIWindow *window = g_windowMgr.sub_A978D0(28);
UIWindow *window = g_windowMgr.EnsureWindow(28);
char name[25];
std::memcpy(name, g_gameModePacketBuffer + 6, 24);
name[24] = '\0';
@ -22098,7 +22092,7 @@ void CGameMode::sub_D08910() {
char name[25];
std::memcpy(name, g_gameModePacketBuffer + 2, 24);
name[24] = '\0';
g_windowMgr.sub_A978D0(32)->SendMsg(nullptr, 50, reinterpret_cast<std::intptr_t>(name), 0, 0, 0);
g_windowMgr.EnsureWindow(32)->SendMsg(nullptr, 50, reinterpret_cast<std::intptr_t>(name), 0, 0, 0);
this->exchangeName.assign(name, strlen(name));
break;
}
@ -22144,7 +22138,7 @@ void CGameMode::sub_D08910() {
g_session.ResetSlots();
break;
case 0xF2:
g_windowMgr.sub_A978D0(33)->SendMsg(nullptr, 55, *reinterpret_cast<const std::int16_t *>(g_gameModePacketBuffer + 2),
g_windowMgr.EnsureWindow(33)->SendMsg(nullptr, 55, *reinterpret_cast<const std::int16_t *>(g_gameModePacketBuffer + 2),
*reinterpret_cast<const std::int16_t *>(g_gameModePacketBuffer + 4), 0, 0);
break;
case 0xF6: {
@ -22164,7 +22158,7 @@ void CGameMode::sub_D08910() {
switch (g_gameModePacketBuffer[2]) {
case 0:
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(LookupMessage(77)), 0xFFFF00, 0, 0, 0);
g_windowMgr.sub_A978D0(34);
g_windowMgr.EnsureWindow(34);
break;
case 1:
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(LookupMessage(78)), 0xFF, 0, 0, 0);
@ -22187,7 +22181,7 @@ void CGameMode::sub_D08910() {
g_forbiddenWords.Mask(name, &masked);
}
g_session.unknown_54C4.assign(name, strlen(name));
g_windowMgr.sub_A978D0(35)->SendMsg(nullptr, 56, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2), reinterpret_cast<std::intptr_t>(name), 0, 0);
g_windowMgr.EnsureWindow(35)->SendMsg(nullptr, 56, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2), reinterpret_cast<std::intptr_t>(name), 0, 0);
break;
}
case 0x101: {
@ -22332,7 +22326,7 @@ void CGameMode::sub_D08910() {
}
case 0x11C: {
g_windowMgr.CloseWindow(39);
UIWindow *window = g_windowMgr.sub_A978D0(39);
UIWindow *window = g_windowMgr.EnsureWindow(39);
window->SendMsg(nullptr, 59, *reinterpret_cast<const std::uint16_t *>(g_gameModePacketBuffer + 2), 0, 0, 0);
const char *name = reinterpret_cast<const char *>(g_gameModePacketBuffer + 4);
for (unsigned int i = 0; i < 4; ++i, name += 16) {
@ -22482,7 +22476,7 @@ void CGameMode::sub_D08910() {
if (g_windowMgr.window_027C || g_windowMgr.window_0274) {
g_windowMgr.Confirm(LookupMessage(587), 0, true, false, 0, "Message", 280, 120, 0);
this->SendMsg(81, 0, 0, 0, 0);
} else if (UIMerchantShopMakeWnd *window = static_cast<UIMerchantShopMakeWnd *>(g_windowMgr.sub_A978D0(41))) {
} else if (UIMerchantShopMakeWnd *window = static_cast<UIMerchantShopMakeWnd *>(g_windowMgr.EnsureWindow(41))) {
window->AddActionButton();
}
break;
@ -22546,7 +22540,7 @@ void CGameMode::sub_D08910() {
case 0x142: {
const std::uint32_t aid = *reinterpret_cast<const std::uint32_t *>(g_gameModePacketBuffer + 2);
if (this->scene->GetGameActorByAID(aid)) {
g_windowMgr.sub_A978D0(56)->SendMsg(nullptr, 28, aid, 0, 0, 0);
g_windowMgr.EnsureWindow(56)->SendMsg(nullptr, 28, aid, 0, 0, 0);
}
break;
}
@ -22741,7 +22735,7 @@ void CGameMode::sub_D08910() {
std::string masked("");
g_forbiddenWords.Mask(name, &masked);
}
g_windowMgr.sub_A978D0(70)->SendMsg(nullptr, 73, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2), reinterpret_cast<std::intptr_t>(name), 0, 0);
g_windowMgr.EnsureWindow(70)->SendMsg(nullptr, 73, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2), reinterpret_cast<std::intptr_t>(name), 0, 0);
break;
}
case 0x16C: {
@ -22784,7 +22778,7 @@ void CGameMode::sub_D08910() {
std::string masked("");
g_forbiddenWords.Mask(name, &masked);
}
g_windowMgr.sub_A978D0(72)->SendMsg(nullptr, 74, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2), reinterpret_cast<std::intptr_t>(name), 0, 0);
g_windowMgr.EnsureWindow(72)->SendMsg(nullptr, 74, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2), reinterpret_cast<std::intptr_t>(name), 0, 0);
break;
}
case 0x173:
@ -22811,7 +22805,7 @@ void CGameMode::sub_D08910() {
break;
case 0x177: {
unsigned int count = (*reinterpret_cast<const std::uint16_t *>(g_gameModePacketBuffer + 2) - 4u) >> 1;
UIWindow *window = g_windowMgr.sub_A978D0(73);
UIWindow *window = g_windowMgr.EnsureWindow(73);
window->SendMsg(nullptr, 75, 0, 0, 0, 0);
const std::int16_t *index = reinterpret_cast<const std::int16_t *>(g_gameModePacketBuffer + 4);
for (; count != 0; --count, ++index) {
@ -22839,7 +22833,7 @@ void CGameMode::sub_D08910() {
break;
case 0x17B: {
unsigned int count = (*reinterpret_cast<const std::uint16_t *>(g_gameModePacketBuffer + 2) - 4u) >> 1;
UIWindow *window = g_windowMgr.sub_A978D0(74);
UIWindow *window = g_windowMgr.EnsureWindow(74);
window->SendMsg(nullptr, 75, 0, 0, 0, 0);
window->SendMsg(nullptr, 77, *reinterpret_cast<const int *>(this->unknown_045C), 0, 0, 0);
const std::int16_t *index = reinterpret_cast<const std::int16_t *>(g_gameModePacketBuffer + 4);
@ -22908,7 +22902,7 @@ void CGameMode::sub_D08910() {
case 0x18C: {
const std::uint16_t id = *reinterpret_cast<const std::uint16_t *>(g_gameModePacketBuffer + 2);
if (id != 1285 && id != 1286 && id != 1287 && id != 1829 && id != 1830) {
g_windowMgr.sub_A978D0(77)->SendMsg(nullptr, 79, reinterpret_cast<std::intptr_t>(g_gameModePacketBuffer), 0, 0, 0);
g_windowMgr.EnsureWindow(77)->SendMsg(nullptr, 79, reinterpret_cast<std::intptr_t>(g_gameModePacketBuffer), 0, 0, 0);
}
break;
}
@ -22919,7 +22913,7 @@ void CGameMode::sub_D08910() {
break;
}
g_windowMgr.CloseWindow(79);
UIWindow *window = g_windowMgr.sub_A978D0(79);
UIWindow *window = g_windowMgr.EnsureWindow(79);
const int *record = reinterpret_cast<const int *>(g_gameModePacketBuffer + 4);
for (; count != 0; --count, record += 4) {
window->SendMsg(nullptr, 31, *record, 0, 0, 0);
@ -22975,7 +22969,7 @@ void CGameMode::sub_D08910() {
std::int16_t &value = *reinterpret_cast<std::int16_t *>(packet + 0x1B);
if (value >= 10000) {
value -= 10000;
if (UIItemCollectionWnd *window = static_cast<UIItemCollectionWnd *>(g_windowMgr.sub_A978D0(12))) {
if (UIItemCollectionWnd *window = static_cast<UIItemCollectionWnd *>(g_windowMgr.EnsureWindow(12))) {
window->unknown_0218 = value;
window->unknown_021A = *reinterpret_cast<const std::int16_t *>(packet + 0x1D);
window->unknown_021C = *reinterpret_cast<const std::int16_t *>(packet + 0x1F);
@ -23003,7 +22997,7 @@ void CGameMode::sub_D08910() {
}
case 0x1A6: {
const int count = static_cast<unsigned int>(*reinterpret_cast<const std::int16_t *>(g_gameModePacketBuffer + 2) - 4) >> 1;
UIWindow *window = g_windowMgr.sub_A978D0(90);
UIWindow *window = g_windowMgr.EnsureWindow(90);
window->SendMsg(nullptr, 75, 0, 0, 0, 0);
const std::int16_t *index = reinterpret_cast<const std::int16_t *>(g_gameModePacketBuffer + 4);
for (int i = 0; i < count; ++i, ++index) {
@ -23039,7 +23033,7 @@ void CGameMode::sub_D08910() {
break;
case 0x1AD: {
const unsigned int count = static_cast<unsigned int>(*reinterpret_cast<const std::uint16_t *>(g_gameModePacketBuffer + 2) - 4) >> 2;
UIWindow *window = g_windowMgr.sub_A978D0(94);
UIWindow *window = g_windowMgr.EnsureWindow(94);
window->SendMsg(nullptr, 75, 0, 0, 0, 0);
const unsigned char *entry = g_gameModePacketBuffer + 4;
for (unsigned int i = count; i != 0; --i, entry += 4) {
@ -23165,7 +23159,7 @@ void CGameMode::sub_D08910() {
if (count <= 0) {
break;
}
if (UIWindow *window = g_windowMgr.sub_A978D0(99)) {
if (UIWindow *window = g_windowMgr.EnsureWindow(99)) {
for (const int *skill = reinterpret_cast<const int *>(g_gameModePacketBuffer + 2); skill < reinterpret_cast<const int *>(g_gameModePacketBuffer + 0x1E);
++skill) {
if (*skill) {
@ -23182,7 +23176,7 @@ void CGameMode::sub_D08910() {
case 0x1D4:
if (this->scene->GetGameActorByAID(*reinterpret_cast<const std::uint32_t *>(g_gameModePacketBuffer + 2)) ||
*reinterpret_cast<const std::uint32_t *>(g_gameModePacketBuffer + 2) == 0) {
g_windowMgr.sub_A978D0(100)->SendMsg(nullptr, 28, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2), 0, 0, 0);
g_windowMgr.EnsureWindow(100)->SendMsg(nullptr, 28, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2), 0, 0, 0);
}
break;
case 0x1D6: {
@ -23233,7 +23227,7 @@ void CGameMode::sub_D08910() {
name[24] = 0;
*reinterpret_cast<int *>(this->unknown_028C) = *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2);
*reinterpret_cast<int *>(this->unknown_028C + 4) = *reinterpret_cast<const int *>(g_gameModePacketBuffer + 6);
g_windowMgr.sub_A978D0(104)->SendMsg(nullptr, 90, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 6), reinterpret_cast<std::intptr_t>(name), 0,
g_windowMgr.EnsureWindow(104)->SendMsg(nullptr, 90, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 6), reinterpret_cast<std::intptr_t>(name), 0,
0);
break;
}
@ -23301,7 +23295,7 @@ void CGameMode::sub_D08910() {
break;
}
case 0x1F0: {
g_windowMgr.sub_A978D0(33);
g_windowMgr.EnsureWindow(33);
const int count = static_cast<unsigned int>(*reinterpret_cast<const std::int16_t *>(g_gameModePacketBuffer + 2) - 4) / sizeof(CardItemRecord);
const CardItemRecord *record = reinterpret_cast<const CardItemRecord *>(g_gameModePacketBuffer + 4);
for (int i = 0; i < count; ++i, ++record) {
@ -23346,7 +23340,7 @@ void CGameMode::sub_D08910() {
char name[25];
std::memcpy(name, g_gameModePacketBuffer + 2, 24);
name[24] = '\0';
g_windowMgr.sub_A978D0(32)->SendMsg(nullptr, 50, reinterpret_cast<std::intptr_t>(name), *reinterpret_cast<const int *>(g_gameModePacketBuffer + 0x1A),
g_windowMgr.EnsureWindow(32)->SendMsg(nullptr, 50, reinterpret_cast<std::intptr_t>(name), *reinterpret_cast<const int *>(g_gameModePacketBuffer + 0x1A),
*reinterpret_cast<const std::int16_t *>(g_gameModePacketBuffer + 0x1E), 0);
this->exchangeName.assign(name, strlen(name));
break;
@ -23357,7 +23351,7 @@ void CGameMode::sub_D08910() {
name[24] = 0;
*reinterpret_cast<int *>(this->unknown_028C) = *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2);
*reinterpret_cast<int *>(this->unknown_028C + 4) = *reinterpret_cast<const int *>(g_gameModePacketBuffer + 6);
g_windowMgr.sub_A978D0(105)->SendMsg(nullptr, 91, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 6), reinterpret_cast<std::intptr_t>(name), 0,
g_windowMgr.EnsureWindow(105)->SendMsg(nullptr, 91, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 6), reinterpret_cast<std::intptr_t>(name), 0,
0);
break;
}
@ -23368,7 +23362,7 @@ void CGameMode::sub_D08910() {
break;
}
g_windowMgr.CloseWindow(107);
UIWindow *window = g_windowMgr.sub_A978D0(107);
UIWindow *window = g_windowMgr.EnsureWindow(107);
const unsigned char *record = g_gameModePacketBuffer + 4;
for (int i = 0; i < count; ++i, record += 23) {
window->SendMsg(nullptr, 31, reinterpret_cast<std::intptr_t>(record), 0, 0, 0);
@ -23427,7 +23421,7 @@ void CGameMode::sub_D08910() {
g_modeMgr.gameMode->SendMsg(175, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2), *reinterpret_cast<const int *>(g_gameModePacketBuffer + 6),
0, 0);
} else {
g_windowMgr.sub_A978D0(109)->SendMsg(nullptr, 95, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2),
g_windowMgr.EnsureWindow(109)->SendMsg(nullptr, 95, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2),
*reinterpret_cast<const int *>(g_gameModePacketBuffer + 6), reinterpret_cast<std::intptr_t>(name), 0);
}
break;
@ -23462,7 +23456,7 @@ void CGameMode::sub_D08910() {
if (g_windowMgr.LookupWindow(111)) {
g_windowMgr.CloseWindow(111);
}
UIWindow *window = g_windowMgr.sub_A978D0(111);
UIWindow *window = g_windowMgr.EnsureWindow(111);
const unsigned char *record = g_gameModePacketBuffer + 4;
for (int i = 0; i < count; ++i, record += 23) {
window->SendMsg(nullptr, 31, *reinterpret_cast<const int *>(record + 2), *reinterpret_cast<const std::int16_t *>(record), 0, 0);
@ -23499,11 +23493,11 @@ void CGameMode::sub_D08910() {
break;
}
case 0x253:
g_windowMgr.sub_A978D0(119)->SendMsg(nullptr, 91, static_cast<signed char>(g_gameModePacketBuffer[2]), 0, 0, 0);
g_windowMgr.EnsureWindow(119)->SendMsg(nullptr, 91, static_cast<signed char>(g_gameModePacketBuffer[2]), 0, 0, 0);
break;
case 0x25A: {
const unsigned int count = static_cast<unsigned int>(*reinterpret_cast<const std::uint16_t *>(g_gameModePacketBuffer + 2) - 6) >> 2;
UIWindow *window = g_windowMgr.sub_A978D0(94);
UIWindow *window = g_windowMgr.EnsureWindow(94);
if (!window) {
break;
}
@ -23632,7 +23626,7 @@ void CGameMode::sub_D08910() {
break;
}
case 0x2EA: {
g_windowMgr.sub_A978D0(33);
g_windowMgr.EnsureWindow(33);
const int count = static_cast<unsigned int>(*reinterpret_cast<const std::int16_t *>(g_gameModePacketBuffer + 2) - 4) / sizeof(CardItemExpiryRecord);
const CardItemExpiryRecord *entry = reinterpret_cast<const CardItemExpiryRecord *>(g_gameModePacketBuffer + 4);
for (int i = 0; i < count; ++i, ++entry) {
@ -23703,7 +23697,7 @@ void CGameMode::sub_D08910() {
if (count == 0) {
break;
}
if (UIWindow *window = g_windowMgr.sub_A978D0(99)) {
if (UIWindow *window = g_windowMgr.EnsureWindow(99)) {
window->SendMsg(nullptr, 27, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 4), 0, 0, 0);
const std::uint16_t *skills = reinterpret_cast<const std::uint16_t *>(g_gameModePacketBuffer + 8);
for (int i = 0; i < count; ++i) {
@ -24159,7 +24153,7 @@ void CGameMode::sub_D08910() {
case 0x845:
case 0xA2B:
if (!g_windowMgr.CloseWindow(318)) {
if (UIWindow *window = g_windowMgr.sub_A978D0(318)) {
if (UIWindow *window = g_windowMgr.EnsureWindow(318)) {
window->SendMsg(nullptr, 120, *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2), *reinterpret_cast<const int *>(g_gameModePacketBuffer + 6),
0, 0);
} else {
@ -24389,7 +24383,7 @@ void CGameMode::sub_D08910() {
this->ReceiveFeedConfig(g_gameModePacketBuffer[0x2], g_gameModePacketBuffer[0x3]);
break;
case 0xAA0:
g_windowMgr.sub_A978D0(295);
g_windowMgr.EnsureWindow(295);
break;
case 0xAB4:
this->ReceiveLapineUpgradeBoxValue(*reinterpret_cast<const int *>(g_gameModePacketBuffer + 0x2));
@ -24698,7 +24692,7 @@ void CGameMode::sub_D08910() {
case 0x973:
this->unknown_024C = 1;
this->unknown_02DC = *reinterpret_cast<const int *>(g_gameModePacketBuffer + 2);
g_windowMgr.sub_A978D0(226)->SendMsg(nullptr, 25, 0, 0, 0, 0);
g_windowMgr.EnsureWindow(226)->SendMsg(nullptr, 25, 0, 0, 0, 0);
break;
case 0xBEE:
switch (g_gameModePacketBuffer[4]) {
@ -24881,7 +24875,7 @@ void CGameMode::sub_D08910() {
memcpy(text, packet + 9, length);
}
text[length] = 0;
g_windowMgr.sub_A978D0(226)->SendMsg(nullptr, 26, reinterpret_cast<std::intptr_t>(text), *reinterpret_cast<const int *>(packet + 4), 0, 0);
g_windowMgr.EnsureWindow(226)->SendMsg(nullptr, 26, reinterpret_cast<std::intptr_t>(text), *reinterpret_cast<const int *>(packet + 4), 0, 0);
break;
}
case 0xBF6: {
@ -24936,7 +24930,7 @@ void CGameMode::sub_D08910() {
if (g_gameModePacketBuffer[2] == 1) {
UIWindow *window = g_windowMgr.LookupWindow(289);
if (!window) {
window = g_windowMgr.sub_A978D0(289);
window = g_windowMgr.EnsureWindow(289);
}
g_session.unknown_61B1 = !g_session.unknown_61B1;
g_windowMgr.SendNotice(3, 0, 0, 0, 0, 0);
@ -24977,10 +24971,10 @@ void CGameMode::sub_D08910() {
case 0xA28:
switch (g_gameModePacketBuffer[2]) {
case 0:
if (UIWindow *window = g_windowMgr.sub_A978D0(45)) {
if (UIWindow *window = g_windowMgr.EnsureWindow(45)) {
window->SendMsg(nullptr, 23, 0, 0, 0, 0);
}
if (UIMerchantShopMakeWnd *window = static_cast<UIMerchantShopMakeWnd *>(g_windowMgr.sub_A978D0(41))) {
if (UIMerchantShopMakeWnd *window = static_cast<UIMerchantShopMakeWnd *>(g_windowMgr.EnsureWindow(41))) {
window->PrintSellList();
}
g_windowMgr.CloseWindow(41);
@ -25088,7 +25082,7 @@ void CGameMode::sub_D08910() {
break;
}
case 0x904: {
g_windowMgr.sub_A978D0(33);
g_windowMgr.EnsureWindow(33);
const int count = static_cast<unsigned int>(*reinterpret_cast<const std::int16_t *>(g_gameModePacketBuffer + 2) - 4) / sizeof(FlaggedItemRecord);
for (int i = 0; i < count; ++i) {
const FlaggedItemRecord *record = reinterpret_cast<const FlaggedItemRecord *>(g_gameModePacketBuffer + 4) + i;
@ -25139,7 +25133,7 @@ void CGameMode::sub_D08910() {
break;
}
case 0x905: {
g_windowMgr.sub_A978D0(33);
g_windowMgr.EnsureWindow(33);
const int count = static_cast<unsigned int>(*reinterpret_cast<const std::int16_t *>(g_gameModePacketBuffer + 2) - 4) / sizeof(FlaggedEquipRecord);
for (int i = 0; i < count; ++i) {
const FlaggedEquipRecord *record = reinterpret_cast<const FlaggedEquipRecord *>(g_gameModePacketBuffer + 4) + i;
@ -25229,8 +25223,8 @@ void CGameMode::sub_D08910() {
item.id = *reinterpret_cast<const int *>(record + 0x15);
g_barterMarketItemMgr->items.push_back(item);
}
g_windowMgr.sub_A978D0(334)->SendMsg(nullptr, 23, 0, 0, 0, 0);
g_windowMgr.sub_A978D0(335)->SendMsg(nullptr, 23, 0, 0, 0, 0);
g_windowMgr.EnsureWindow(334)->SendMsg(nullptr, 23, 0, 0, 0, 0);
g_windowMgr.EnsureWindow(335)->SendMsg(nullptr, 23, 0, 0, 0, 0);
break;
}
case 0x9D5: {
@ -25250,10 +25244,10 @@ void CGameMode::sub_D08910() {
g_session.AddItem1718(item, *reinterpret_cast<const int *>(entry + 9),
static_cast<std::uint16_t>(*reinterpret_cast<const std::uint16_t *>(entry + 0xD) / 10));
}
UIWindow *window = g_windowMgr.sub_A978D0(254);
UIWindow *window = g_windowMgr.EnsureWindow(254);
window->SendMsg(nullptr, 36, 0, 0, 0, 0);
window->SendMsg(nullptr, 23, 0, 0, 0, 0);
window = g_windowMgr.sub_A978D0(255);
window = g_windowMgr.EnsureWindow(255);
window->SendMsg(nullptr, 36, 0, 0, 0, 0);
window->SendMsg(nullptr, 23, 0, 0, 0, 0);
break;

View file

@ -1,4 +1,5 @@
#include "Client/Mode/CLoginMode.h"
#include "Utility/EncryptedName.h"
#include "Client/Mode/CGameMode.h"
#include "Client/Application/ApplicationMessages.h"
#include "Client/Application/ApplicationWindow.h"
@ -11,6 +12,7 @@
#include "Client/Mode/ModeMgr.h"
#include "Client/Session.h"
#include "Client/Replay.h"
#include "Client/Timer.h"
#include "Client/Input/InputCharset.h"
#include "Client/Stove/StovePCSDK.h"
#include "Contents/Async/AsyncWorkMgr.h"
@ -90,7 +92,6 @@
#include <random>
#include <timeapi.h>
void sub_D8C390(const int* first, const int* last);
void TraceSelection(int selection);
void TraceSelectionRange(int first, int last);
@ -335,8 +336,6 @@ int g_restoreSurfaces;
// GLOBAL: gl_25384
int g_isAppActive;
int sub_C7F5A0();
static_assert(sizeof(CharacterSlotsPacket) == 0x1D);
static_assert(offsetof(AcceptLoginPacket, body) == 0x2F);
static_assert(sizeof(ServerAddress) == 0x20);
@ -346,37 +345,6 @@ static_assert(offsetof(CharacterSlotCountsPacket, extension) == 0xA);
static_assert(sizeof(BlockedCharacter) == 0x18);
static_assert(offsetof(AcceptEnterPacket, characters) == 0x1B);
template <std::size_t Length, std::uint64_t Key>
class EncryptedName {
public:
// INLINED
template <typename Byte>
explicit EncryptedName(const Byte (&source)[Length]) : m_encrypted(true) {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = source[index];
}
}
~EncryptedName() {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = 0;
}
}
const char* Text() {
if (this->m_encrypted) {
utility::XorBytes(this->m_text, Length, Key);
this->m_encrypted = false;
}
return reinterpret_cast<const char*>(this->m_text);
}
private:
/* 0000 */ std::uint8_t m_text[Length];
bool m_encrypted;
};
// INLINED
template <std::uint64_t Key, std::size_t Length>
const char* DecryptName(const char (&source)[Length]) {
@ -1028,7 +996,7 @@ void CLoginMode::Slot5(int value) {
return;
}
if (sub_C7F5A0()) {
if (ShouldRenderFrame()) {
g_renderer->ClearDepth(1);
g_windowMgr.UpdateFrameWindows();
if (g_serviceType == 0 || g_serviceType == 4 || g_serviceType == 8 || g_serviceType == 9 || g_serviceType == 3 || g_serviceType == 10 ||
@ -1178,7 +1146,7 @@ void CLoginMode::Update() {
return;
}
if (sub_C7F5A0()) {
if (ShouldRenderFrame()) {
g_renderer->ClearDepth(1);
g_windowMgr.UpdateFrameWindows();
if (g_serviceType == 0 || g_serviceType == 4 || g_serviceType == 8 || g_serviceType == 9 || g_serviceType == 3 || g_serviceType == 10 ||
@ -1213,7 +1181,7 @@ void CLoginMode::SubD97F00(int) {
// OFFSET: 0x00D97F10
// FUNCTION: fn_22308
void OpenAccountRegistration() {
void CLoginMode::OpenAccountRegistration() {
switch (g_serviceType) {
case 0:
if (*reinterpret_cast<const int*>(&g_session.unknown_59DC[0x198]) == 1) {
@ -3348,7 +3316,6 @@ int CLoginMode::SendMsg(int event, int argument1, int argument2, int argument3,
return 0;
case 10022:
this->unknown_6F4C = argument1;
sub_D8C390(this->unknown_6F38.data(), this->unknown_6F38.data() + this->unknown_6F38.size());
this->unknown_6F38.clear();
TraceSelectionRange(this->unknown_6F48, this->unknown_6F4C);
this->pendingCursorType = 3;

View file

@ -1,4 +1,5 @@
#include "Client/Session.h"
#include "Utility/EncryptedName.h"
#include "Client/Mode/CGameMode.h"
#include "Contents/Actors/RenderObject.h"
#include "Contents/Effects/EffectActor.h"
@ -2740,35 +2741,6 @@ void CSession::LoadMiniPartyInfo() {
delete[] data;
}
template <std::size_t Length, std::uint64_t Key>
class EncryptedName {
public:
explicit EncryptedName(const std::uint8_t (&source)[Length]) : m_encrypted(true) {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = source[index];
}
}
~EncryptedName() {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = 0;
}
}
const char* Text() {
if (this->m_encrypted) {
utility::XorBytes(this->m_text, Length, Key);
this->m_encrypted = false;
}
return reinterpret_cast<const char*>(this->m_text);
}
private:
/* 0000 */ std::uint8_t m_text[Length];
bool m_encrypted;
};
// OFFSET: 0x00DFD060
// FUNCTION: fn_23603
void CSession::LoadExternalSettings() {

View file

@ -713,7 +713,6 @@ public:
int GetMapProperty13() const;
bool HasUnknown6178Records() const;
bool HasUnknown6178Record(int id) const;
bool sub_E06580(int id);
int IsBerserkActive() const;
int IsTrickDeadActive() const;
int HasActiveSkillEffect(int id) const;
@ -900,7 +899,6 @@ public:
int SkillLevel(int id) const;
CRenderObject* FindGameActor(std::uint32_t aid) const;
int GetPetTargetAid() const;
bool sub_E1DE30(std::uint32_t aid);
int sub_DDD2C0(const ITEM_INFO& item);
const char* GetJobName(unsigned job, int sex);
void InitJobNameTable();

View file

@ -1,4 +1,5 @@
#include "Client/Application/ApplicationWindow.h"
#include "Utility/EncryptedName.h"
#include "Client/Application/Launcher.h"
#include "Client/Mode/CGameMode.h"
#include "Client/Mode/CMode.h"
@ -26,14 +27,14 @@
// GLOBAL: gl_24904
bool g_stoveWaitingCallback;
void sub_63A7F0(Stove::PCSDK::CallbackResult callbackResult);
void sub_63A8D0(Stove::PCSDK::CallbackResult callbackResult);
void sub_63A860(Stove::PCSDK::CallbackResult callbackResult);
void OnStoveTermsAgreementFetched(Stove::PCSDK::CallbackResult callbackResult, int unused, const wchar_t* url);
void OnStoveCategoryProductsFetched(Stove::PCSDK::CallbackResult callbackResult, const Stove::PCSDK::IAP::StovePCProduct* products, unsigned int count);
void OnStoveAllProductsFetched(Stove::PCSDK::CallbackResult callbackResult, const Stove::PCSDK::IAP::StovePCProduct* products, unsigned int count);
void sub_DD8A20(int value);
void sub_63A780(Stove::PCSDK::CallbackResult callbackResult);
void sub_63AA50(Stove::PCSDK::CallbackResult callbackResult, Stove::PCSDK::Base::StovePCShutdown shutdown);
void sub_63A940(Stove::PCSDK::CallbackResult callbackResult, Stove::PCSDK::IAP::StovePCPurchaseResult purchaseResult);
void sub_63A9D0(Stove::PCSDK::CallbackResult callbackResult, bool purchased, int unknown1, unsigned int count, int unknown2, int unknown3);
void OnStoveInitialized(Stove::PCSDK::CallbackResult callbackResult);
void OnStoveShutdown(Stove::PCSDK::CallbackResult callbackResult, Stove::PCSDK::Base::StovePCShutdown shutdown);
void OnStovePurchaseStarted(Stove::PCSDK::CallbackResult callbackResult, Stove::PCSDK::IAP::StovePCPurchaseResult purchaseResult);
void OnStovePurchaseConfirmed(Stove::PCSDK::CallbackResult callbackResult, bool purchased, int unknown1, unsigned int count, int unknown2, int unknown3);
// STRING: st_01259
const wchar_t g_stoveCategoryIdA[] = L"44C71118750747D";
@ -49,7 +50,7 @@ void CStoveMgr::FetchAllProducts() {
allParam.SetCategoryId(L"");
allParam.SetPageNumber(1);
allParam.SetPageSize(0x7FFFFFFF);
IAP_FetchProducts(&allParam, sub_63A860);
IAP_FetchProducts(&allParam, OnStoveAllProductsFetched);
g_stoveWaitingCallback = true;
do {
Base_RunCallback();
@ -61,7 +62,7 @@ void CStoveMgr::FetchAllProducts() {
categoryParam.SetCategoryId(this->m_environment == 2 ? g_stoveCategoryIdA : g_stoveCategoryIdB);
categoryParam.SetPageNumber(1);
categoryParam.SetPageSize(0x7FFFFFFF);
IAP_FetchProducts(&categoryParam, sub_63A8D0);
IAP_FetchProducts(&categoryParam, OnStoveCategoryProductsFetched);
g_stoveWaitingCallback = true;
do {
Base_RunCallback();
@ -74,7 +75,7 @@ void CStoveMgr::FetchAllProducts() {
void FetchStoveTermsAgreement() {
Stove::PCSDK::IAP::StovePCTermsOption option;
option.SetOperation(Stove::PCSDK::IAP::StovePCPaymentOperation::DEFAULT);
IAP_FetchTermsAgreement(&option, sub_63A7F0);
IAP_FetchTermsAgreement(&option, OnStoveTermsAgreementFetched);
g_stoveWaitingCallback = true;
do {
Base_RunCallback();
@ -90,7 +91,7 @@ void CStoveMgr::FetchCategoryProducts() {
param.SetCategoryId(this->m_environment == 2 ? g_stoveCategoryIdA : g_stoveCategoryIdB);
param.SetPageNumber(1);
param.SetPageSize(0x7FFFFFFF);
IAP_FetchProducts(&param, sub_63A8D0);
IAP_FetchProducts(&param, OnStoveCategoryProductsFetched);
g_stoveWaitingCallback = true;
do {
Base_RunCallback();
@ -98,36 +99,6 @@ void CStoveMgr::FetchCategoryProducts() {
} while (g_stoveWaitingCallback);
}
template <std::size_t Length, std::uint64_t Key>
class EncryptedName {
public:
// INLINED
explicit EncryptedName(const char (&source)[Length]) : m_encrypted(true) {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = source[index];
}
}
~EncryptedName() {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = 0;
}
}
const char* Text() {
if (this->m_encrypted) {
utility::XorBytes(this->m_text, Length, Key);
this->m_encrypted = false;
}
return reinterpret_cast<const char*>(this->m_text);
}
private:
/* 0000 */ std::uint8_t m_text[Length];
bool m_encrypted;
};
// INLINED
template <std::uint64_t Key, std::size_t Length>
const char* DecryptName(const char (&source)[Length]) {
@ -151,6 +122,14 @@ struct PurchaseCheckingMessage {
EncryptedName<129, 0x2D3B15774149D5DDULL>& operator()() const;
};
struct InitializeCallback {
void operator()(Stove::PCSDK::CallbackResult callbackResult) const;
};
struct TermsAgreementCallback {
void operator()(Stove::PCSDK::CallbackResult callbackResult, int unused, const wchar_t* url) const;
};
struct FetchProductsCallback {
void operator()(Stove::PCSDK::CallbackResult callbackResult, const Stove::PCSDK::IAP::StovePCProduct* products, unsigned int count) const;
};
@ -171,6 +150,48 @@ struct ConfirmPurchaseCallback {
void operator()(Stove::PCSDK::CallbackResult callbackResult, bool purchased, int unknown1, unsigned int count, int unknown2, int unknown3) const;
};
// OFFSET: 0x0063A780
// FUNCTION: fn_04771
void OnStoveInitialized(Stove::PCSDK::CallbackResult callbackResult) {
InitializeCallback()(callbackResult);
}
// OFFSET: 0x0063A7F0
// FUNCTION: fn_04772
void OnStoveTermsAgreementFetched(Stove::PCSDK::CallbackResult callbackResult, int unused, const wchar_t* url) {
TermsAgreementCallback()(callbackResult, unused, url);
}
// OFFSET: 0x0063A860
// FUNCTION: fn_04773
void OnStoveAllProductsFetched(Stove::PCSDK::CallbackResult callbackResult, const Stove::PCSDK::IAP::StovePCProduct* products, unsigned int count) {
CategoryProductsCallback()(callbackResult, products, count);
}
// OFFSET: 0x0063A8D0
// FUNCTION: fn_04774
void OnStoveCategoryProductsFetched(Stove::PCSDK::CallbackResult callbackResult, const Stove::PCSDK::IAP::StovePCProduct* products, unsigned int count) {
FetchProductsCallback()(callbackResult, products, count);
}
// OFFSET: 0x0063A940
// FUNCTION: fn_04775
void OnStovePurchaseStarted(Stove::PCSDK::CallbackResult callbackResult, Stove::PCSDK::IAP::StovePCPurchaseResult purchaseResult) {
PurchaseResultCallback()(callbackResult, purchaseResult);
}
// OFFSET: 0x0063A9D0
// FUNCTION: fn_04776
void OnStovePurchaseConfirmed(Stove::PCSDK::CallbackResult callbackResult, bool purchased, int unknown1, unsigned int count, int unknown2, int unknown3) {
ConfirmPurchaseCallback()(callbackResult, purchased, unknown1, count, unknown2, unknown3);
}
// OFFSET: 0x0063AA50
// FUNCTION: fn_04777
void OnStoveShutdown(Stove::PCSDK::CallbackResult callbackResult, Stove::PCSDK::Base::StovePCShutdown shutdown) {
ShutdownCallback()(callbackResult, shutdown);
}
// OFFSET: 0x0063AAE0
// FUNCTION: fn_04778
@ -425,7 +446,7 @@ EncryptedName<100, 0x4F1791FB1503C713ULL>& TokenCallbackFailureMessage::operator
// OFFSET: 0x0063D260
// FUNCTION: fn_04789
void CStoveMgr::OnInitializeCallback(Stove::PCSDK::CallbackResult callbackResult) {
void InitializeCallback::operator()(Stove::PCSDK::CallbackResult callbackResult) const {
g_stoveWaitingCallback = false;
if (!callbackResult.GetResult().IsSuccessful()) {
const char captionSource[] = {'\xD5', '\x3D', '\xF8', '\x60', '\x2C', '\x37', '\xD7'};
@ -521,12 +542,12 @@ bool CStoveMgr::Initialize() {
return false;
}
Base_Initialize(&param, sub_63A780);
Base_Initialize(&param, OnStoveInitialized);
this->WaitForCallback();
Stove::PCSDK::Result result = IAP_Initialize(this->unknown_02B8.c_str());
if (result.IsSuccessful()) {
this->FetchUser();
Base_GetShutdown(sub_63AA50);
Base_GetShutdown(OnStoveShutdown);
this->m_initialized = true;
return true;
}
@ -592,7 +613,7 @@ void CStoveMgr::StartPurchase(const std::vector<ITEM_INFO>& items) {
Stove::PCSDK::IAP::StovePCPaymentOption option;
option.SetOperation(Stove::PCSDK::IAP::StovePCPaymentOperation::DEFAULT);
param.SetPurchaseOption(option);
IAP_StartPurchase(&param, sub_63A940);
IAP_StartPurchase(&param, OnStovePurchaseStarted);
g_stoveWaitingCallback = true;
do {
Base_RunCallback();
@ -613,7 +634,7 @@ void CStoveMgr::StartPurchase(const std::vector<ITEM_INFO>& items) {
const char* verb = DecryptName<0x9B17C9EFDBB39F2FULL>(verbSource);
ShellExecuteA(nullptr, verb, url, url, nullptr, SW_SHOWNORMAL);
if (g_windowMgr.Confirm(PurchaseCheckingMessage()().Text(), 2, true, false, 0, "Message", 250, 170, 0) == 187) {
IAP_ConfirmPurchase((static_cast<std::int64_t>(this->unknown_0014) << 32) | static_cast<std::uint32_t>(this->unknown_0010), sub_63A9D0);
IAP_ConfirmPurchase((static_cast<std::int64_t>(this->unknown_0014) << 32) | static_cast<std::uint32_t>(this->unknown_0010), OnStovePurchaseConfirmed);
g_stoveWaitingCallback = true;
do {
Base_RunCallback();
@ -635,7 +656,7 @@ void CStoveMgr::WaitForCallback() {
// OFFSET: 0x0063CD20
// FUNCTION: fn_04785
void CStoveMgr::OnOpenUrlCallback(Stove::PCSDK::CallbackResult callbackResult, int unused, const wchar_t* url) {
void TermsAgreementCallback::operator()(Stove::PCSDK::CallbackResult callbackResult, int unused, const wchar_t* url) const {
g_stoveWaitingCallback = false;
if (callbackResult.GetResult().IsSuccessful()) {
g_modeMgr.GetGameMode()->SendMsg(323, 0, 0, 0, 0);

View file

@ -7,9 +7,6 @@
struct ITEM_INFO;
namespace Stove::PCSDK {
struct CallbackResult;
}
// VTABLE: vt_00291
template <class T> class Singleton2 {
@ -40,8 +37,6 @@ public:
__declspec(noinline) void WaitForCallback();
void FetchCategoryProducts();
void FetchAllProducts();
void OnInitializeCallback(Stove::PCSDK::CallbackResult callbackResult);
void OnOpenUrlCallback(Stove::PCSDK::CallbackResult callbackResult, int unused, const wchar_t* url);
bool Initialize();
void StartPurchase(const std::vector<ITEM_INFO>& items);
};

View file

@ -156,8 +156,10 @@ Stove::PCSDK::Result IAP_UnInitialize();
Stove::PCSDK::Result Base_UnInitialize();
void IAP_StartPurchase(const Stove::PCSDK::IAP::StovePCStartPurchaseParam* param,
void (*callback)(Stove::PCSDK::CallbackResult, Stove::PCSDK::IAP::StovePCPurchaseResult));
void IAP_FetchTermsAgreement(Stove::PCSDK::IAP::StovePCTermsOption* option, void (*callback)(Stove::PCSDK::CallbackResult));
void IAP_FetchProducts(Stove::PCSDK::IAP::StovePCFetchProductParam* param, void (*callback)(Stove::PCSDK::CallbackResult));
void IAP_FetchTermsAgreement(Stove::PCSDK::IAP::StovePCTermsOption* option,
void (*callback)(Stove::PCSDK::CallbackResult, int, const wchar_t*));
void IAP_FetchProducts(Stove::PCSDK::IAP::StovePCFetchProductParam* param,
void (*callback)(Stove::PCSDK::CallbackResult, const Stove::PCSDK::IAP::StovePCProduct*, unsigned int));
void IAP_ConfirmPurchase(std::int64_t transactionNumber, void (*callback)(Stove::PCSDK::CallbackResult, bool, int, unsigned int, int, int));
}

View file

@ -37,3 +37,9 @@ void InitTimer(unsigned long freq) {
void ResetTimer() {
frameTime = timeGetTime();
}
// OFFSET: 0x00C7F5A0
// FUNCTION: fn_20434
int ShouldRenderFrame() {
return 1;
}

View file

@ -6,5 +6,6 @@ extern int g_frameskip;
void ResetTimer();
void InitTimer(unsigned long freq);
int GetSkipFrameCount();
int ShouldRenderFrame();
#endif

View file

@ -264,7 +264,6 @@ public:
__declspec(noinline) int WeaponActionBase(int weaponType);
int GetUnknown0404();
int MountHeightOffset();
float sub_CAD4B0();
void ResetState();
void UpdateGaugePositions();
void UpdateHpGauge();

View file

@ -408,7 +408,7 @@ int AiHomunGetV(lua_State* state) {
}
std::uint32_t homunAid = *reinterpret_cast<const std::uint32_t*>(&g_session.unknown_5570[8]);
if (actor->render.accountId != g_session.m_aid && !g_session.sub_E1DE30(actor->render.accountId)) {
if (actor->render.accountId != g_session.m_aid && !g_session.IsCompanionAid(actor->render.accountId)) {
CGameActor* targetActor = static_cast<CGameActor*>(static_cast<CGameMode*>(g_modeMgr.GetGameMode())->scene->GetGameActorByAID(homunAid));
if (targetActor) {
int targetX, targetY;
@ -592,7 +592,7 @@ int AiMercenaryGetV(lua_State* state) {
}
std::uint32_t mercAid = *reinterpret_cast<const std::uint32_t*>(&g_session.unknown_5620[8]);
if (actor->render.accountId != g_session.m_aid && !g_session.sub_E1DE30(actor->render.accountId)) {
if (actor->render.accountId != g_session.m_aid && !g_session.IsCompanionAid(actor->render.accountId)) {
CGameActor* targetActor = static_cast<CGameActor*>(static_cast<CGameMode*>(g_modeMgr.GetGameMode())->scene->GetGameActorByAID(mercAid));
if (targetActor) {
int targetX, targetY;

View file

@ -553,7 +553,7 @@ void CPc::Slot39(int value) {
// OFFSET: 0x00DDD190
// FUNCTION: fn_23381
static __declspec(noinline) std::string GetBodyImfName(int job, int sex, int head, int costumeJob) {
__declspec(noinline) std::string GetBodyImfName(int job, int sex, int head, int costumeJob) {
return g_equipmentResourceMgr->GetBodyImfName(job, sex, head, costumeJob);
}

View file

@ -86,7 +86,6 @@ struct CharacterRenderDrawItem {
RenderCommand* command;
};
std::list<CharacterRenderDrawItem> sub_8105A0(unsigned char kind, char* useBounds);
// GLOBAL: gl_24798
int g_multiHitInterval = 200;
@ -2640,7 +2639,7 @@ void CCharacterNpc::Render(int) {
characterRender->unknown_0044 = this->render.curMotion;
char useBounds = 0;
std::list<CharacterRenderDrawItem> drawList = sub_8105A0(this->render.unknown_00A4Bytes[1], &useBounds);
std::list<CharacterRenderDrawItem> drawList = characterRender->BuildDrawList(this->render.unknown_00A4Bytes[1], &useBounds);
float bounds[5];
std::memcpy(bounds, characterRender->unknown_0094, sizeof(bounds));
@ -4536,75 +4535,6 @@ void CGameActor::SetActorJob(int job) {
this->sub_CAA4D0();
}
__declspec(noinline) void CWorld::PlayerMove(const float& x, const float& z) {
const float position[2] = { x, z };
UpdateWorldProximityNotification(
reinterpret_cast<unsigned char&>(this->unknown_00F4),
[this, position]() {
return this->FindActorInCell(position, [](std::uint32_t id) {
return id == g_guildInfo.unknown_00D0;
});
},
GetRagConnection(),
g_packetLengths,
g_guildInfo.unknown_00D0
);
}
__declspec(noinline) void CWorld::PcApproachToPlayer(std::uint32_t accountId, const CellFloatPos& pos) {
if (this->player == nullptr) {
return;
}
if (this->player->Slot50() < 1) {
return;
}
bool found = false;
for (std::list<CRenderObject*>::iterator it = this->actors.begin(); it != this->actors.end(); ++it) {
CGameActor* actor = static_cast<CGameActor*>(*it);
if (actor == nullptr) {
continue;
}
if (actor->render.accountId != accountId) {
continue;
}
if (actor->Slot42() == static_cast<int>(g_guildInfo.unknown_00D0)) {
found = true;
break;
}
}
if (!found) {
return;
}
const float playerX = this->player->render.position.x;
const float playerZ = this->player->render.position.z;
const float cellX = pos.x;
const float cellZ = pos.z;
const int range = this->nearbyRange;
UpdateWorldProximityNotification(
reinterpret_cast<unsigned char&>(this->unknown_00F4),
[playerX, playerZ, cellX, cellZ, range]() {
const float dx = playerX - cellX;
const float dz = playerZ - cellZ;
return dx * dx + dz * dz <= static_cast<float>(range) * static_cast<float>(range);
},
GetRagConnection(),
g_packetLengths,
g_guildInfo.unknown_00D0
);
}
__declspec(noinline) void CGameMode::RemoveUnknown0604(int window) {
for (std::list<UIWindow*>::iterator it = this->unknown_0604.begin(); it != this->unknown_0604.end(); ++it) {
if (*it == reinterpret_cast<UIWindow*>(window)) {
this->unknown_0604.erase(it);
return;
}
}
}
// OFFSET: 0x00CAAFD0
// FUNCTION: fn_21023
void CGameActor::ClearUnknown0188() {
@ -4859,6 +4789,15 @@ CCharacterNpc::CCharacterNpc() : CNpc() {
this->unknown_0440 = 0;
}
// INLINED
CCharacterNpc::~CCharacterNpc() {
if (this->unknown_0440) {
delete this->unknown_0440;
this->unknown_0440 = nullptr;
}
}
// OFFSET: 0x00CBFC40
// FUNCTION: fn_21120
void CGameActor::SetStatusStates(int bodyState, std::uint32_t stateFlags, int effectState, bool notify) {

View file

@ -98,7 +98,6 @@ public:
unsigned char animation, unsigned char firstFrame, unsigned char lastFrame, unsigned char finishAnimation,
unsigned char finishFrame, int timed, std::uint32_t duration, int loop
);
void ClearLevelEffects();
void PlayFrameSounds();
/* 0010 */ RenderObjectState render;

View file

@ -1,4 +1,5 @@
#include "Client/Session.h"
#include "Utility/EncryptedName.h"
#include "Contents/EquipmentResourceMgr.h"
#include "Contents/Jobs/JobId.h"
#include "Utility/Cipher/XorBytes.h"
@ -8,35 +9,6 @@
#include <cstdint>
#include <string>
template <std::size_t Length, std::uint64_t Key>
class EncryptedName {
public:
// INLINED
explicit EncryptedName(const char (&source)[Length]) : m_encrypted(true) {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = source[index];
}
}
~EncryptedName() {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = 0;
}
}
const char* Text() {
if (this->m_encrypted) {
utility::XorBytes(this->m_text, Length, Key);
this->m_encrypted = false;
}
return reinterpret_cast<const char*>(this->m_text);
}
private:
/* 0000 */ std::uint8_t m_text[Length];
bool m_encrypted;
};
// OFFSET: 0x00DC7440
// FUNCTION: fn_22794

View file

@ -318,8 +318,7 @@ public:
void Paint() override;
int SendMsg(UIWindow* sender, int message, std::intptr_t argument1, std::intptr_t argument2, std::intptr_t argument3, std::intptr_t argument4) override;
unsigned int Select(int actionId);
void Select(CashEmotionCommand* command);
__declspec(noinline) void Select(CashEmotionCommand* command);
void Previous();
void Refresh(int first);
void Next();
@ -640,14 +639,14 @@ void CCashEmotionMgr::RefreshCommands() {
// OFFSET: 0x00599730
// FUNCTION: fn_02942
int CCashEmotionMgr::ProcessChatCommand(const char* command) {
void CCashEmotionMgr::ProcessChatCommand(const char* command) {
if (!ChatWindow() || !ChatWindow()->m_suggestions) {
return 0;
return;
}
if (!command || std::strlen(command) < 1 || command[0] != '/') {
ChatWindow()->ShowSuggestions(0);
return 0;
return;
}
const char* key = command + 1;
@ -661,10 +660,9 @@ int CCashEmotionMgr::ProcessChatCommand(const char* command) {
if (actionId != 0) {
ChatWindow()->ShowSuggestions(1);
auto* miniWnd = reinterpret_cast<UICashEmotionMiniWnd*>(ChatWindow()->m_suggestions);
return static_cast<int>(miniWnd->Select(actionId));
miniWnd->Select(reinterpret_cast<CashEmotionCommand*>(actionId));
} else {
this->HideSuggestions();
return 0;
}
}

View file

@ -130,7 +130,7 @@ public:
void ClearCommands();
__declspec(noinline) void HideSuggestions();
__declspec(noinline) int FindEmotionId(const char* name);
int ProcessChatCommand(const char* command);
void ProcessChatCommand(const char* command);
__declspec(noinline) const char* GetPackName(int packId);
std::vector<int> FindBaseEmotions(const char* filter);
__declspec(noinline) CashEmotionTable* GetBasePackEmotions();

View file

@ -1117,25 +1117,6 @@ bool CSession::OnItemEquipped(ITEM_INFO& item) {
return true;
}
void EquipmentProperties::CEquipmentPropertiesMgr::UnequipWearable(const int& location) {
this->m_dirty = true;
auto found = this->properties1.find(GetEquipLocationIndex(location));
if (found != this->properties1.end()) {
CEquipmentWearable*& wearable = found->second;
for (CEquipmentAttachable& attachable : wearable->GetAttachables()) {
this->UnequipItem(attachable.GetId(), true);
}
this->UnequipItem(wearable->GetId(), true);
wearable->Clear();
delete wearable;
this->properties1.erase(found);
}
if (this->unknown_0020 != nullptr) {
this->unknown_0020->SendMsg(nullptr, 0x3C, 0, 0, 0, 0);
}
}
// OFFSET: 0x00DFC620
// FUNCTION: fn_23598
bool CSession::UnequipItem(int location, std::uint32_t identity) {

View file

@ -1,6 +1,7 @@
#include "Contents/ClientState.h"
#include "Client/Mode/CGameMode.h"
#include "Contents/Configuration/ServiceOptions.h"
#include "Client/Mode/ModeMgr.h"
#include "Client/Session.h"
#include "Contents/Actors/Pc.h"
@ -981,14 +982,12 @@ void CSession::SetPetAutoFeed(bool enabled) {
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(text), 0x64FFFF, 0, 0, 0);
}
extern "C" void __cdecl sub_6C2A80(int id, bool value);
// OFFSET: 0x00E489C0
// FUNCTION: fn_24224
void __stdcall sub_E489C0(bool enabled) {
std::string notice = LookupMessage(enabled ? 4357 : 4379);
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(notice.c_str()), 0x64FFFF, 0, 0, 0);
sub_6C2A80(0x128, enabled);
g_serviceOptions.Set(0x128, enabled);
g_windowMgr.sub_AAB070(0x128);
}

View file

@ -1,4 +1,5 @@
#include "Contents/Configuration/ServiceOptions.h"
#include "Utility/EncryptedName.h"
#include "Contents/Actors/Pc.h"
#include "Contents/Camera/Camera.h"
#include "Contents/Configuration/ServiceConfiguration.h"
@ -410,35 +411,6 @@ const char* const g_serviceOptionNames[300] = {
"TT_3D_SOUND_ON_OFF"
};
template <std::size_t Length, std::uint64_t Key>
class EncryptedName {
public:
explicit EncryptedName(const std::uint8_t (&source)[Length]) : m_encrypted(true) {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = source[index];
}
}
~EncryptedName() {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = 0;
}
}
const char* Text() {
if (this->m_encrypted) {
utility::XorBytes(this->m_text, Length, Key);
this->m_encrypted = false;
}
return reinterpret_cast<const char*>(this->m_text);
}
private:
std::uint8_t m_text[Length];
bool m_encrypted;
};
__declspec(noinline) void NotifyServiceOption(unsigned char enabled, int enabledMessage, int disabledMessage, int color);
__declspec(noinline) void ApplyServiceOption(int id, unsigned char value, bool notify, int enabledMessage, int disabledMessage);
@ -706,8 +678,6 @@ bool GameSettings::ReadOptionTable() {
return lua_gettop(state) == 0;
}
void sub_AAB070(int id);
// OFFSET: 0x006C2610
// FUNCTION: fn_06322
void GameSettings::ResetToDefaults() {
@ -729,7 +699,7 @@ void GameSettings::ToggleOption(int id) {
if (option.type == 0) {
const unsigned char current = g_serviceOptions.Get(id);
this->sub_6C0C40(id, current == 0, true);
sub_AAB070(id);
g_windowMgr.sub_AAB070(id);
} else if (option.type == 1) {
const auto entry = this->functions.find(id);
if (entry != this->functions.end() && entry->second) {
@ -1112,7 +1082,7 @@ void ApplyServiceOptionAskOnDisable(int id, unsigned char value, bool notify, in
if (!value &&
g_windowMgr.Confirm(LookupMessage(0x1104), 2, true, false, 0, "Message", 0x118, 0x78, 0) == 0xBC) {
g_serviceOptions.Set(0x128, 1);
sub_AAB070(0x128);
g_windowMgr.sub_AAB070(0x128);
return;
}

View file

@ -19,7 +19,7 @@ struct ServiceOptions {
/* 0000 */ std::unordered_map<std::uint32_t, unsigned char, SkillIdHash> values;
unsigned char Get(int id) const;
bool Set(int id, unsigned char value);
static bool Set(int id, unsigned char value);
};
extern ServiceOptions g_serviceOptions;

View file

@ -6640,7 +6640,7 @@ void CEffectPrim::Render2DPrimitive() {
if (cdState) {
cdState->x = static_cast<int>(this->render.position.x);
cdState->y = static_cast<int>(this->render.position.y);
g_cooldownOwner->Draw(0, 0, 16, 16, *cdState, 0, 0, 0);
g_cooldownOwner->Drawing().Draw(0, 0, 16, 16, *cdState, 0, 0, 0);
}
}
}
@ -6648,7 +6648,7 @@ void CEffectPrim::Render2DPrimitive() {
if (g_overrideColor == 1) {
g_cooldownOwner->ClearReverseCommands();
} else {
g_cooldownOwner->SubmitReverse();
g_cooldownOwner->Drawing().SubmitReverse(g_renderer->queues, g_renderer->fog.supported != 0, g_depthStart, g_depthEnd);
}
}
}

View file

@ -132,6 +132,11 @@ CEZ2STRParticle::CEZ2STRParticle(vector3d position, int flags) : CParticle(posit
this->Clear();
}
// INLINED
CEZ2STRParticle::~CEZ2STRParticle() {
}
// OFFSET: 0x00B3CFC0
// FUNCTION: fn_18815
void CEZ2STRParticle::Slot01() {

View file

@ -470,7 +470,7 @@ void CSpriteEffect::Slot03() {
case 0x46A: {
int height = 8;
if (CGameActor* actor = static_cast<CGameActor*>(FindRenderObject(this->actor))) {
height = static_cast<int>(actor->sub_CAD4B0() + 8.0f);
height = static_cast<int>(actor->GetNameOffset() + 8.0f);
}
particle->position.x = this->position[0];
@ -496,7 +496,7 @@ void CSpriteEffect::Slot03() {
case 0x488: {
int height = 25;
if (CGameActor* actor = static_cast<CGameActor*>(FindRenderObject(this->actor))) {
height = static_cast<int>(actor->sub_CAD4B0() + 25.0f);
height = static_cast<int>(actor->GetNameOffset() + 25.0f);
}
particle->position.x = this->position[0];
@ -512,7 +512,7 @@ void CSpriteEffect::Slot03() {
break;
}
const int height = static_cast<int>(actor->sub_CAD4B0() + 8.0f);
const int height = static_cast<int>(actor->GetNameOffset() + 8.0f);
particle->position.x = this->position[0];
particle->position.y = this->position[1] - static_cast<float>(height);
particle->position.z = this->position[2];
@ -524,7 +524,7 @@ void CSpriteEffect::Slot03() {
break;
}
const int height = static_cast<int>(actor->sub_CAD4B0() + 3.0f);
const int height = static_cast<int>(actor->GetNameOffset() + 3.0f);
particle->position.x = this->position[0];
particle->position.y = this->position[1] - static_cast<float>(height);
particle->position.z = this->position[2];
@ -537,7 +537,7 @@ void CSpriteEffect::Slot03() {
break;
}
const int height = static_cast<int>(actor->sub_CAD4B0());
const int height = static_cast<int>(actor->GetNameOffset());
particle->position.x = this->position[0];
particle->position.y = this->position[1] - static_cast<float>(height);
particle->position.z = this->position[2];
@ -549,7 +549,7 @@ void CSpriteEffect::Slot03() {
break;
}
const float height = actor->sub_CAD4B0();
const float height = actor->GetNameOffset();
const float offset = g_session.IsDoramJob(actor->GetEffectiveJob(-1)) ? height + 13.7f : height + 17.0f;
particle->position.x = this->position[0];
particle->position.y = this->position[1] - offset;
@ -575,7 +575,7 @@ void CSpriteEffect::Slot03() {
break;
}
const float height = actor->sub_CAD4B0();
const float height = actor->GetNameOffset();
particle->position.x = this->position[0];
particle->position.y = this->position[1] - height;
particle->position.z = this->position[2];

View file

@ -11,8 +11,8 @@
#include <array>
#include <string>
CParticle* sub_B82ED0(const vector3d* position, int flags);
void sub_B82FD0(CParticle* particle);
CParticle* CreateEZ2STRParticle(const vector3d* position, int flags);
void FreeParticle(CParticle* particle);
// GLOBAL: gl_24871
static const std::array<std::string, 4> s_talismanStartEffects = {
@ -48,7 +48,7 @@ CTalismanMarkEffect::CTalismanMarkEffect() : CEffect(-1) {
void CTalismanMarkEffect::Close() {
for (auto it = this->particles.begin(); it != this->particles.end(); ++it) {
if (*it) {
sub_B82FD0(*it);
FreeParticle(*it);
}
}
this->particles.clear();
@ -65,9 +65,9 @@ void CTalismanMarkEffect::PlayEnd() {
const int index = particle->unknown_000C;
const int angle = particle->unknown_004C;
sub_B82FD0(particle);
FreeParticle(particle);
particle = static_cast<CEZ2STRParticle*>(sub_B82ED0(reinterpret_cast<const vector3d*>(this->position), 13));
particle = static_cast<CEZ2STRParticle*>(CreateEZ2STRParticle(reinterpret_cast<const vector3d*>(this->position), 13));
if (!particle) {
*it = nullptr;
continue;
@ -92,7 +92,7 @@ void CTalismanMarkEffect::Slot01() {
this->retained = 1;
for (int i = 0; i < std::min<unsigned int>(this->unknown_00B0, 4); ++i) {
CEZ2STRParticle* particle = static_cast<CEZ2STRParticle*>(sub_B82ED0(reinterpret_cast<const vector3d*>(this->position), 13));
CEZ2STRParticle* particle = static_cast<CEZ2STRParticle*>(CreateEZ2STRParticle(reinterpret_cast<const vector3d*>(this->position), 13));
if (!particle) {
continue;
}
@ -128,9 +128,9 @@ void CTalismanMarkEffect::Slot03() {
{
const int index = particle->unknown_000C;
const int angle = particle->unknown_004C;
sub_B82FD0(particle);
FreeParticle(particle);
particle = static_cast<CEZ2STRParticle*>(sub_B82ED0(reinterpret_cast<const vector3d*>(this->position), 13));
particle = static_cast<CEZ2STRParticle*>(CreateEZ2STRParticle(reinterpret_cast<const vector3d*>(this->position), 13));
if (!particle) {
*it = nullptr;
continue;
@ -156,7 +156,7 @@ void CTalismanMarkEffect::Slot03() {
break;
}
sub_B82FD0(particle);
FreeParticle(particle);
it = this->particles.erase(it);
continue;
default:

View file

@ -9,8 +9,8 @@
#include <cmath>
CParticle* sub_B82ED0(const vector3d* position, int flags);
void sub_B82FD0(CParticle* particle);
CParticle* CreateEZ2STRParticle(const vector3d* position, int flags);
void FreeParticle(CParticle* particle);
// OFFSET: 0x0072ED00
// FUNCTION: fn_07521
@ -21,7 +21,7 @@ CTriangleShotArrow::CTriangleShotArrow() : CEffect(-1), current{}, direction{},
// OFFSET: 0x0072EE80
// FUNCTION: fn_07523
void CTriangleShotArrow::Close() {
sub_B82FD0(this->arrow);
FreeParticle(this->arrow);
}
// OFFSET: 0x0072EE90
@ -31,7 +31,7 @@ void CTriangleShotArrow::Slot01() {
this->current.y = this->position[1];
this->current.z = this->position[2];
CEZ2STRParticle* arrow = static_cast<CEZ2STRParticle*>(sub_B82ED0(&this->current, 5));
CEZ2STRParticle* arrow = static_cast<CEZ2STRParticle*>(CreateEZ2STRParticle(&this->current, 5));
if (g_serviceOptions.Get(229)) {
arrow->Open("mineffect\\new_triangleshot\\new_triangleshot_arrow\\new_triangleshot_arrow.str");
} else {

View file

@ -58,6 +58,11 @@ CEnchantMgr::CEnchantMgr() {
m_unknown_0030 = true;
}
// INLINED
CEnchantMgr::~CEnchantMgr() {
}
// OFFSET: 0x00682960
// FUNCTION: fn_05540
void CEnchantMgr::SendCloseEnchant() {

View file

@ -420,18 +420,11 @@ std::string ITEM_INFO::DisplayName(unsigned char detailed) const {
#include "File/File.h"
#include "File/ResourcePath.h"
#include "Resource/Bitmap/BitmapResource.h"
class CItemInfoMgr {
public:
void Apply(std::map<int, ITEM_DESC>& values);
};
#include "Contents/Items/ItemInfoMgr.h"
// GLOBAL: gl_24730
CCommonObject g_tableStorage;
// GLOBAL: gl_24729
CItemInfoMgr* g_itemInfoMgr;
// OFFSET: 0x005E11E0
// FUNCTION: fn_03873
std::string ItemDisplayName(int id) {
@ -751,7 +744,7 @@ __declspec(noinline) void LoadItemNameTables() {
}
}
g_itemInfoMgr->Apply(g_itemDescriptions);
g_itemInfoMgr->SetItemInfo(g_itemDescriptions);
}
if (ResourceExists("EventNum2ItemResNameTable.txt", 0)) {

View file

@ -1,4 +1,5 @@
#include "Contents/Messenger/ClientMessenger.h"
#include "Utility/EncryptedName.h"
#include "Contents/Effects/PartyMemberEffects.h"
#include "Client/Mode/ModeMgr.h"
#include "Client/Mode/CGameMode.h"
@ -6243,35 +6244,6 @@ void CGameMode::Zc_Mer_Par_Change(const unsigned char* data) {
g_session.RefreshMercenaryInfo();
}
template <std::size_t Length, std::uint64_t Key>
class EncryptedName {
public:
explicit EncryptedName(const std::uint8_t (&source)[Length]) : m_encrypted(true) {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = source[index];
}
}
~EncryptedName() {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = 0;
}
}
const char* Text() {
if (this->m_encrypted) {
utility::XorBytes(this->m_text, Length, Key);
this->m_encrypted = false;
}
return reinterpret_cast<const char*>(this->m_text);
}
private:
/* 0000 */ std::uint8_t m_text[Length];
bool m_encrypted;
};
template <std::size_t CaptionLength, std::uint64_t CaptionKey, std::size_t MessageLength, std::uint64_t MessageKey>
void ShowEncryptedFailure(const std::uint8_t (&captionBytes)[CaptionLength], const std::uint8_t (&messageBytes)[MessageLength]) {
thread_local EncryptedName<CaptionLength, CaptionKey> caption(captionBytes);

View file

@ -87,8 +87,6 @@ public:
void RemoveGauge();
void SetUnknown010C(int first, int second);
void SetGaugeValues(int current, int maximum);
std::string sub_A80880(int width, const char* text, int font, int height, int bold);
void sub_A84360(int x, int y, const char* text, int length, int font, int height, unsigned int color, int bold, int shadow);
/* 00B4 */ MessengerMember member;
/* 0104 */ UIPcGage* gauge;
@ -396,8 +394,8 @@ void UIDragMiniPartyWnd::Paint() {
const char* mapName = g_session.GetMapDisplayName(this->member.map.c_str());
char text[256];
sprintf(text, "%d %s(%s)", this->member.level, this->member.name.c_str(), mapName);
std::string clipped = this->sub_A80880(this->geometry.width - 0x43, text, 0, 12, 1);
this->sub_A84360(
std::string clipped = this->FitDisplayText(this->geometry.width - 0x43, text, 0, 12, 1);
this->DrawTextAt(
this->iconPositions[this->iconIndex].x + 0x1C,
this->iconPositions[this->iconIndex].y + 3,
clipped.c_str(),
@ -413,7 +411,7 @@ void UIDragMiniPartyWnd::Paint() {
char hpText[128];
sprintf(hpText, "%d/%d", this->gauge->current, this->gauge->maximum);
int len = static_cast<int>(strlen(hpText));
this->sub_A84360(
this->DrawTextAt(
this->gauge->geometry.x + 0x42,
this->gauge->geometry.y - 4,
hpText,

View file

@ -632,8 +632,8 @@ int CRenewQuestMgr::L_AddQuestIconTooltip(lua_State* state) {
// OFFSET: 0x0067B620
// FUNCTION: fn_05457
void CRenewQuestMgr::sub_67B620(unsigned int questId) {
if (auto* window = static_cast<CUIRenewQuestUI*>(g_windowMgr.EnsureWindow(0x2719))) {
window->sub_A56050(questId);
if (auto* window = static_cast<CUIOngoingQuestInfo*>(g_windowMgr.EnsureWindow(0x2719))) {
window->SetQuest(questId);
}
}

View file

@ -1,13 +1,177 @@
#include "Contents/ReputeMgr.h"
#include "Client/Application/ErrorDialog.h"
#include "Render/DeviceContext/DCSurface.h"
#include "Contents/MessageTable.h"
#include "File/File.h"
#include "Network/TextEncoding.h"
#include "UI/Window/UIWindow.h"
#include "UI/Window/UIWindowMgr.h"
#include "Utility/JsonCppLoader.h"
#include <algorithm>
#include <cstring>
#include <utility>
int sub_AD6360(const char* text, unsigned int type);
// OFFSET: 0x0050AE30
// FUNCTION: fn_00894
bool JsonCppLoader::sub_50AE30(std::map<int, ReputeGroupRecord>* out) {
if (!this->loaded) {
this->Fail("초기화가 되어야 합니다.");
return false;
}
JsonValue groups;
this->GetValue(groups, "ReputeGroup", this->document, JsonValue::OBJECT_VALUE);
if (groups.IsNull()) {
this->Fail("키에 해당하는 데이터가 없습니다. (key : %s)", "ReputeGroup");
return false;
}
const JsonObject& members = groups.GetObject();
for (JsonObject::const_iterator member = members.begin(); member != members.end(); ++member) {
JsonValue idValue;
JsonValue nameValue;
JsonValue listValue;
this->GetValue(idValue, "ID", member->second, JsonValue::STRING_VALUE);
if (idValue.IsNull()) {
this->Fail("key 에 해당하는 데이터를 찾지 못했습니다. (keyName : %s)", "ID");
}
this->GetValue(nameValue, "Name", member->second, JsonValue::STRING_VALUE);
if (nameValue.IsNull()) {
this->Fail("key 에 해당하는 데이터를 찾지 못했습니다. (keyName : %s)", "Name");
}
this->GetValue(listValue, "ReputeList", member->second, JsonValue::ARRAY_VALUE);
if (listValue.IsNull()) {
this->Fail("key 에 해당하는 데이터를 찾지 못했습니다. (keyName : %s)", "ReputeList");
}
ReputeGroupRecord record;
if (!idValue.IsNull()) {
record.id = idValue.AsString();
}
if (!nameValue.IsNull()) {
record.name = nameValue.AsString();
}
if (!listValue.IsNull()) {
const JsonArray& ids = listValue.GetArray();
for (JsonArray::const_iterator id = ids.begin(); id != ids.end(); ++id) {
if (id->GetType() != JsonValue::INT64_VALUE) {
this->Fail("잘못된 데이터가 입력되었습니다. intValue 가 입력되어야 합니다. (keyName : %s)", "ReputeList");
break;
}
record.reputes.push_back(id->AsInt());
}
}
if (!out->insert(std::make_pair(std::stoi(member->first), record)).second) {
this->Fail("중복키가 입력되었습니다. (name : %s)", member->first.c_str());
return false;
}
}
return this->succeeded;
}
// OFFSET: 0x0050B830
// FUNCTION: fn_00895
bool JsonCppLoader::sub_50B830(std::map<int, ReputeInfoRecord>* out) {
if (!this->loaded) {
this->Fail("초기화가 되어야 합니다.");
return false;
}
const JsonValue* infos = nullptr;
if (const JsonObject* root = this->document.ObjectRange()) {
for (const JsonMember& entry : *root) {
if (entry.first == "reputeInfo") {
infos = &entry.second;
break;
}
}
}
if (infos == nullptr) {
this->Fail("키에 해당하는 데이터가 없습니다. (key : %s)", "reputeInfo");
return false;
}
const JsonObject* members = infos->ObjectRange();
const JsonObject none;
for (const JsonMember& member : members ? *members : none) {
const std::string name = member.first;
const JsonValue node = member.second;
ReputeInfoRecord record;
this->GetStringValue(node, "Name", &record.name);
this->GetIntValue(node, "MaxPoint_Positive", &record.maxPointPositive);
this->GetIntValue(node, "MaxPoint_Negative", &record.maxPointNegative);
this->GetStringValue(node, "Invisible", &record.invisible);
if (!out->insert(std::make_pair(std::stoi(name), record)).second) {
this->Fail("중복키가 입력되었습니다. (key : %s)", name.c_str());
return false;
}
}
return this->succeeded;
}
// OFFSET: 0x0060DC70
// FUNCTION: fn_04294
bool CReputeMgr::sub_60DC70(std::map<std::uint64_t, ReputeGroup>& groups) {
std::string path = "ContentData\\Repute\\ReputeGroupData.bson";
CFile file;
if (!file.Open(path.c_str(), 0, true, false)) {
return false;
}
const auto* data = static_cast<const unsigned char*>(file.GetData());
std::vector<unsigned char> buffer(data, data + file.GetSize());
JsonCppLoader loader;
if (!loader.sub_4F3C70(buffer, true)) {
return false;
}
std::map<int, ReputeGroupRecord> records;
if (!loader.sub_50AE30(&records)) {
return false;
}
groups.clear();
for (std::pair<const int, ReputeGroupRecord> record : records) {
GroupInserter{this, &groups}(record);
}
return true;
}
// OFFSET: 0x0060E090
// FUNCTION: fn_04295
bool CReputeMgr::sub_60E090(std::map<std::uint64_t, ReputeInfo>& infos) {
std::string path = "ContentData\\Repute\\ReputeInfoData.bson";
CFile file;
if (!file.Open(path.c_str(), 0, true, false)) {
return false;
}
const auto* data = static_cast<const unsigned char*>(file.GetData());
std::vector<unsigned char> buffer(data, data + file.GetSize());
JsonCppLoader loader;
if (!loader.sub_4F3C70(buffer, true)) {
return false;
}
std::map<int, ReputeInfoRecord> records;
if (!loader.sub_50B830(&records)) {
return false;
}
infos.clear();
for (std::pair<const int, ReputeInfoRecord> record : records) {
InfoInserter{this, &infos}(record);
}
return true;
}
// OFFSET: 0x0060C5D0
// FUNCTION: fn_04283
@ -76,7 +240,7 @@ bool CReputeMgr::sub_60DBF0() {
return true;
}
sub_AD6360("Failed : LoadReputeInfoData", 0);
ShowErrorDialog(GetRenderSystemHolder()->system, "Failed : LoadReputeInfoData", 0);
return false;
}

View file

@ -68,6 +68,7 @@ public:
class CSkillAction_DamageWereRaptorForm : public CSkillAction_AnimalForm, public CSkillAction_Direction {
public:
void sub_5A4760(int sourceActor, CGameActor* target);
void Slot16(int level, CGameActor* source, CGameActor* target) override;
bool Slot17(CGameActor* actor) override;
void Slot18(CGameActor* actor) override;
@ -189,7 +190,6 @@ public:
int Slot02() override;
void Slot11(int level, CGameActor* source, CGameActor* target) override;
void Slot15(int level, CGameActor* source, CGameActor* target) override;
void sub_5A4760(int level, CGameActor* source);
};
class CSkillAction_DR_FLICKING_TONADO : public CSkillAction_DamageWereRaptorForm {

View file

@ -11,52 +11,50 @@ extern "C" {
CSkillInfo* FindGroupedSkill(CSession& session, std::uint32_t id);
namespace {
// OFFSET: 0x00AFEE00
// FUNCTION: fn_18349
int AddSkill(lua_State* state) {
CSkillInfo skill(0);
const double group = luaL_checknumber(state, 1);
const double id = luaL_checknumber(state, 2);
const char* name = luaL_checkstring(state, 3);
const int position = static_cast<int>(luaL_checknumber(state, 4));
const int value = static_cast<int>(luaL_checknumber(state, 5));
const double last = luaL_checknumber(state, 6);
// OFFSET: 0x00AFEE00
// FUNCTION: fn_18349
int AddSkill(lua_State* state) {
CSkillInfo skill(0);
const double group = luaL_checknumber(state, 1);
const double id = luaL_checknumber(state, 2);
const char* name = luaL_checkstring(state, 3);
const int position = static_cast<int>(luaL_checknumber(state, 4));
const int value = static_cast<int>(luaL_checknumber(state, 5));
const double last = luaL_checknumber(state, 6);
if (std::strcmp(name, "") != 0 && position != -1 && value != -1) {
skill.level = 0;
skill.unknown_0014 = 0;
skill.unknown_001C = 0;
skill.unknown_0018 = 0;
skill.available = 1;
skill.name = name;
skill.unknown_0024 = position;
skill.unknown_0028 = value;
skill.id = static_cast<std::uint32_t>(static_cast<int>(id));
skill.unknown_0034 = 0;
skill.unknown_002C = static_cast<int>(last);
g_session.m_skillBundle.AddGrouped(static_cast<int>(group), skill);
}
return 1;
if (std::strcmp(name, "") != 0 && position != -1 && value != -1) {
skill.level = 0;
skill.unknown_0014 = 0;
skill.unknown_001C = 0;
skill.unknown_0018 = 0;
skill.available = 1;
skill.name = name;
skill.unknown_0024 = position;
skill.unknown_0028 = value;
skill.id = static_cast<std::uint32_t>(static_cast<int>(id));
skill.unknown_0034 = 0;
skill.unknown_002C = static_cast<int>(last);
g_session.m_skillBundle.AddGrouped(static_cast<int>(group), skill);
}
// OFFSET: 0x00AFED50
// FUNCTION: fn_18348
int AddNeededSkill(lua_State* state) {
const int id = static_cast<int>(luaL_checknumber(state, 1));
const int needed = static_cast<int>(luaL_checknumber(state, 2));
const int level = static_cast<int>(luaL_checknumber(state, 3));
return 1;
}
if (id != -1 && needed != -1 && level != -1) {
CSkillInfo* skill = FindGroupedSkill(g_session, static_cast<std::uint32_t>(id));
if (skill && skill->available) {
skill->entries.push_back({static_cast<std::uint32_t>(needed), static_cast<std::uint32_t>(level)});
}
// OFFSET: 0x00AFED50
// FUNCTION: fn_18348
int AddNeededSkill(lua_State* state) {
const int id = static_cast<int>(luaL_checknumber(state, 1));
const int needed = static_cast<int>(luaL_checknumber(state, 2));
const int level = static_cast<int>(luaL_checknumber(state, 3));
if (id != -1 && needed != -1 && level != -1) {
CSkillInfo* skill = FindGroupedSkill(g_session, static_cast<std::uint32_t>(id));
if (skill && skill->available) {
skill->entries.push_back({static_cast<std::uint32_t>(needed), static_cast<std::uint32_t>(level)});
}
return 1;
}
return 1;
}
// INLINED

View file

@ -4,6 +4,8 @@
struct lua_State;
class CPlayerSkillBundle;
int AddSkill(lua_State* state);
int AddNeededSkill(lua_State* state);
void RegisterSkillTreeCallbacks(lua_State* state, CPlayerSkillBundle& bundle);
#endif

View file

@ -1,4 +1,5 @@
#include "Contents/SpecialPopupMgr.h"
#include "Script/LuaFileOperations.h"
#include "Script/NLuaState.h"
extern "C" {
@ -12,8 +13,6 @@ extern "C" {
#include <new>
#include <windows.h>
bool sub_AF6580(lua_State* state, const std::string& path, bool flag);
// GLOBAL: gl_24839
CSpecialPopupMgr* g_specialPopupMgr = nullptr;
@ -72,7 +71,7 @@ bool CSpecialPopupMgr::Init() {
lua_pushcclosure(luaState.GetState(), CSpecialPopupMgr::LuaAddDesc, 0);
lua_setfield(luaState.GetState(), LUA_GLOBALSINDEX, "AddDesc");
if (!sub_AF6580(luaState.GetState(), "System\\spopup.lub", false)) {
if (!LoadLuaResource(luaState.GetState(), "System\\spopup.lub", false)) {
MessageBoxA(NULL, lua_tostring(luaState.GetState(), -1), "CSpecialPopupMgr LuaLoadFile X", 0);
return false;
}

View file

@ -6,7 +6,7 @@
// OFFSET: 0x00DDE340
// FUNCTION: fn_23394
static std::string GetBodyActionResourceName(int job, int sex, int costumeJob, int costume) {
std::string GetBodyActionResourceName(int job, int sex, int costumeJob, int costume) {
return g_equipmentResourceMgr->GetBodyResourceName(0, job, sex, costumeJob, costume);
}

View file

@ -30,6 +30,11 @@ CConnection::~CConnection() = default;
CRagConnection::CRagConnection() : unknown_006C(0) {
}
// INLINED
CRagConnection::~CRagConnection() {
}
// OFFSET: 0x00C7C4D0
// FUNCTION: fn_20389
bool CConnection::Connect(const ConnectionEndpoint& endpoint) {

View file

@ -3,6 +3,7 @@
#include <d3d9.h>
extern "C" {
HRESULT WINAPI D3DXFilterTexture(IDirect3DBaseTexture9* texture, const PALETTEENTRY* palette, UINT level, DWORD filter);
HRESULT WINAPI D3DXLoadSurfaceFromMemory(
IDirect3DSurface9* destination, const PALETTEENTRY* destinationPalette, const RECT* destinationRect, const void* source, D3DFORMAT format,
@ -14,5 +15,6 @@ HRESULT WINAPI D3DXLoadSurfaceFromSurface(
);
D3DMATRIX* WINAPI D3DXMatrixPerspectiveFovLH(D3DMATRIX* output, float fovy, float aspect, float nearPlane, float farPlane);
HRESULT WINAPI D3DXSaveSurfaceToFileA(const char* filename, int format, IDirect3DSurface9* surface, const PALETTEENTRY* palette, const RECT* rectangle);
}
#endif

View file

@ -79,32 +79,32 @@ void DrawScreenQuad(
// OFFSET: 0x00915F60
// FUNCTION: fn_12581
void DrawScreenQuad(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, CTexture* texture, std::uint32_t color) {
void DrawScreenQuad(ScreenPoint p0, ScreenPoint p1, ScreenPoint p2, ScreenPoint p3, CTexture* texture, std::uint32_t color) {
RenderPrimitive* primitive = g_renderer->primitives.Acquire();
RenderVertex* vertices = primitive->vertices;
vertices[0].x = x0;
vertices[0].y = y0;
vertices[0].x = p0.x;
vertices[0].y = p0.y;
vertices[0].z = 0.8f;
vertices[0].rhw = 1.0f;
vertices[0].diffuse = color;
vertices[0].u = 0.0f;
vertices[0].v = 0.0f;
vertices[1].x = x1;
vertices[1].y = y1;
vertices[1].x = p1.x;
vertices[1].y = p1.y;
vertices[1].z = 0.8f;
vertices[1].rhw = 1.0f;
vertices[1].diffuse = color;
vertices[1].u = 1.0f;
vertices[1].v = 0.0f;
vertices[2].x = x2;
vertices[2].y = y2;
vertices[2].x = p2.x;
vertices[2].y = p2.y;
vertices[2].z = 0.8f;
vertices[2].rhw = 1.0f;
vertices[2].diffuse = color;
vertices[2].u = 0.0f;
vertices[2].v = 1.0f;
vertices[3].x = x3;
vertices[3].y = y3;
vertices[3].x = p3.x;
vertices[3].y = p3.y;
vertices[3].z = 0.8f;
vertices[3].rhw = 1.0f;
vertices[3].diffuse = color;

View file

@ -1,6 +1,7 @@
#include "Resource/GifResource.h"
#include "File/File.h"
#include "Resource/GifLzw.h"
#include <algorithm>
#include <cstring>
@ -294,7 +295,7 @@ bool CGifRes::DecodeGif(const void* data, int bytes, bool iconOnly) {
++cursor;
unsigned char* indices = new unsigned char[descriptor.width * descriptor.height];
if (this->DecodeGifLzw(minimumCodeSize, compressed, compressedBytes, indices) > 0) {
if (DecodeGifLzw(minimumCodeSize, compressed, compressedBytes, indices) > 0) {
const unsigned int pixelCount = screenHeight * screenWidth;
std::uint32_t* pixels = new std::uint32_t[pixelCount];

View file

@ -23,7 +23,6 @@ public:
void CreateBlank(int width, int height);
bool DecodeGif(const void* data, int bytes, bool iconOnly);
int DecodeGifLzw(int minimumCodeSize, const unsigned char* input, int inputBytes, unsigned char* output);
/* 0124 */ std::vector<Frame> frames;
/* 0130 */ std::uint16_t loopCount;

View file

@ -9,6 +9,7 @@
#include "Contents/Effects/EvilsPawEffect.h"
#include "Contents/Effects/WindEffect.h"
#include "Contents/Hotkeys/HotkeyInfo.h"
#include "Contents/Skills/SkillTreeScript.h"
#include "File/File.h"
#include "File/ResourcePath.h"
#include "Script/LuaFileOperations.h"
@ -88,8 +89,6 @@ static void AddAttendanceBanner(UICheckAttendanceWnd* window, std::string image,
window->m_banner->AddBanner(image, url, action, argument);
}
int AddSkill(lua_State* state);
int AddNeededSkill(lua_State* state);
// OFFSET: 0x00AFF7E0
// FUNCTION: fn_18354

View file

@ -22,9 +22,18 @@ struct TreeSubMap {
unsigned int size;
void Clear() noexcept;
void EraseSubtree(TreeSubMap& al, TreeSubNode* node);
__declspec(noinline) void EraseSubtree(TreeSubMap& al, TreeSubNode* node);
};
// OFFSET: 0x00BA1A20
// FUNCTION: fn_19656
void TreeSubMap::EraseSubtree(TreeSubMap& al, TreeSubNode* node) {
while (node->isnil == 0) {
this->EraseSubtree(al, node->right);
::operator delete(std::exchange(node, node->left), 0x18);
}
}
// OFFSET: 0x00CA4AE0
// FUNCTION: fn_20939
void TreeSubMap::Clear() noexcept {

View file

@ -28,7 +28,7 @@ void sub_E929B0(const char* name);
int sub_E92820();
int __stdcall sub_76D910(int code, const int* packet);
void sub_E92E90(int(__stdcall* callback)(int, const int*));
void sub_CF0BA0(const char* file, int line, const char* message);
void WriteMyLog(const char* file, int line, const char* format, ...);
void __fastcall sub_76C320(void* tokens);
namespace {
@ -257,7 +257,7 @@ int CNProtectGameGuardMgr::sub_76C9D0() {
MessageBoxA(hWnd, message, title, 0);
return 0;
}
sub_CF0BA0(g_nprotectSource, 0x284, title);
WriteMyLog(g_nprotectSource, 0x284, title);
}
sub_E92E90(sub_76D910);

View file

@ -1,21 +1,13 @@
#include "Security/ThemidaMgr.h"
#include "Archive/GPak.h"
#include <new>
#include <random>
// GLOBAL: gl_24891
CThemidaMgr* g_themidaMgr;
void sub_6563E0(char* first, char* last, void* distribution);
struct ThemidaKeyRandom {
std::mt19937 engine;
std::uniform_int_distribution<int> distribution;
ThemidaKeyRandom(unsigned int seed) : engine(seed), distribution(1, 0xfe) {
}
};
struct ThemidaKeyEncoderA {
unsigned char* Generate(const unsigned char* input);
};
@ -38,8 +30,8 @@ CThemidaMgr::~CThemidaMgr() {
// FUNCTION: fn_08237
unsigned char* ThemidaKeyEncoderA::Generate(const unsigned char* input) {
auto* output = reinterpret_cast<unsigned char*>(this);
ThemidaKeyRandom random(std::random_device{}());
sub_6563E0(reinterpret_cast<char*>(output), reinterpret_cast<char*>(output) + 5, &random);
PakUniformRandom random(1, 0xfe, std::random_device{}());
FillRandomBytes(reinterpret_cast<char*>(output), reinterpret_cast<char*>(output) + 5, random);
output[5] = input[0] ^ output[1] ^ output[0];
output[6] = input[1] ^ output[2] ^ output[1];
output[7] = input[2] ^ output[3] ^ output[2];
@ -51,8 +43,8 @@ unsigned char* ThemidaKeyEncoderA::Generate(const unsigned char* input) {
// FUNCTION: fn_08238
unsigned char* ThemidaKeyEncoderB::Generate(const unsigned char* input) {
auto* output = reinterpret_cast<unsigned char*>(this);
ThemidaKeyRandom random(std::random_device{}());
sub_6563E0(reinterpret_cast<char*>(output), reinterpret_cast<char*>(output) + 5, &random);
PakUniformRandom random(1, 0xfe, std::random_device{}());
FillRandomBytes(reinterpret_cast<char*>(output), reinterpret_cast<char*>(output) + 5, random);
output[5] = input[0] ^ output[1] ^ output[0];
output[6] = input[1] ^ output[2] ^ output[1];
output[7] = input[2] ^ output[3] ^ output[2];

View file

@ -195,9 +195,6 @@ static const char bookmarkKeySuffixText[] = "\\BookMark";
// GLOBAL: gl_24751
const char* g_bookmarkKeySuffix = bookmarkKeySuffixText;
// GLOBAL: gl_25332
int g_window315Enabled = 1;
// GLOBAL: gl_25391
bool g_randomLoadingScreen;
@ -611,7 +608,7 @@ void UIEquipWnd::Paint() {
if (this->m_page == 0) {
ITEM_INFO dragItem = LookupClientItemByIdentity(g_session.m_inventoryItems, g_session.unknown_16EC);
if (dragItem.unknown_0000[1] != 0) {
this->sub_8A8EE0(this->geometry.width / 2 - 25, this->m_contentTop + 44, &dragItem, 0);
DrawItemIcon(*this, ResourceMgr::Instance(), this->geometry.width / 2 - 25, this->m_contentTop + 44, dragItem, 0);
this->DrawItemName(this->geometry.width / 2 - 25, this->m_contentTop + 68, 40, &dragItem, 0, 0, 12);
}
this->m_otherButton->Enable(1);
@ -792,7 +789,7 @@ int UIMinimapZoomWnd::SendMsg(UIWindow* sender, int message, std::intptr_t argum
if (!g_session.IsNavigationAllowed()) {
g_windowMgr.Confirm(LookupMessage(2767), 0, true, false, 0, "Message", 280, 120, 0);
} else if (!g_windowMgr.CloseWindow(273)) {
g_windowMgr.sub_A978D0(273);
g_windowMgr.EnsureWindow(273);
}
return 0;
case 216:
@ -825,7 +822,7 @@ int UIMinimapZoomWnd::SendMsg(UIWindow* sender, int message, std::intptr_t argum
}
case 454:
if (!g_windowMgr.CloseWindow(140)) {
g_windowMgr.sub_A978D0(140);
g_windowMgr.EnsureWindow(140);
}
return 0;
case 455: {
@ -3122,7 +3119,7 @@ int UIEquipWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::int
if (g_windowMgr.unknown_0210 != nullptr) {
g_windowMgr.CloseWindow(18);
}
UIWindow* menu = g_windowMgr.sub_A978D0(18);
UIWindow* menu = g_windowMgr.EnsureWindow(18);
if (!menu) {
return 0;
}
@ -3163,7 +3160,7 @@ int UIEquipWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::int
case 249:
if ((g_replayAnimationScaling == 0 || Replay::Instance().header.options.Get(ReplayRecordOption::Item) != 0) && !g_windowMgr.LookupWindow(227) &&
!g_windowMgr.CloseWindow(40) && g_session.unknown_5C1C > 0) {
g_windowMgr.sub_A978D0(40);
g_windowMgr.EnsureWindow(40);
}
return 0;
case 271: {
@ -3235,7 +3232,7 @@ int UIEquipWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::int
}
case 582:
if (!g_windowMgr.CloseWindow(10001)) {
g_windowMgr.sub_A978D0(10001);
g_windowMgr.EnsureWindow(10001);
}
return 0;
}
@ -4287,7 +4284,7 @@ void UIItemIdentifyWnd::Paint() {
this->FillRegion(5, top + 31, this->geometry.width - 24, 30, RGB(red, green, blue));
}
this->sub_8A8EE0(8, y, &*it, 0);
DrawItemIcon(*this, ResourceMgr::Instance(), 8, y, *it, 0);
this->DrawFittedItemName(40, y, &*it, 0, 0, 12, 0);
if (it->unknown_0088 > 0) {
this->DrawBitmap(
@ -5840,7 +5837,7 @@ int UIChatRoomMakeWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, s
if (g_windowMgr.unknown_0214) {
g_windowMgr.CloseWindow(26);
}
UIWindow* list = g_windowMgr.sub_A978D0(26);
UIWindow* list = g_windowMgr.EnsureWindow(26);
int count = 1;
if (a == 228) {
this->m_listKind = 0;
@ -5923,7 +5920,7 @@ int UIChatRoomChangeWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a,
if (g_windowMgr.unknown_0214) {
g_windowMgr.CloseWindow(26);
}
UIWindow* list = g_windowMgr.sub_A978D0(26);
UIWindow* list = g_windowMgr.EnsureWindow(26);
int count = 1;
if (a == 228) {
this->m_listKind = 0;
@ -9963,7 +9960,7 @@ void UIItemCollectionWnd::Slot32(int x, int y) {
card.unknown_0000[0] = 6;
card.unknown_0060 = 0;
card.SetItemId(cardId);
UIWindow* window = g_windowMgr.sub_A978D0(82);
UIWindow* window = g_windowMgr.EnsureWindow(82);
window->SendMsg(nullptr, 76, card.identified, 0, 0, 0);
window->SendMsg(nullptr, 24, reinterpret_cast<std::intptr_t>(&card), index >= ItemSlotsCount(this->m_item), 0, 0);
@ -9976,7 +9973,7 @@ void UIItemCollectionWnd::Slot32(int x, int y) {
compareCard.unknown_0000[0] = 6;
compareCard.unknown_0060 = 0;
compareCard.SetItemId(compareId);
UIWindow* compareWindow = g_windowMgr.sub_A978D0(250);
UIWindow* compareWindow = g_windowMgr.EnsureWindow(250);
compareWindow->SendMsg(nullptr, 76, compareCard.identified, 0, 0, 0);
compareWindow->SendMsg(nullptr, 24, reinterpret_cast<std::intptr_t>(&compareCard), 1, 0, 0);
}
@ -10000,7 +9997,7 @@ void UIItemCollection_ComparisonWnd::Slot32(int x, int y) {
card.unknown_0000[0] = 6;
card.unknown_0060 = 0;
card.SetItemId(cardId);
UIWindow* window = g_windowMgr.sub_A978D0(82);
UIWindow* window = g_windowMgr.EnsureWindow(82);
window->SendMsg(nullptr, 76, card.identified, 0, 0, 0);
window->SendMsg(nullptr, 24, reinterpret_cast<std::intptr_t>(&card), index >= ItemSlotsCount(this->m_item), 0, 0);
}
@ -12427,7 +12424,7 @@ int UIItemCollectionWnd::SendMsg(UIWindow* sender, int message, std::intptr_t ar
g_windowMgr.CloseWindow(this->m_kind);
return 0;
case 250: {
UIWindow* window = g_windowMgr.sub_A978D0(47);
UIWindow* window = g_windowMgr.EnsureWindow(47);
window->SendMsg(nullptr, 62, reinterpret_cast<std::intptr_t>(this->m_item.itemId.c_str()), this->m_item.identified, 0, 0);
return 0;
}
@ -12445,13 +12442,13 @@ int UIItemCollectionWnd::SendMsg(UIWindow* sender, int message, std::intptr_t ar
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>("책이 없습니다"), 0xFF, 0, 0, 0);
return 0;
}
UIWindow* window = g_windowMgr.sub_A978D0(106);
UIWindow* window = g_windowMgr.EnsureWindow(106);
window->SendMsg(nullptr, 94, reinterpret_cast<std::intptr_t>(this->m_item.itemId.c_str()), argument1, 0, 0);
file.Close();
return 0;
}
case 343: {
UIWindow* window = g_windowMgr.sub_A978D0(10012);
UIWindow* window = g_windowMgr.EnsureWindow(10012);
if (window) {
static_cast<CUIProbabilityTable*>(window)->SetItem(this->m_item.GetItemId());
window->PlaceBeside(this);
@ -12460,7 +12457,7 @@ int UIItemCollectionWnd::SendMsg(UIWindow* sender, int message, std::intptr_t ar
break;
}
case 354: {
UIWindow* window = g_windowMgr.sub_A978D0(294);
UIWindow* window = g_windowMgr.EnsureWindow(294);
if (window) {
window->SendMsg(this, 23, reinterpret_cast<std::intptr_t>(&this->m_item), 0, 0, 0);
return 0;
@ -12613,7 +12610,7 @@ int UIItemCollectionWnd::SendMsg(UIWindow* sender, int message, std::intptr_t ar
if (this->m_kind == 12) {
ITEM_INFO* equipped = g_session.GetEquippedItem(&this->m_item);
if (g_serviceOptions.Get(264) && equipped && argument4 == 0) {
UIWindow* window = g_windowMgr.sub_A978D0(234);
UIWindow* window = g_windowMgr.EnsureWindow(234);
if (window) {
window->SendMsg(nullptr, 24, reinterpret_cast<std::intptr_t>(equipped), 1, 0, 0);
}

View file

@ -1980,10 +1980,6 @@ CUIListBox<CUISubTab>* CUITab::CreateSubTabList() {
}
CUIAdventureGuide::CUIAdventureGuide()
: background(nullptr), titleBar(nullptr), characterInfo(nullptr), titleText(nullptr), intro(nullptr), quest(nullptr), monster(nullptr), item(nullptr), tabs(nullptr) {
}
// OFFSET: 0x009C1230
// FUNCTION: fn_13986
CUIAdventureGuide* CreateAdventureGuide() {

View file

@ -155,6 +155,15 @@ public:
}
template <>
void CUIListBoxEx<AdventureGuide::CUIItemInfo, AdventureGuide::CItemData>::AddNewItem();
template <>
void CUIListBoxEx<AdventureGuide::CUIMonsterInfo, AdventureGuide::CMonsterData>::AddNewItem();
template <>
void CUIListBoxEx<AdventureGuide::CUIQuestInfo, AdventureGuide::CQuestInfo>::AddNewItem();
template <>
void CUIListBoxEx<AdventureGuide::CUITabInfo, Guide_Intro::Contents>::AddNewItem();
#if defined(_WIN32) && !defined(_WIN64)
static_assert(sizeof(AdventureGuide::CUIIntro) == 0x8C);
static_assert(sizeof(AdventureGuide::CUIMonster) == 0xA0);

View file

@ -1,4 +1,5 @@
#include "UI/CashShop/UICashShopWnd.h"
#include "Utility/EncryptedName.h"
#include "Client/Mode/CGameMode.h"
#include "Client/Mode/CMode.h"
@ -43,35 +44,6 @@
#include <shellapi.h>
#include <timeapi.h>
template <std::size_t Length, std::uint64_t Key>
class EncryptedName {
public:
// INLINED
explicit EncryptedName(const char (&source)[Length]) : m_encrypted(true) {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = source[index];
}
}
~EncryptedName() {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = 0;
}
}
const char* Text() {
if (this->m_encrypted) {
utility::XorBytes(this->m_text, Length, Key);
this->m_encrypted = false;
}
return reinterpret_cast<const char*>(this->m_text);
}
private:
/* 0000 */ std::uint8_t m_text[Length];
bool m_encrypted;
};
#pragma pack(push, 1)
struct CashItemPurchase {

View file

@ -351,7 +351,7 @@ int UINewChatWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::i
case 6:
switch (a) {
case 0xC1:
if (UIWindow* window = g_windowMgr.sub_A978D0(0x84)) {
if (UIWindow* window = g_windowMgr.EnsureWindow(0x84)) {
window->SendMsg(this, 6, 0xC1, this->m_currentTab, 1, 0);
}
return 0;
@ -375,7 +375,7 @@ int UINewChatWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::i
if (g_windowMgr.unknown_0214 != nullptr) {
g_windowMgr.CloseWindow(0x1A);
}
UIWindow* menu = g_windowMgr.sub_A978D0(0x1A);
UIWindow* menu = g_windowMgr.EnsureWindow(0x1A);
menu->SendMsg(nullptr, 0x1F, reinterpret_cast<std::intptr_t>(LookupMessage(0x55)), 0, 0, 0);
menu->SendMsg(nullptr, 0x1F, reinterpret_cast<std::intptr_t>(LookupMessage(0x56)), 0, 0, 0);
menu->SendMsg(nullptr, 0x1F, reinterpret_cast<std::intptr_t>(LookupMessage(0x1B5)), 0, 0, 0);
@ -402,7 +402,7 @@ int UINewChatWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::i
return 0;
}
UIWindow* menu = g_windowMgr.sub_A978D0(0x1A);
UIWindow* menu = g_windowMgr.EnsureWindow(0x1A);
for (int i = 0; i < count; ++i) {
menu->SendMsg(nullptr, 0x1F, reinterpret_cast<std::intptr_t>(static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->history[i].c_str()), 0, 0, 0);
}

View file

@ -8,6 +8,13 @@ CooldownOwner::CooldownOwner() : m_initialized(false) {
this->m_initialized = true;
}
// INLINED
CooldownOwner::~CooldownOwner() {
this->m_drawing.normal.clear();
this->m_drawing.reverse.clear();
this->m_values.clear();
}
// OFFSET: 0x00CA61A0
// FUNCTION: fn_20957
void CooldownOwner::Register(unsigned id, std::uint32_t duration, std::uint32_t start, std::uint32_t elapsed) {

View file

@ -8,11 +8,9 @@
class CooldownOwner {
public:
CooldownOwner();
~CooldownOwner();
__declspec(noinline) ~CooldownOwner();
void Register(unsigned id, std::uint32_t duration, std::uint32_t start, std::uint32_t elapsed);
void ClearReverseCommands();
void SubmitReverse();
void Draw(int centerX, int centerY, int radiusX, int radiusY, CooldownState& value, int limit, int offsetX, int offsetY);
CooldownState* Find(unsigned id);
void Erase(unsigned id);

View file

@ -195,7 +195,7 @@ void CUIEditCtrlEx::Synchronize() {
if (reinterpret_cast<const unsigned char*>(&this->unknown_0184)[1] != 0) {
int wrapWidth = this->geometry.width - this->unknown_0130->geometry.width - this->unknown_01B4;
this->WrapTextWithBreaks(fullText.c_str(), &lines, &breaks, wrapWidth);
this->sub_860C60(&lines);
this->WrapLines(lines);
} else {
lines.push_back(fullText);
breaks.push_back(false);

View file

@ -29,7 +29,6 @@ public:
void UpdateScrollBar() override;
int SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) override;
void sub_860C60(std::vector<std::string>* lines);
__declspec(noinline) void RefreshPlaceholder();
void HandleKeyDown(int key, std::intptr_t lparam);

View file

@ -1369,7 +1369,7 @@ int UIMerchantItemMyShopWnd::SendMsg(UIWindow* sender, int message, std::intptr_
}
{
UIWindow* window = g_windowMgr.sub_A978D0(windowId);
UIWindow* window = g_windowMgr.EnsureWindow(windowId);
if (window) {
window->Show(1);
window->Move(this->geometry.x, this->geometry.y);
@ -3770,20 +3770,13 @@ bool ItemTypeNameLess::operator()(const ITEM_INFO& left, const ITEM_INFO& right)
return leftRank < rightRank;
}
extern "C" void sub_96E320(void* head, size_t size, ...);
// OFFSET: 0x00996870
// FUNCTION: fn_13470
bool UIItemStoreSubWnd::Sort1() {
if (!this->sub_996950()) {
return false;
}
struct Flag {
char val;
} flag{0};
void* head = *reinterpret_cast<void**>(reinterpret_cast<char*>(this) + 0xe8);
size_t size = *reinterpret_cast<size_t*>(reinterpret_cast<char*>(this) + 0xec);
sub_96E320(head, size, flag);
this->items.sort();
return true;
}
@ -3793,12 +3786,7 @@ bool UIItemStoreSubWnd::Sort2() {
if (!this->sub_996AF0()) {
return false;
}
struct Flag {
char val;
} flag{0};
void* head = *reinterpret_cast<void**>(reinterpret_cast<char*>(this) + 0xe8);
size_t size = *reinterpret_cast<size_t*>(reinterpret_cast<char*>(this) + 0xec);
sub_96E320(head, size, flag);
this->items.sort();
return true;
}
@ -3808,12 +3796,7 @@ bool UIItemStoreSubWnd::Sort3() {
if (!this->sub_996C90()) {
return false;
}
struct Flag {
char val;
} flag{0};
void* head = *reinterpret_cast<void**>(reinterpret_cast<char*>(this) + 0xe8);
size_t size = *reinterpret_cast<size_t*>(reinterpret_cast<char*>(this) + 0xec);
sub_96E320(head, size, flag);
this->items.sort();
return true;
}
@ -3823,12 +3806,7 @@ bool UIItemStoreSubWnd::SortReversed1() {
if (!this->sub_996950()) {
return false;
}
struct Flag {
char val;
} flag{0};
void* head = *reinterpret_cast<void**>(reinterpret_cast<char*>(this) + 0xe8);
size_t size = *reinterpret_cast<size_t*>(reinterpret_cast<char*>(this) + 0xec);
sub_96E320(head, size, flag);
this->items.sort();
this->items.reverse();
return true;
}
@ -3839,12 +3817,7 @@ bool UIItemStoreSubWnd::SortReversed2() {
if (!this->sub_996AF0()) {
return false;
}
struct Flag {
char val;
} flag{0};
void* head = *reinterpret_cast<void**>(reinterpret_cast<char*>(this) + 0xe8);
size_t size = *reinterpret_cast<size_t*>(reinterpret_cast<char*>(this) + 0xec);
sub_96E320(head, size, flag);
this->items.sort();
this->items.reverse();
return true;
}
@ -3855,12 +3828,7 @@ bool UIItemStoreSubWnd::SortReversed3() {
if (!this->sub_996C90()) {
return false;
}
struct Flag {
char val;
} flag{0};
void* head = *reinterpret_cast<void**>(reinterpret_cast<char*>(this) + 0xe8);
size_t size = *reinterpret_cast<size_t*>(reinterpret_cast<char*>(this) + 0xec);
sub_96E320(head, size, flag);
this->items.sort();
this->items.reverse();
return true;
}
@ -6567,7 +6535,7 @@ int UIMerchantItemPurchaseWnd::SendMsg(UIWindow* sender, int message, std::intpt
}
mode->SendMsg(273, this->unknown_00F8, this->unknown_0104, 0, 0);
} else {
static_cast<UIMerchantItemPurchaseMSGWnd*>(g_windowMgr.sub_A978D0(230))->SetPurchase(this->unknown_00F8, this->unknown_0104);
static_cast<UIMerchantItemPurchaseMSGWnd*>(g_windowMgr.EnsureWindow(230))->SetPurchase(this->unknown_00F8, this->unknown_0104);
}
mode->SendMsg(40, 0, 0, 0, 0);
@ -8582,7 +8550,7 @@ int UIItemStoreWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std:
case 365: {
std::string text(this->searchEdit->Text());
if (!text.empty()) {
UIItemStoreFindWnd* window = static_cast<UIItemStoreFindWnd*>(g_windowMgr.sub_A978D0(153));
UIItemStoreFindWnd* window = static_cast<UIItemStoreFindWnd*>(g_windowMgr.EnsureWindow(153));
this->unknown_0140 = window;
window->SetSearchText(std::string(text.c_str(), text.size()));
this->unknown_0140->SendMsg(nullptr, 23, 365, 0, 0, 0);
@ -8606,7 +8574,7 @@ int UIItemStoreWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std:
if (tab->geometry.unknown_0030 != 0) {
this->unknown_0120[index] = nullptr;
this->unknown_0120[index] = g_windowMgr.sub_A978D0(a);
this->unknown_0120[index] = g_windowMgr.EnsureWindow(a);
if (this->unknown_0120[index]) {
this->unknown_0120[index]->SendMsg(nullptr, 23, 0, 0, 0, 0);
}
@ -8628,7 +8596,7 @@ int UIItemStoreWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std:
if (this->tabs[7]->geometry.unknown_0030 != 0) {
this->unknown_0120[7] = nullptr;
this->unknown_0120[7] = g_windowMgr.sub_A978D0(309);
this->unknown_0120[7] = g_windowMgr.EnsureWindow(309);
if (this->unknown_0120[7]) {
this->unknown_0120[7]->SendMsg(nullptr, 23, 0, 0, 0, 0);
}
@ -8644,7 +8612,7 @@ int UIItemStoreWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std:
break;
case 133:
if (!this->unknown_0140) {
this->unknown_0140 = g_windowMgr.sub_A978D0(153);
this->unknown_0140 = g_windowMgr.EnsureWindow(153);
std::string text(this->searchEdit->Text());
if (!text.empty() && reinterpret_cast<UIItemStoreSubWnd*>(this)->FilterByName3(std::string(text.c_str(), text.size()))) {
static_cast<UIItemStoreFindWnd*>(this->unknown_0140)->SetSearchText(std::string(text.c_str(), text.size()));
@ -11516,7 +11484,7 @@ int UIMerchantShopMakeWnd::SendMsg(UIWindow* sender, int message, std::intptr_t
std::memcpy(&header, data + offset, sizeof(header));
offset += 6;
if (header.type == 21301 || header.type == 21351) {
UIWindow* window = g_windowMgr.sub_A978D0(header.type == 21301 ? 42 : 175);
UIWindow* window = g_windowMgr.EnsureWindow(header.type == 21301 ? 42 : 175);
if (window) {
window->SendMsg(nullptr, 23, 0, 0, 0, 0);
}
@ -11532,7 +11500,7 @@ int UIMerchantShopMakeWnd::SendMsg(UIWindow* sender, int message, std::intptr_t
g_session.m_skipPriceWarning = !g_session.m_skipPriceWarning;
} else if (a == 343) {
if (!g_windowMgr.LookupWindow(333)) {
g_windowMgr.sub_A978D0(333);
g_windowMgr.EnsureWindow(333);
}
} else if (a == 560) {
this->unknown_0168->SetDisabled(1);

View file

@ -65,6 +65,11 @@ int UIEntryQueueHelpWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a,
__declspec(noinline) UIEntryQueueListBox::UIEntryQueueListBox() : UIListBox() {
}
// INLINED
UIEntryQueueListBox::~UIEntryQueueListBox() {
}
// OFFSET: 0x00BA4490
// FUNCTION: fn_19686
void UIEntryQueueListBox::AddEntry(const char* name, int value) {
@ -99,6 +104,11 @@ UIEntryQueueRequestWnd::UIEntryQueueRequestWnd()
: UIFrameWnd(0), m_interval(1000), m_elapsed(0), m_delta(0), m_lastTick(0) {
}
// INLINED
UIEntryQueueRequestWnd::~UIEntryQueueRequestWnd() {
}
// OFFSET: 0x00BA48E0
// FUNCTION: fn_19691
bool UIEntryQueueRequestWnd::Create() {
@ -225,6 +235,11 @@ UIEntryQueueStandByWnd::UIEntryQueueStandByWnd()
m_rankingText() {
}
// INLINED
UIEntryQueueStandByWnd::~UIEntryQueueStandByWnd() {
}
// OFFSET: 0x00BA5700
// FUNCTION: fn_19698
bool UIEntryQueueStandByWnd::Create() {
@ -329,6 +344,11 @@ UIEntryQueueWnd::UIEntryQueueWnd() : UIFrameWnd(0) {
std::memset(this->m_values, 0, sizeof(this->m_values));
}
// INLINED
UIEntryQueueWnd::~UIEntryQueueWnd() {
}
// OFFSET: 0x00BA6410
// FUNCTION: fn_19706
int UIEntryQueueWnd::SelectedIndex() {

View file

@ -11,10 +11,6 @@
template <>
CUIRegisterMgr* Singleton<CUIRegisterMgr>::s_instance = nullptr;
__declspec(noinline) CUIRegisterMgr::CUIRegisterMgr() {
InitializeCriticalSection(&this->lock);
}
// OFFSET: 0x009E69D0
// FUNCTION: fn_14469
CUIFrameWnd::~CUIFrameWnd() {

View file

@ -98,8 +98,6 @@ std::map<int, int> g_optionHotkeys;
// GLOBAL: gl_25229
bool g_restartClient;
RenderAdapter sub_56A0F0();
// OFFSET: 0x00A3D0A0
// FUNCTION: fn_15905
RenderAdapter::RenderAdapter() : backend(0), ordinal(0), drawGuid{}, renderGuid{}, deviceGuid{} {
@ -795,6 +793,33 @@ void CUIListBoxEx<GameSettingsUI::CUIComboItem, std::string>::AddNewItem() {
this->scrollBar->SetVisible(this->geometry.height);
}
// INLINED
template <>
void CUIListBoxEx<GameSettingsUI::CUIOptionItem, TALKTYPE>::SelectItem(CUIListItem* item) {
if (this->unknown_00C4) {
return;
}
for (GameSettingsUI::CUIOptionItem* other : this->items) {
if (item != other) {
other->SetSelected(0);
}
}
item->SetSelected(1);
if (item->index == static_cast<int>(this->selected) && this->unknown_00E0) {
return;
}
GameSettingsUI::CUIOptionItem* selectedItem = dynamic_cast<GameSettingsUI::CUIOptionItem*>(item);
if (!selectedItem) {
return;
}
this->selected = selectedItem->index;
if (this->onSelect && static_cast<int>(this->selected) >= 0 && this->selected < this->data.size()) {
auto node = this->data.begin();
std::advance(node, static_cast<int>(this->selected));
this->onSelect(selectedItem, *node);
}
}
// OFFSET: 0x00A35170
// FUNCTION: fn_15425
template <>
@ -2063,7 +2088,7 @@ void GameSettingsUI::CUIGroupTextureDetailLevel::Slot16() {
void ToggleGameSettingsTab4() {
UIWindow* window = g_windowMgr.LookupWindow(0x271E);
if (!window) {
window = g_windowMgr.sub_A978D0(0x271E);
window = g_windowMgr.EnsureWindow(0x271E);
}
CUIGameSettingsUI* settings = static_cast<CUIGameSettingsUI*>(window);
@ -2223,7 +2248,7 @@ void GameSettingsUI::CUIGroupGraphics::Slot16() {
const char* modeText = LookupMessage(0xc6e);
this->m_modeText->SetText(modeText, std::strlen(modeText));
GetRenderSystemHolder();
this->m_pendingAdapter = sub_56A0F0();
this->m_pendingAdapter = SelectedRenderAdapter();
this->m_adapter = this->m_pendingAdapter;
DisplayMode mode{};
mode.width = g_configuredScreenWidth;
@ -2425,7 +2450,7 @@ void GameSettingsUI::CUIGroupSound::Apply() {
// OFFSET: 0x00A19C60
// FUNCTION: fn_15346
CUIButton::CUIButton() : CUIControl(), state(0), disabled(0), tooltip(), unknown_00C4(nullptr), unknown_00EC(nullptr) {
inline CUIButton::CUIButton() : CUIControl(), state(0), disabled(0), tooltip(), unknown_00C4(nullptr), unknown_00EC(nullptr) {
}
// OFFSET: 0x00A19D30

View file

@ -237,12 +237,12 @@ int UIGuildHelperWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a1, s
break;
case 343:
if (!g_windowMgr.CloseWindow(214)) {
g_windowMgr.sub_A978D0(214);
g_windowMgr.EnsureWindow(214);
}
break;
case 448:
if (!g_windowMgr.CloseWindow(213)) {
g_windowMgr.sub_A978D0(213);
g_windowMgr.EnsureWindow(213);
if (g_windowMgr.unknown_0438) {
int x = 0;
int y = 0;

View file

@ -43,16 +43,6 @@ template void CUIListBoxEx<EquipmentPropertiesWnd::CUIItemEquipmentPropertiesLin
template void CUIListBoxEx<EquipmentPropertiesWnd::CUIItemEquipmentPropertiesLine, std::string>::Slot35(int);
template void CUIListBoxEx<EquipmentPropertiesWnd::CUIItemEquipmentPropertiesLine, std::string>::ClearItems();
void CUIListItem::SetImageResources(CBitmapRes* normal, CBitmapRes* hover, CBitmapRes* pressed, CBitmapRes* disabled) {
auto& images = *reinterpret_cast<std::map<int, CBitmapRes*>*>(reinterpret_cast<std::uint8_t*>(this) + 0x80);
images.clear();
images[0] = normal;
images[1] = hover;
images[2] = pressed;
this->disabledImage = disabled;
this->Invalidate();
}
// OFFSET: 0x00A0EBF0
// FUNCTION: fn_15152
EquipmentPropertiesWnd::CUIItemEquipmentPropertiesLine::CUIItemEquipmentPropertiesLine()

View file

@ -75,6 +75,11 @@ void CMergeItemWnd::SelectSameItems(int id) {
}
}
// INLINED
CMergeItemWnd::~CMergeItemWnd() {
}
// OFFSET: 0x007DF3D0
// FUNCTION: fn_09663
int CMergeItemWnd::ItemIdOf(int id) {

View file

@ -122,7 +122,7 @@ void UISwapEquipmentWnd::sub_82FD90() {
const int row = slot & 3;
if (slot < 8) {
const int iconY = row * 26 + 48;
this->sub_8A8EE0(xCoords[slot / 4 + 2], iconY, &item, 0);
DrawItemIcon(*this, ResourceMgr::Instance(), xCoords[slot / 4 + 2], iconY, item, 0);
this->DrawItemName(xCoords[slot / 4], yCoords[row], 70, &item, 0, 0, 12);
if (item.unknown_0088 > 0) {
CBitmapRes* gradeBitmap = static_cast<CBitmapRes*>(
@ -131,7 +131,7 @@ void UISwapEquipmentWnd::sub_82FD90() {
this->DrawBitmap(xCoords[slot / 4 + 2], iconY + 12, gradeBitmap ? &gradeBitmap->image : nullptr, true);
}
} else {
this->sub_8A8EE0(xCoords[row + 2], 22, &item, 0);
DrawItemIcon(*this, ResourceMgr::Instance(), xCoords[row + 2], 22, item, 0);
this->DrawItemName(xCoords[slot - 8], 30, 70, &item, 0, 0, 12);
}
} else {
@ -367,7 +367,7 @@ void UISwapEquipmentWnd::Paint() {
if (g_session.unknown_7EC8 != 0) {
ITEM_INFO dragItem = LookupClientItemByIdentity(g_session.m_inventoryItems, g_session.unknown_7EC8);
if (dragItem.unknown_0000[1] > 0) {
this->sub_8A8EE0(this->geometry.width / 2 - 24, 27, &dragItem, 0);
DrawItemIcon(*this, ResourceMgr::Instance(), this->geometry.width / 2 - 24, 27, dragItem, 0);
this->DrawFittedItemName(this->geometry.width / 2 - 24, 51, &dragItem, 0, 0, 12, 0);
}
}

View file

@ -392,6 +392,8 @@ public:
// FUNCTION: fn_14344
// OFFSET: 0x00A06300
// FUNCTION: fn_15001
// OFFSET: 0x00A4E360
// FUNCTION: fn_16205
void UpdateScrollBar() {
this->scrollBar->SetTotal(this->data.size() * this->rowHeight + this->itemY);
this->scrollBar->SetVisible(this->geometry.height);

View file

@ -19,6 +19,10 @@
#include <cstring>
#include <windows.h>
// INLINED
UITagListBox::STagInfoV2::~STagInfoV2() {
}
// OFFSET: 0x009B7A10
// FUNCTION: fn_13869
void UITagListBox::AddLine(const char* text) {

View file

@ -543,10 +543,10 @@ void CUIProbabilityTable::OnPrepareItem(ProbabilityTable::CUIItem*, const Probab
void BindItem(ProbabilityTable::CUIItem* item, const ProbabilityTable::CItemData& data) {
item->nameText->Clear();
item->probabilityText->Clear();
item->nameText->SetText(data.name);
item->nameText->AddLine(data.name);
item->nameText->SetBackgroundColor(data.color);
item->probabilityText->SetBackgroundColor(data.color);
item->probabilityText->SetText(FormatOwnedString("%.4lf%%", data.probability));
item->probabilityText->AddLine(FormatOwnedString("%.4lf%%", data.probability));
}
// OFFSET: 0x00A493D0
@ -852,13 +852,3 @@ void CUIItem::Slot25(int, int) {
}
}
// OFFSET: 0x00A4E360
// FUNCTION: fn_16205
template <>
void CUIListBoxEx<ProbabilityTable::CUIItem, ProbabilityTable::CItemData>::UpdateScrollBar() {
this->scrollBar->SetTotal(this->data.size() * this->rowHeight + this->itemY);
this->scrollBar->SetVisible(this->geometry.height);
this->scrollBar->SetPosition(this->scrollBar->position);
this->rebind = 1;
}

View file

@ -701,6 +701,33 @@ CUIScrollWindow::CUIScrollWindow()
}
}
// INLINED
template <>
void CUIListBoxEx<OngoingQuestInfo::CUIRewardItem, OngoingQuestInfo::CRewardItemData>::SelectItem(CUIListItem* item) {
if (this->unknown_00C4) {
return;
}
for (OngoingQuestInfo::CUIRewardItem* other : this->items) {
if (item != other) {
other->SetSelected(0);
}
}
item->SetSelected(1);
if (item->index == static_cast<int>(this->selected) && this->unknown_00E0) {
return;
}
OngoingQuestInfo::CUIRewardItem* selectedItem = dynamic_cast<OngoingQuestInfo::CUIRewardItem*>(item);
if (!selectedItem) {
return;
}
this->selected = selectedItem->index;
if (this->onSelect && static_cast<int>(this->selected) >= 0 && this->selected < this->data.size()) {
auto node = this->data.begin();
std::advance(node, static_cast<int>(this->selected));
this->onSelect(selectedItem, *node);
}
}
// OFFSET: 0x00A53A90
// FUNCTION: fn_16233
template <>

View file

@ -1,4 +1,5 @@
#include "UI/Quest/UIRenewQuestUI.h"
#include "Utility/EncryptedName.h"
#include "Client/Replay.h"
#include "Contents/MessageTable.h"
#include "Contents/RenewQuestMgr.h"
@ -25,36 +26,6 @@
// GLOBAL: gl_25249
static bool s_recommendedTabFirstSelect = true;
template <std::size_t Length, std::uint64_t Key>
class EncryptedName {
public:
// INLINED
template <typename Byte>
explicit EncryptedName(const Byte (&source)[Length]) : m_encrypted(true) {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = source[index];
}
}
~EncryptedName() {
for (std::uint64_t index = 0; index < Length; ++index) {
this->m_text[index] = 0;
}
}
const char* Text() {
if (this->m_encrypted) {
utility::XorBytes(this->m_text, Length, Key);
this->m_encrypted = false;
}
return reinterpret_cast<const char*>(this->m_text);
}
private:
/* 0000 */ std::uint8_t m_text[Length];
bool m_encrypted;
};
// INLINED
template <std::uint64_t Key, std::size_t Length>
@ -78,7 +49,7 @@ const char* EncryptedName<6, 0xE33F2FF779878559ULL>::Text() {
// OFFSET: 0x00A5A010
// FUNCTION: fn_16372
template <>
const char* EncryptedName<6, 0xC70319B5EB61598FULL>::Text() {
inline const char* EncryptedName<6, 0xC70319B5EB61598FULL>::Text() {
if (this->m_encrypted) {
utility::XorBytes(this->m_text, 6, 0xC70319B5EB61598FULL);
this->m_encrypted = false;

View file

@ -85,7 +85,6 @@ public:
void OnCallback56();
void OnCallback74();
void OnCallback80();
void sub_A56050(unsigned int questId);
void sub_A67290(unsigned int flags);
void sub_A66FF0(unsigned int questId);

View file

@ -107,7 +107,7 @@ void UIRodexComposeWnd::sub_7FF710(const ITEM_INFO& item) {
tagCtrl->taggedText = this->m_contents->Text();
std::string appendResult = tagCtrl->AppendTag(item.DisplayName(0));
this->m_contents->SetText(appendResult.c_str());
this->m_contents->sub_855150();
this->m_contents->MoveCursorToEnd();
tagCtrl->sub_89CFE0(item, 0xd630a9);
}
@ -135,7 +135,7 @@ void UIRodexComposeWnd::sub_7FF940(int tagId) {
std::string fullText = std::string(this->m_contents->Text()) + tagText;
this->m_contents->SetText(fullText.c_str());
this->m_contents->sub_855150();
this->m_contents->MoveCursorToEnd();
}
// OFFSET: 0x00800480

View file

@ -27,7 +27,6 @@ class UIRodexEditCtrl3 : public UIEditCtrl3 {
public:
UIRodexEditCtrl3();
void Slot15(int width, int height) override;
void sub_855150();
};
class UIRodexComposeWnd : public UIFrameWnd {

View file

@ -161,6 +161,60 @@ void CUIListBoxEx<SelectPackageItemBox::CUITabInfo, SelectPackageItemBox::CTabIn
}
}
// INLINED
template <>
void CUIListBoxEx<SelectPackageItemBox::CUIItemInfo, ITEM_INFO>::SelectItem(CUIListItem* item) {
if (this->unknown_00C4) {
return;
}
for (SelectPackageItemBox::CUIItemInfo* other : this->items) {
if (item != other) {
other->SetSelected(0);
}
}
item->SetSelected(1);
if (item->index == static_cast<int>(this->selected) && this->unknown_00E0) {
return;
}
SelectPackageItemBox::CUIItemInfo* selectedItem = dynamic_cast<SelectPackageItemBox::CUIItemInfo*>(item);
if (!selectedItem) {
return;
}
this->selected = selectedItem->index;
if (this->onSelect && static_cast<int>(this->selected) >= 0 && this->selected < this->data.size()) {
auto node = this->data.begin();
std::advance(node, static_cast<int>(this->selected));
this->onSelect(selectedItem, *node);
}
}
// INLINED
template <>
void CUIListBoxEx<SelectPackageItemBox::CUITabInfo, SelectPackageItemBox::CTabInfoData>::SelectItem(CUIListItem* item) {
if (this->unknown_00C4) {
return;
}
for (SelectPackageItemBox::CUITabInfo* other : this->items) {
if (item != other) {
other->SetSelected(0);
}
}
item->SetSelected(1);
if (item->index == static_cast<int>(this->selected) && this->unknown_00E0) {
return;
}
SelectPackageItemBox::CUITabInfo* selectedTab = dynamic_cast<SelectPackageItemBox::CUITabInfo*>(item);
if (!selectedTab) {
return;
}
this->selected = selectedTab->index;
if (this->onSelect && static_cast<int>(this->selected) >= 0 && this->selected < this->data.size()) {
auto node = this->data.begin();
std::advance(node, static_cast<int>(this->selected));
this->onSelect(selectedTab, *node);
}
}
// OFFSET: 0x00A6D1A0
// FUNCTION: fn_16670
template <>

View file

@ -1247,7 +1247,7 @@ int UISubChatHisWnd::SendMsg(UIWindow* sender, int message, std::intptr_t argume
case 6:
switch (argument1) {
case 0xC1:
if (UIWindow* window = g_windowMgr.sub_A978D0(0x84)) {
if (UIWindow* window = g_windowMgr.EnsureWindow(0x84)) {
window->SendMsg(this, 6, 0xC1, this->m_index, 0, 0);
return 0;
}

View file

@ -1230,7 +1230,7 @@ void UIAchSummaryWnd::Slot15(int, int) {
int UIAchListWnd::SendMsg(UIWindow*, int message, std::intptr_t argument1, std::intptr_t, std::intptr_t, std::intptr_t) {
switch (message) {
case 6:
if (g_session.sub_E06580(this->ids[this->unknown_008C + argument1])) {
if (g_session.ToggleTrackedAchievement(this->ids[this->unknown_008C + argument1])) {
UIWindow* window = g_windowMgr.EnsureWindow(271);
if (window) {
window->Invalidate();
@ -1486,6 +1486,14 @@ UIAchListWnd::UIAchListWnd()
unknown_009C(0), unknown_00AC(nullptr), scrollBar(nullptr) {
}
// INLINED
UIAchListWnd::~UIAchListWnd() {
if (this->buttons) {
delete[] this->buttons;
}
}
// OFFSET: 0x007B1F40
// FUNCTION: fn_09182
UIAchScrollBar::UIAchScrollBar() : UIScrollBar() {

View file

@ -37,7 +37,6 @@ public:
void SetScrollBarThumbImages(const std::string& top, const std::string& middle, const std::string& bottom);
void SetScrollBarThumbImage(const std::string& name);
void SetScrollBarBackground(const std::string& name);
void SetText(const std::string& text);
void Clear();
void AddLine(const std::string& text);
void Relayout();

View file

@ -109,7 +109,7 @@ __forceinline void UITextViewer::Activate(UITextButton* button, int id) {
item.unknown_0060 = 0;
item.itemId = button->GetLine(0);
if (UIWindow* window = g_windowMgr.sub_A978D0(12)) {
if (UIWindow* window = g_windowMgr.EnsureWindow(12)) {
window->SendMsg(nullptr, 24, reinterpret_cast<std::intptr_t>(&item), 0, 0, 0);
}
@ -119,7 +119,7 @@ __forceinline void UITextViewer::Activate(UITextButton* button, int id) {
if (button && button->GetLinesCount() != 0) {
const std::string& tip = button->GetLine(0);
if (UIWindow* window = g_windowMgr.sub_A978D0(315)) {
if (UIWindow* window = g_windowMgr.EnsureWindow(315)) {
static_cast<UITipboxWnd*>(window)->ShowTip(std::atoi(tip.c_str()));
}
}
@ -362,7 +362,7 @@ int UITextViewer::SendMsg(UIWindow* sender, int message, std::intptr_t argument1
item.unknown_0000[0] = static_cast<unsigned>(idValue);
item.unknown_0060 = 0;
item.itemId = button->GetLine(0);
if (UIWindow* window = g_windowMgr.sub_A978D0(12)) {
if (UIWindow* window = g_windowMgr.EnsureWindow(12)) {
window->SendMsg(nullptr, 24, reinterpret_cast<std::intptr_t>(&item), 0, 0, 0);
}
}
@ -370,7 +370,7 @@ int UITextViewer::SendMsg(UIWindow* sender, int message, std::intptr_t argument1
case 517:
if (button && button->GetLinesCount() != 0) {
const std::string& tip = button->GetLine(0);
if (UIWindow* window = g_windowMgr.sub_A978D0(315)) {
if (UIWindow* window = g_windowMgr.EnsureWindow(315)) {
static_cast<UITipboxWnd*>(window)->ShowTip(std::atoi(tip.c_str()));
}
}

View file

@ -95,7 +95,7 @@ void UIBroadcastBalloon::Paint() {
DrawRoundedBorder(*this, x, y, message.width, message.height, 0xFF5C5C5C);
y += 4;
for (const BroadcastBalloonLine& line : message.lines) {
this->sub_A86510(x + 6, y, line.text.c_str(), 0, line.color, line.outlineColor, 0, message.fontHeight, 0);
this->DrawShadowedText(x + 6, y, line.text.c_str(), 0, line.color, line.outlineColor, 0, message.fontHeight, 0);
int lineHeight = this->TextHeight(line.text.c_str(), 0, 0, message.fontHeight, 0, 0);
y += 4 + lineHeight;
}

View file

@ -36,10 +36,6 @@ public:
void Slot43() override;
void AddMessage(int category, const BroadcastBalloonMessage& message);
void sub_A86510(
int x, int y, const char* text, int bytes, std::uint32_t color, std::uint32_t outline, int family, int height,
unsigned char bold
);
protected:
/* 007C */ std::map<int, std::list<BroadcastBalloonMessage>> m_messages;

View file

@ -115,16 +115,16 @@ void UICaptchaPreviewWnd::Paint() {
// OFFSET: 0x007ED960
// FUNCTION: fn_09813
void UIMacroDetectorWnd::Paint() {
this->sub_8D2CE0(false, "", 0);
this->DrawTitleBar(false, "", 0);
this->DrawButtonBar(0, 0, 1);
this->FillRegion(0, 16, this->geometry.width, this->geometry.height - 36, 0xFFFFFFFF);
DrawRectangleBorder(*this, 0, 16, this->geometry.width, this->geometry.height - 36, 0xC6C6C6);
this->sub_A84360(25, 28, LookupMessage(2883), 0, 0, 12, 0, 1, 0);
this->sub_A84360(25, 45, LookupMessage(2884), 0, 0, 12, 0, 1, 0);
this->sub_A84360(25, 62, LookupMessage(2885), 0, 0, 12, 0, 1, 0);
this->DrawTextAt(25, 28, LookupMessage(2883), 0, 0, 12, 0, 1, 0);
this->DrawTextAt(25, 45, LookupMessage(2884), 0, 0, 12, 0, 1, 0);
this->DrawTextAt(25, 62, LookupMessage(2885), 0, 0, 12, 0, 1, 0);
this->sub_A84360(25, 82, this->message.c_str(), 0, 0, 12, 0x2323FF, 1, 0);
this->DrawTextAt(25, 82, this->message.c_str(), 0, 0, 12, 0x2323FF, 1, 0);
this->FillRegion(59, 158, 222, 92, 0xC6C6C6);
this->FillRegion(60, 97, 220, 30, 0xC6C6C6);
@ -138,11 +138,11 @@ void UIMacroDetectorWnd::Paint() {
unsigned int seconds = remaining / 1000;
{
std::string str = FormatOwnedString("%2d : %2d", seconds / 60, seconds);
this->sub_A86440(280, 138, str.c_str(), 0, 0, 13, 0xFF2323, 1);
this->DrawRightAlignedText(280, 138, str.c_str(), 0, 0, 13, 0xFF2323, 1);
}
{
std::string str = FormatOwnedString(LookupMessage(2886), this->unknown_00D0);
this->sub_A84360(60, 138, str.c_str(), 0, 0, 13, 0x2323FF, 1, 0);
this->DrawTextAt(60, 138, str.c_str(), 0, 0, 13, 0x2323FF, 1, 0);
}
}
}

View file

@ -43,8 +43,8 @@ UICaptchaRegisterWnd::UICaptchaRegisterWnd()
// OFFSET: 0x007EA3B0
// FUNCTION: fn_09788
void UICaptchaRegisterWnd::Slot15(int width, int height) {
this->sub_8CEF10();
this->sub_8CF0C0("", 0);
this->AddBaseButton();
this->AddCloseButton("", 0);
std::string directory = FormatOwnedString("%s\\captcha\\", g_applicationDirectory);

View file

@ -19,8 +19,6 @@ public:
int SendMsg(UIWindow* sender, int message, std::intptr_t a1, std::intptr_t a2, std::intptr_t a3, std::intptr_t a4) override;
void SetRegisterDisabled(unsigned char disabled);
void sub_8CEF10();
void sub_8CF0C0(const char* tooltip, int width);
/* 00B4 */ UIStaticText* m_pathText;
/* 00B8 */ UIComboBoxDefWnd* m_fileComboBox;

View file

@ -48,6 +48,11 @@ UICheckAttendanceWnd::UICheckAttendanceWnd()
this->m_rewardCount = static_cast<int>(g_checkAttendanceMgr->m_rewards.size());
}
// INLINED
UICheckAttendanceWnd::~UICheckAttendanceWnd() {
}
// OFFSET: 0x007DCBD0
// FUNCTION: fn_09636
void UICheckAttendanceWnd_Banner::AddBanner(std::string image, std::string url, int action, int argument) {
@ -95,6 +100,11 @@ UICheckAttendanceWnd_Banner::UICheckAttendanceWnd_Banner()
: UIWindow(0), m_current(0), m_lastSwitch(timeGetTime()) {
}
// INLINED
UICheckAttendanceWnd_Banner::~UICheckAttendanceWnd_Banner() {
}
// OFFSET: 0x007DCF50
// FUNCTION: fn_09639
void UICheckAttendanceWnd::Slot15(int, int) {

View file

@ -1,4 +1,5 @@
#include "UI/Window/UINewSelectCharWnd.h"
#include "UI/Shop/ItemDrawing.h"
#include "UI/UIGradeEnchantWnd.h"
#include "Client/Mode/CMode.h"
@ -250,7 +251,7 @@ void UIGradeEnchantWnd::Paint() {
ITEM_INFO itemInfo;
itemInfo.SetItemId(material.itemId);
itemInfo.sub_6D5810(description, capacity, 0);
this->sub_8A8EE0(170, y - 9, &itemInfo, 0);
DrawItemIcon(*this, ResourceMgr::Instance(), 170, y - 9, itemInfo, 0);
std::string text = FormatOwnedString(LookupMessage(3553), description, material.amount);
this->sub_A85850(203, y, text, 180, 0, 0, 0, 0, 11, 0, 0);
y += 40;
@ -260,7 +261,7 @@ void UIGradeEnchantWnd::Paint() {
ITEM_INFO itemInfo;
itemInfo.SetItemId(this->info.unknown_0000);
itemInfo.sub_6D5810(description, capacity, 0);
this->sub_8A8EE0(195, 228, &itemInfo, 0);
DrawItemIcon(*this, ResourceMgr::Instance(), 195, 228, itemInfo, 0);
std::string text = FormatOwnedString(LookupMessage(3553), description, this->unknown_0114);
this->sub_A85850(228, 237, text, 160, 0, 0xFFFFFF, 0, 0, 11, 1, 1);
}
@ -292,7 +293,7 @@ void UIGradeEnchantWnd::Paint() {
}
if (this->item.unknown_0000[1] > 0) {
this->sub_8A8EE0(64, 125, &this->item, 0);
DrawItemIcon(*this, ResourceMgr::Instance(), 64, 125, this->item, 0);
if (this->item.unknown_0088 > 0) {
this->DrawBitmap(64, 137, reinterpret_cast<const BitmapImage*>(ResourceMgr::Instance().Load(Resolve(FormatOwnedString("유저인터페이스\\grade_enchant\\grade_icon%d.bmp", this->item.unknown_0088).c_str()))), true);
}

View file

@ -283,7 +283,7 @@ int UIHotkeyGuideWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, st
if (message == 6) {
switch (a) {
case 342: {
UIWindow* window = g_windowMgr.sub_A978D0(156);
UIWindow* window = g_windowMgr.EnsureWindow(156);
if (window) {
window->SendMsg(this, 22, 1, 0, 0, 0);
}

View file

@ -21,9 +21,6 @@ public:
void Slot31(int x, int y) override;
int SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) override;
void sub_8D2CE0(bool closeButton, const char* title, int width);
void sub_A84360(int x, int y, const char* text, int bytes, int family, int height, std::uint32_t color, unsigned char bold, unsigned char italic);
void sub_A86440(int right, int y, const char* text, int bytes, int family, int height, std::uint32_t color, unsigned char bold);
void AddImageData(const void* data, int size);
void ClearImageData();
void SetCountdown(unsigned char count, std::uint32_t duration);

View file

@ -12,6 +12,7 @@
#include "UI/Lists/UIComboBoxEx.h"
#include "UI/Window/WindowBorder.h"
#include "UI/Window/WindowManagerWindows.h"
#include "Utility/JsonCppLoader.h"
#include "Utility/Text/FormatString.h"
#include <algorithm>

View file

@ -36,7 +36,5 @@ public:
std::vector<const ReputeInfo*> m_reputes;
};
#include "Contents/ReputeMgrLoad.inl"
#endif

View file

@ -891,7 +891,7 @@ int UIChatRoomWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::
return 0;
}
case 2:
g_windowMgr.sub_A978D0(30)->SendMsg(nullptr, 34, reinterpret_cast<std::intptr_t>(&mode->unknown_03C8), 0, 0, 0);
g_windowMgr.EnsureWindow(30)->SendMsg(nullptr, 34, reinterpret_cast<std::intptr_t>(&mode->unknown_03C8), 0, 0, 0);
return 0;
case 3:
g_windowMgr.Confirm(LookupMessage(191), 0, true, false, 0, "Message", 280, 120, 0);
@ -962,7 +962,7 @@ int UIChatRoomWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::
}
if (!this->unknown_0114.empty()) {
UIWindow* menu = g_windowMgr.sub_A978D0(18);
UIWindow* menu = g_windowMgr.EnsureWindow(18);
for (unsigned index = 0; index < this->unknown_0114.size(); ++index) {
menu->SendMsg(nullptr, 31, reinterpret_cast<std::intptr_t>(this->unknown_0114[index].first.c_str()), 0, 0, 0);
}

View file

@ -19,7 +19,6 @@ public:
CUIFrameWnd* Create(int key);
void Load();
bool SaveTemporary();
void sub_9EB920();
/* 0004 */ std::map<int, std::function<CUIFrameWnd*()>> entries;
/* 000C */ std::map<int, std::pair<int, int>> unknown_000C;

View file

@ -756,7 +756,7 @@ int UIRoMapWnd::SendMsg(UIWindow* sender, int message, std::intptr_t argument1,
this->Invalidate();
return 0;
case 200:
g_windowMgr.sub_A978D0(203);
g_windowMgr.EnsureWindow(203);
if (g_windowMgr.window_4F174) {
g_windowMgr.window_4F174->SendMsg(nullptr, 6, 200, 0, 0, 0);
}

Some files were not shown because too many files have changed in this diff Show more