Decompile 3 functions in Source/UI/Window/UISeekPartyListWnd.cpp, Source/UI/Window/UISeekPartyListWnd.h, ...

Batch #3206 by eAthena: 0 byte-identical, 3 confirmed by peer review.

- fn_12815 UISeekPartyListWnd::NotifyNewAd: logic confirmed by peer review
- fn_12825 UISeekPartyListWnd::MatchesFilter: logic confirmed by peer review
- fn_18448 PartyBookingMgr::OnAdvertisement: logic confirmed by peer review

Peer-reviewed-by: meitogi, alisonrag, superintelligence
Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
Adds to the build: Source/UI/Window/UISeekPartyListWnd.cpp
This commit is contained in:
ragnarok-clanker 2026-10-29 21:49:06 +00:00
commit b85cc9c7b4
6 changed files with 135 additions and 15 deletions

View file

@ -0,0 +1,21 @@
#ifndef RAGNAROK_SOURCE_CONTENTS_PARTY_PARTYBOOKINGINFO_H
#define RAGNAROK_SOURCE_CONTENTS_PARTY_PARTYBOOKINGINFO_H
#include <ctime>
struct PARTY_BOOKING_DETAIL {
/* 0000 */ short level;
/* 0002 */ short mapId;
/* 0004 */ short job[6];
};
struct PARTY_BOOKING_AD_INFO {
/* 0000 */ int index;
/* 0004 */ char charName[24];
/* 001C */ __time32_t expireTime;
/* 0020 */ PARTY_BOOKING_DETAIL detail;
};
static_assert(sizeof(PARTY_BOOKING_AD_INFO) == 0x30);
#endif

View file

@ -2,6 +2,9 @@
#include "Client/Session.h"
#include "Contents/MessageTable.h"
#include "Contents/Sound/SoundMgr.h"
#include "UI/Window/UISeekPartyListWnd.h"
#include "UI/Window/UIWindowMgr.h"
#include <cstdio>
#include <cstring>
@ -24,6 +27,52 @@ void PartyBookingMgr::Clear() {
// OFFSET: 0x00B16CF0
// OFFSET: 0x00B175B0
// FUNCTION: fn_18448
void PartyBookingMgr::OnAdvertisement(PARTY_BOOKING_AD_INFO info) {
UISeekPartyListWnd* window = static_cast<UISeekPartyListWnd*>(g_windowMgr.LookupWindow(0xA9));
if (window) {
if (window->MatchesFilter(info)) {
if (!this->m_lastPage) {
this->AddEntries(&info, 1, false);
window->NotifyNewAd();
} else {
std::pair<bool, PartyBookingEntry> result = this->MakeEntry(info);
if (result.first) {
this->m_pending.insert(std::pair<const int, PartyBookingEntry>(info.index, result.second));
}
window->NotifyNewAd();
}
}
return;
}
if (this->m_filterEnabled) {
PARTY_BOOKING_AD_INFO ad = info;
if (this->m_filterLevel > 0 && (ad.detail.level < this->m_filterLevel || this->m_filterLevel + 15 < ad.detail.level)) {
return;
}
if (this->m_filterMap > 0 && this->m_filterMap != ad.detail.mapId) {
return;
}
if (this->m_filterJob > 0) {
int i = 0;
while (this->m_filterJob != ad.detail.job[i]) {
if (++i >= 6) {
return;
}
}
}
}
if (this->m_alarm) {
g_soundMgr->PlayWave("party_alarm.wav", 0.0f, 0.0f, 0.0f, 250, 40, 1.0f, 0);
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(LookupMessage(0x6D9)), 0xFFFF00, 15, 0, 0);
}
}
// OFFSET: 0x00B17820
// OFFSET: 0x00B17C40

View file

