Batch #6824 by bigodeira: 0 byte-identical, 4 confirmed by peer review. - fn_09839 UIMacroReporterWnd::sub_7EF2C0: logic confirmed by peer review - fn_09840 UIMacroReporterWnd::sub_7EF2E0: logic confirmed by peer review - fn_09841 UIMacroReporterWnd::sub_7EF430: logic confirmed by peer review - fn_09843 UIMacroReporterWnd::ValidateNames: logic confirmed by peer review Peer-reviewed-by: eAthena, superintelligence, Tanke Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
386 lines
11 KiB
C++
386 lines
11 KiB
C++
#include "UI/UIMacroUserInfoWnd.h"
|
|
|
|
#include "Client/Mode/CGameMode.h"
|
|
#include "Client/Mode/ModeMgr.h"
|
|
#include "Client/Session.h"
|
|
#include "Contents/Actors/GameActor.h"
|
|
#include "Client/Mode/CGameMode.h"
|
|
#include "Client/Mode/ModeMgr.h"
|
|
#include "Client/Session.h"
|
|
#include "Contents/Actors/GameActor.h"
|
|
#include "Contents/MapInfoMgr.h"
|
|
#include "Contents/MessageTable.h"
|
|
#include "Contents/World/World.h"
|
|
#include "Network/Connection/Connection.h"
|
|
#include "Network/Packets/PacketLengths.h"
|
|
#include "Contents/World/World.h"
|
|
#include "Network/Connection/Connection.h"
|
|
#include "Network/Packets/PacketLengths.h"
|
|
#include "UI/Buttons/UIBitmapButton.h"
|
|
#include "UI/Buttons/UIButton.h"
|
|
#include "UI/Buttons/UITextButton.h"
|
|
#include "UI/Layout/SnapMgr.h"
|
|
#include "UI/Layout/WindowSnapping.h"
|
|
#include "UI/Lists/UIScrollBar.h"
|
|
#include "UI/Window/FrameFocus.h"
|
|
#include "UI/Window/UIWindowMgr.h"
|
|
#include "UI/Window/WindowBorder.h"
|
|
#include "Utility/Text/FormatString.h"
|
|
|
|
#include <algorithm>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
|
|
// OFFSET: 0x007EE980
|
|
// FUNCTION: fn_09831
|
|
MacroReporterEntry::MacroReporterEntry(std::string name, int id, short unknown_001C)
|
|
: name(name), id(id), unknown_001C(unknown_001C) {}
|
|
|
|
// OFFSET: 0x007EF2C0
|
|
// FUNCTION: fn_09839
|
|
void UIMacroReporterWnd::sub_7EF2C0(MacroReporterEntry* entry) {
|
|
if (entry) {
|
|
this->sub_7EF2E0(entry->id);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x007EF2E0
|
|
// FUNCTION: fn_09840
|
|
void UIMacroReporterWnd::sub_7EF2E0(int aid) {
|
|
CGameMode* mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
|
|
CGameActor* actor = static_cast<CGameActor*>(mode->scene->GetGameActorByAID(aid));
|
|
if (!actor) {
|
|
return;
|
|
}
|
|
|
|
if (!g_session.IsPlayerJobId(actor->GetEffectiveJob(-1))) {
|
|
return;
|
|
}
|
|
|
|
mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
|
|
std::string name = mode->ActorName(aid);
|
|
|
|
for (auto it = this->m_entries.begin(); it != this->m_entries.end(); ++it) {
|
|
if (it->id == aid) {
|
|
goto found;
|
|
}
|
|
}
|
|
|
|
this->m_entries.push_back(MacroReporterEntry(name, aid, static_cast<short>(actor->GetEffectiveJob(-1))));
|
|
|
|
found:
|
|
this->sub_7EF430(aid, name);
|
|
this->UpdateScrollBar();
|
|
}
|
|
|
|
struct AccessibleButton : public UIButton {
|
|
using UIButton::m_argument;
|
|
};
|
|
|
|
struct AccessibleTextButton : public UITextButton {
|
|
using UITextButton::m_hoverColor;
|
|
};
|
|
|
|
// OFFSET: 0x007EF430
|
|
// FUNCTION: fn_09841
|
|
void UIMacroReporterWnd::sub_7EF430(int aid, std::string name) {
|
|
for (std::size_t i = 0; i < this->m_rows.size(); ++i) {
|
|
if (this->m_rows[i].second->geometry.id == aid) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
auto* btn1 = new UIBitmapButton();
|
|
btn1->SetBitmap("유저인터페이스\\basic_interface\\que_close_on.bmp", 0, 0);
|
|
btn1->SetBitmap("유저인터페이스\\basic_interface\\que_close_off.bmp", 1, 0);
|
|
btn1->SetBitmap("유저인터페이스\\basic_interface\\que_close_off.bmp", 2, 0);
|
|
btn1->SetSize(btn1->BitmapWidth(), btn1->BitmapHeight());
|
|
btn1->SetId(211);
|
|
reinterpret_cast<AccessibleButton*>(btn1)->m_argument = aid;
|
|
btn1->Enable(0);
|
|
this->AddChild(btn1);
|
|
|
|
std::string truncated = this->sub_7EF680(0x8E, name.c_str(), 0, 13, 0);
|
|
auto* btn2 = new UITextButton(*this->m_context, *this->m_controls);
|
|
btn2->Configure("", 0, 0, 13, 0, 1);
|
|
static_cast<AccessibleTextButton*>(btn2)->m_hoverColor = 0x2D2D2D;
|
|
btn2->label = truncated;
|
|
btn2->ResizeToText();
|
|
btn2->SetTooltip(name.c_str());
|
|
btn2->SetId(aid);
|
|
btn2->Enable(0);
|
|
this->AddChild(btn2);
|
|
|
|
this->m_rows.push_back(std::make_pair(btn1, btn2));
|
|
}
|
|
|
|
// OFFSET: 0x007EF680
|
|
|
|
// OFFSET: 0x007F0480
|
|
// FUNCTION: fn_09845
|
|
bool UIMacroUserInfoWnd::Slot08() {
|
|
return true;
|
|
}
|
|
|
|
// OFFSET: 0x007F0EE0
|
|
// FUNCTION: fn_09847
|
|
void UIMacroUserInfoWnd::Slot15(int, int) {
|
|
this->AddCloseButton(*this->m_controls, "", 0);
|
|
}
|
|
|
|
// OFFSET: 0x007F0EF0
|
|
// FUNCTION: fn_09848
|
|
void UIMacroReporterWnd::Paint() {
|
|
if (this->m_mode == 0 || this->m_mode == 1) {
|
|
this->m_reportButton->SetDisabled(this->m_entries.empty());
|
|
this->m_reportButton->Invalidate();
|
|
} else if (this->m_mode == 2 || this->m_mode == 3) {
|
|
this->m_reportButton->SetDisabled(!(this->m_namesValid == 1 && this->m_targetValid == 1));
|
|
this->m_reportButton->Invalidate();
|
|
}
|
|
|
|
DrawFilledRoundedBorder(*this, 0, 0, this->geometry.width, this->geometry.height, 0xFFFFFFFF);
|
|
this->DrawTitleBar(this->m_controls->fonts, this->m_controls->locale, true, "", 0);
|
|
this->DrawButtonBar(1, 0, 1);
|
|
|
|
if (this->m_mode != 0 && this->m_mode != 1) {
|
|
return;
|
|
}
|
|
|
|
for (int row = 0, y = 56; row < this->m_visibleRows; ++row, y += 22) {
|
|
this->FillRegion(14, y, 214, 18, 0xE6E6E6);
|
|
}
|
|
|
|
for (unsigned int index = 0; index < this->m_rows.size(); ++index) {
|
|
this->m_rows[index].first->Enable(0);
|
|
this->m_rows[index].second->Enable(0);
|
|
}
|
|
|
|
int y = 57;
|
|
for (unsigned int index = this->m_firstRow; static_cast<int>(index) < this->m_firstRow + this->m_visibleRows; ++index, y += 22) {
|
|
if (index >= this->m_rows.size()) {
|
|
return;
|
|
}
|
|
|
|
this->m_rows[index].first->Enable(1);
|
|
this->m_rows[index].first->Move(15, y + 2);
|
|
this->m_rows[index].second->Enable(1);
|
|
this->m_rows[index].second->Move(36, y);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x007F10F0
|
|
// FUNCTION: fn_09849
|
|
void UIMacroUserInfoWnd::Paint() {
|
|
this->ClearSurface(0xFAFAFA);
|
|
this->DrawTextAt(this->m_controls->fonts, this->m_controls->locale, 5, 5, this->m_name.c_str(), 0, 0, 12, 0, 1, 0);
|
|
this->DrawTextAt(this->m_controls->fonts, this->m_controls->locale, 5, 20, this->m_message.c_str(), 0, 0, 12, 0, 0, 0);
|
|
}
|
|
|
|
// OFFSET: 0x007F1160
|
|
// FUNCTION: fn_09850
|
|
void UIMacroReporterWnd::Slot25(int x, int y) {
|
|
if (this->unknown_010C == 1 && y >= 18) {
|
|
return;
|
|
}
|
|
|
|
if (g_dragWindowId != this->geometry.id) {
|
|
g_windowMgr.BringToFront(this->geometry.id);
|
|
g_dragWindowId = this->geometry.id;
|
|
}
|
|
|
|
g_windowMgr.SetCapture(this);
|
|
this->ToScreen(x, y);
|
|
this->m_dragX = x;
|
|
this->m_dragY = y;
|
|
this->m_originX = this->geometry.x;
|
|
this->m_originY = this->geometry.y;
|
|
this->m_frameContext->snapping.graph.CaptureOrigins(this);
|
|
}
|
|
|
|
// OFFSET: 0x007F11F0
|
|
// FUNCTION: fn_09851
|
|
void UIMacroReporterWnd::Slot31(int, int) {
|
|
if (g_windowMgr.Capture() != this) {
|
|
return;
|
|
}
|
|
|
|
g_dragWindowId = -1;
|
|
g_windowMgr.ReleaseCapture();
|
|
this->m_frameContext->snapping.graph.Refresh(this);
|
|
}
|
|
|
|
// OFFSET: 0x007F1230
|
|
// FUNCTION: fn_09852
|
|
void UIMacroReporterWnd::Slot19() {
|
|
for (auto it = this->m_removedRows.begin(); it != this->m_removedRows.end();) {
|
|
if ((*it)->Disabled()) {
|
|
this->RemoveChild(*it, 1);
|
|
it = this->m_removedRows.erase(it);
|
|
} else {
|
|
++it;
|
|
}
|
|
}
|
|
|
|
this->Invalidate();
|
|
}
|
|
|
|
// OFFSET: 0x007F12A0
|
|
// FUNCTION: fn_09853
|
|
void UIMacroReporterWnd::Slot35(int delta) {
|
|
if (this->m_scrollable == 1) {
|
|
this->SendMsg(this->m_scrollBar, 7, delta < 0 ? 3 : -3, 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x007F12E0
|
|
// FUNCTION: fn_09854
|
|
void UIMacroReporterWnd::UpdateScrollBar() {
|
|
const int count = static_cast<int>(this->m_rows.size());
|
|
if (count == 0 || !this->m_scrollBar) {
|
|
return;
|
|
}
|
|
|
|
const int maximum = (std::max)(count - this->m_visibleRows, 0);
|
|
this->m_scrollable = maximum > 0;
|
|
if (maximum < 1) {
|
|
this->m_firstRow = 0;
|
|
this->m_scrollBar->SetRange(0, this->m_visibleRows, count);
|
|
} else {
|
|
this->m_scrollBar->SetRange(maximum, this->m_visibleRows, count);
|
|
if (this->m_firstRow < 0) {
|
|
this->m_firstRow = 0;
|
|
this->m_scrollBar->SetPosition(0);
|
|
} else {
|
|
if (maximum < this->m_firstRow) {
|
|
this->m_firstRow = maximum;
|
|
}
|
|
this->m_scrollBar->SetPosition(this->m_firstRow);
|
|
}
|
|
}
|
|
|
|
this->m_scrollBar->Invalidate();
|
|
this->Invalidate();
|
|
}
|
|
|
|
// OFFSET: 0x007EFE30
|
|
// FUNCTION: fn_09843
|
|
bool UIMacroReporterWnd::ValidateNames(unsigned char notify) {
|
|
this->m_nameCount = 0;
|
|
bool invalid = false;
|
|
|
|
for (int i = 0; i < this->m_visibleRows; ++i) {
|
|
std::string name = this->m_names[i];
|
|
if (name.empty()) {
|
|
continue;
|
|
}
|
|
|
|
std::string displayName = g_mapInfoMgr->GetDisplayName(name + ".rsw");
|
|
if (displayName == LookupMessage(187)) {
|
|
if (notify == 1) {
|
|
g_windowMgr.SendNotice(
|
|
1,
|
|
reinterpret_cast<std::intptr_t>(FormatOwnedString("%d번 %s", i + 1, LookupMessage(4010)).c_str()),
|
|
0xFF,
|
|
0,
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
invalid = true;
|
|
} else {
|
|
++this->m_nameCount;
|
|
}
|
|
}
|
|
|
|
if (this->m_nameCount > 0 && !invalid) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// OFFSET: 0x007F01A0
|
|
// FUNCTION: fn_09844
|
|
bool UIMacroReporterWnd::ValidateTarget(unsigned char notify) {
|
|
std::string text = this->m_target;
|
|
if (text.empty() || text.size() - 4 > 4) {
|
|
if (notify == 1) {
|
|
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(FormatOwnedString("%s", LookupMessage(4011)).c_str()), 0xFF, 0, 0, 0);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
const int value = std::atoi(text.c_str());
|
|
char digits[16] = {};
|
|
if (text.size() != 0) {
|
|
std::memset(digits, '0', text.size());
|
|
}
|
|
|
|
if (value == 0 && text.compare(digits) != 0) {
|
|
if (notify == 1) {
|
|
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(FormatOwnedString("%s", LookupMessage(4011)).c_str()), 0xFF, 0, 0, 0);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
text = "1" + this->m_target;
|
|
char number[16] = {};
|
|
int scale = 1;
|
|
for (std::size_t index = 1; index < text.size(); ++index) {
|
|
scale *= 10;
|
|
}
|
|
_itoa(scale + value, number, 10);
|
|
|
|
if (text.compare(number) != 0) {
|
|
if (notify == 1) {
|
|
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(FormatOwnedString("%s", LookupMessage(4011)).c_str()), 0xFF, 0, 0, 0);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// OFFSET: 0x007F25C0
|
|
// FUNCTION: fn_09857
|
|
int UIMacroUserInfoWnd::SendMsg(
|
|
UIWindow* sender, int message, std::intptr_t argument1, std::intptr_t argument2, std::intptr_t argument3, std::intptr_t argument4
|
|
) {
|
|
if (message == 6 && argument1 == 201) {
|
|
g_windowMgr.CloseWindow(287);
|
|
}
|
|
return this->UIFrameWnd::SendMsg(sender, message, argument1, argument2, argument3, argument4);
|
|
}
|
|
|
|
// OFFSET: 0x007F26C0
|
|
// FUNCTION: fn_09858
|
|
void UIMacroReporterWnd::Slot11() {
|
|
if (this->m_state) {
|
|
this->m_state->width = this->geometry.width;
|
|
this->m_state->height = this->geometry.height;
|
|
this->m_state->x = this->geometry.x;
|
|
this->m_state->y = this->geometry.y;
|
|
this->m_state->unknown_0011 = this->unknown_010C;
|
|
this->m_state->entries.clear();
|
|
this->m_state->entries.resize(this->m_entries.size());
|
|
for (unsigned int index = 0; index < this->m_entries.size(); ++index) {
|
|
this->m_state->entries[index] = this->m_entries[index];
|
|
}
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x007F13C0
|
|
// FUNCTION: fn_09855
|
|
void __stdcall SendMacroUserInfoPacket(std::uint16_t first, std::uint16_t second, std::uint8_t third) {
|
|
struct Packet {
|
|
std::uint16_t id;
|
|
std::uint16_t first;
|
|
std::uint16_t second;
|
|
std::uint8_t third;
|
|
} packet{0x0A6C, first, second, third};
|
|
|
|
CRagConnection* connection = &GetRagConnection();
|
|
const PacketLengths& lengths = reinterpret_cast<const PacketLengths&>(GetRagConnection());
|
|
connection->Send(lengths.FixedLength(packet.id), &packet);
|
|
}
|