@ -1,6 +1,8 @@
#ifndef RAGNAROK_SOURCE_CONTENTS_PARTY_PARTYBOOKINGMGR_H
#define RAGNAROK_SOURCE_CONTENTS_PARTY_PARTYBOOKINGMGR_H
#include "Contents/Party/PartyBookingInfo.h"
#include <cstddef>
#include <ctime>
#include <map>
@ -8,21 +10,6 @@
#include <utility>
#include <vector>
struct PARTY_BOOKING_DETAIL {
/* 0000 */ short level;
/* 0002 */ short mapId;
/* 0004 */ short job[6];
};
struct PARTY_BOOKING_AD_INFO {
/* 0000 */ int index;
/* 0004 */ char charName[24];
/* 001C */ __time32_t expireTime;
/* 0020 */ PARTY_BOOKING_DETAIL detail;
};
static_assert(sizeof(PARTY_BOOKING_AD_INFO) == 0x30);
struct PartyBookingMapInfo {
/* 0000 */ std::string name;
/* 0018 */ int id;
@ -54,6 +41,7 @@ public:
void SetJobs(int index, const short* jobs);
bool FlushPending();
void AddEntries(const PARTY_BOOKING_AD_INFO* infos, int count, bool more);
void OnAdvertisement(PARTY_BOOKING_AD_INFO info);
std::pair<bool, PartyBookingEntry> MakeEntry(PARTY_BOOKING_AD_INFO info);
/* 0000 */ int unknown_0000;

View file

@ -0,0 +1,38 @@
#include "UI/Window/UISeekPartyListWnd.h"
#include "Contents/MessageTable.h"
#include "Contents/Sound/SoundMgr.h"
#include "UI/Buttons/UICheckBox.h"
#include "UI/Window/UIWindowMgr.h"
// OFFSET: 0x009431D0
// FUNCTION: fn_12815
void UISeekPartyListWnd::NotifyNewAd() {
if (this->m_alarmCheck->geometry.unknown_0030 != 0) {
g_soundMgr->PlayWave("party_alarm.wav", 0.0f, 0.0f, 0.0f, 250, 40, 1.0f, 0);
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(LookupMessage(0x6D9)), 0xFFFF00, 15, 0, 0);
}
}
// OFFSET: 0x009435F0
// FUNCTION: fn_12825
bool UISeekPartyListWnd::MatchesFilter(PARTY_BOOKING_AD_INFO info) {
if (this->m_filterLevel > 0 && (this->m_filterLevel > info.detail.level || this->m_filterLevel + 15 < info.detail.level)) {
return false;
}
if (this->m_filterMap > 0 && this->m_filterMap != info.detail.mapId) {
return false;
}
if (this->m_filterJob > 0) {
for (int i = 0; i < 6; ++i) {
if (this->m_filterJob == info.detail.job[i]) {
return true;
}
}
return false;
}
return true;
}

View file

@ -0,0 +1,23 @@
#ifndef RAGNAROK_SOURCE_UI_WINDOW_UISEEKPARTYLISTWND_H
#define RAGNAROK_SOURCE_UI_WINDOW_UISEEKPARTYLISTWND_H
#include "Contents/Party/PartyBookingInfo.h"
#include "UI/Window/UIFrameWnd.h"
class UICheckBox;
class UISeekPartyListWnd : public UIFrameWnd {
public:
void NotifyNewAd();
bool MatchesFilter(PARTY_BOOKING_AD_INFO info);
protected:
/* 00B4 */ unsigned char unknown_00B4[0x3C];
/* 00F0 */ UICheckBox* m_alarmCheck;
/* 00F4 */ unsigned char unknown_00F4[0xD0];
/* 01C4 */ short m_filterLevel;
/* 01C6 */ short m_filterMap;
/* 01C8 */ short m_filterJob;
};
#endif

View file

@ -757,6 +757,7 @@
"Source/UI/Window/UIControl.cpp": 2,
"Source/UI/Window/UIFrameWnd.cpp": 2,
"Source/UI/Window/UIMessageBox.cpp": 2,
"Source/UI/Window/UISeekPartyListWnd.cpp": 2,
"Source/UI/Window/UIWindow.cpp": 2,
"Source/UI/Window/UIWindowMgr.cpp": 2,
"Source/UI/Window/WindowAncestry.cpp": 2,