rodecomp/Source/Contents/ReputeMgr.cpp
ragnarok-clanker dc3d5ce1a5 Maintenance: Resubmission of 14942 (gate: three existing in-class helpers whose lines changed lacked an annotation; marked // INLINED
Batch #14943 by ragnarok-clanker: no function's compiled code changes; checked with 741 compiled unit(s), including every includer of Source/ActorPickNode.h, Source/Client/Browser/BrowserClientSite.h, Source/Client/Browser/BrowserPopupDispatch.h, Source/Client/Mode/CGameMode.h, Source/Client/Mode/CLoginMode.h, Source/Client/Mode/CMode.h, Source/Client/Mode/ModeDragState.h, Source/Client/Replay.h, Source/Client/Session.h, Source/Client/Stove/StoveMgr.h, Source/Contents/AchievementMgr.h, Source/Contents/ActorNameCard.h, Source/Contents/Actors/CharacterRender.h, Source/Contents/Actors/EffectActors.h, Source/Contents/Actors/GameActor.h, Source/Contents/Actors/GrannyGameActor.h, Source/Contents/Actors/GroundScope.h, Source/Contents/Actors/Item.h, Source/Contents/Actors/Npc.h, Source/Contents/Actors/Pc.h, Source/Contents/Actors/RenderObjectState.h, Source/Contents/Actors/Skill.h, Source/Contents/AdventureGuideMgr.h, Source/Contents/Camera/Camera.h, Source/Contents/Camera/CameraState.h, Source/Contents/CashEmotionMgr.h, Source/Contents/Configuration/GameSettingsMgr.h, Source/Contents/EffectResourceSwitcher.h, Source/Contents/Effects/AMachineEffect.h, Source/Contents/Effects/AcidifiedThrow.h, Source/Contents/Effects/AxeBoomerang.h, Source/Contents/Effects/BlastForge.h, Source/Contents/Effects/CaneOfEvilEyeEffect.h, Source/Contents/Effects/CharacterParticleBundle.h, Source/Contents/Effects/CloudKillEffect.h, Source/Contents/Effects/Effect.h, Source/Contents/Effects/EffectActor.h, Source/Contents/Effects/EffectEmitter.h, Source/Contents/Effects/EffectMaker.h, Source/Contents/Effects/EffectPrimitiveState.h, Source/Contents/Effects/FuumaShouakuEffect.h, Source/Contents/Effects/GravityControlEffect.h, Source/Contents/Effects/HealSpEffect.h, Source/Contents/Effects/Level99Effect.h, Source/Contents/Effects/MapChainEffect.h, Source/Contents/Effects/MonsterSkillEffects.h, Source/Contents/Effects/MsgEffect.h, Source/Contents/Effects/NyanggrassEffect.h, Source/Contents/Effects/Particle.h, Source/Contents/Effects/PowderingEffect.h, Source/Contents/Effects/RagEffectState.h, Source/Contents/Effects/RectUpEffect.h, Source/Contents/Effects/ShadowExceedEffect.h, Source/Contents/Effects/SkillEffects.h, Source/Contents/Effects/SpriteParticle.h, Source/Contents/Effects/StormCannonEffect.h, Source/Contents/Effects/ThrowEffects.h, Source/Contents/EntryQueueMgr.h, Source/Contents/EquipmentResourceMgr.h, Source/Contents/FlyingShipRouteInfo.h, Source/Contents/Ground/GroundGeometry.h, Source/Contents/GuildInfo.h, Source/Contents/Items/ItemDescription.h, Source/Contents/Items/ItemInfo.h, Source/Contents/MapSkyMgr.h, Source/Contents/Messenger/MessengerWindows.h, Source/Contents/Models/ModelNode.h, Source/Contents/NavigationManager.h, Source/Contents/Party/AdventurerAgencyMgr.h, Source/Contents/RDamageVar.h, Source/Contents/RenewQuestMgr.h, Source/Contents/ReputeMgr.h, Source/Contents/RodexMailStore.h, Source/Contents/RouletteMgr.h, Source/Contents/Schedule/Schedule.h, Source/Contents/SignBoard/SignBoard.h, Source/Contents/Skills/ClientSkills.h, Source/Contents/Skills/PlayerSkillBundle.h, Source/Contents/Skills/SkillInfo.h, Source/Contents/SpriteLayerDrawing.h, Source/Contents/TipBoxTitles.h, Source/Contents/UserData/AccountLinkedUserDataMgr.h, Source/Contents/UserData/NormalItemSlots.h, Source/Contents/World/World.h, Source/Contents/WorldView/WorldViewData.h, Source/Render/Primitives/LightmappedPrimitive.h, Source/Render/Primitives/RenderPrimitive.h, Source/Render/Renderer.h, Source/Render/Textures/SpritePixels.h, Source/Render/Textures/Texture.h, Source/Resource/EZeffectResource.h, Source/Resource/Models/AnimatedModelResource.h, Source/Resource/Models/GrannyModelResource.h, Source/Resource/Sprites/ActionResource.h, Source/Resource/World/GroundResource.h, Source/Resource/World/WorldResource.h, Source/Resource/XmlNode.h, Source/UI/AdventureGuide/UIAdventureGuide.h, Source/UI/Buttons/UIBmpRadioBtn.h, Source/UI/Buttons/UIDescriptRace.h, Source/UI/Buttons/UIItemTagButton.h, Source/UI/Buttons/UISlotBmpButton.h, Source/UI/Buttons/UISpriteButton.h, Source/UI/Buttons/UITVTextButton.h, Source/UI/Buttons/UITextureButton.h, Source/UI/CashEmotion/UICashEmotionListWnd.h, Source/UI/CashEmotion/UICashEmotionPack.h, Source/UI/CashShop/UICashShopWnd.h, Source/UI/Chat/UIChatRoomMakeWnd.h, Source/UI/Chat/UIChatRoomTitle.h, Source/UI/Chat/UINewChatWnd.h, Source/UI/Chat/UISubChatHisWnd.h, Source/UI/Chat/UISubChatMiniWnd.h, Source/UI/Chat/UIWhisperWnd.h, Source/UI/Clan/UIClanWnd.h, Source/UI/Dialogs/UIBookWnd.h, Source/UI/Dialogs/UIChooseWarpWnd.h, Source/UI/Dialogs/UIMenuWnd.h, Source/UI/Dialogs/UIMiniMapWnd.h, Source/UI/Dialogs/UIMinimapZoomWnd.h, Source/UI/Dialogs/UINpcEditDialogWnd.h, Source/UI/Dialogs/UIPasswordWnd.h, Source/UI/Dialogs/UISayDialogWnd.h, Source/UI/Dialogs/UISelectCartWnd.h, Source/UI/Dialogs/UITipboxWnd.h, Source/UI/Edit/UIEditBoxEx.h, Source/UI/Edit/UIEditCtrl.h, Source/UI/Edit/UIEditCtrl_Currency.h, Source/UI/Edit/UIItemTagCtrl.h, Source/UI/Enchant/EnchantUI.h, Source/UI/Exchange/UIExchangeUI.h, Source/UI/FrameSkin.h, Source/UI/GameSettings/GameSettingsUI.h, Source/UI/Gauges/UIPcGage.h, Source/UI/Guild/UIGuildHelperWnd.h, Source/UI/Guild/UIGuildWnd.h, Source/UI/Guild/UIGuild_Storage_Log.h, Source/UI/Item/UIEquipmentPropertiesWnd.h, Source/UI/Item/UIItemBaseWnd.h, Source/UI/Item/UIItemPurchaseWnd.h, Source/UI/Item/UIItemSellWnd2.h, Source/UI/Item/UIItemShopWnd.h, Source/UI/Item/UIItemShopWnd2.h, Source/UI/Item/UIItemStoreFindWnd.h, Source/UI/Item/UIItemStoreSubWnd.h, Source/UI/Item/UIItemStoreWnd.h, Source/UI/Item/UIItemWnd.h, Source/UI/Item/UIMerchantItemLogWnd.h, Source/UI/Item/UIParaItemShopWnd.h, Source/UI/Items/UICardItemIllustWnd.h, Source/UI/Items/UIEquipWnd.h, Source/UI/Items/UIExchangeWnd.h, Source/UI/Items/UIGameItem.h, Source/UI/Items/UIItemCollectionWnd.h, Source/UI/Items/UIItemIdentifyWnd.h, Source/UI/Items/UIItemParamChangeDisplayWnd.h, Source/UI/Items/UISwapEquipmentWnd.h, Source/UI/Layout/WindowGeometry.h, Source/UI/Lists/UIChatHisBox.h, Source/UI/Lists/UIComboBoxV2Wnd.h, Source/UI/Lists/UIImgMenu.h, Source/UI/Lists/UIListBoxID.h, Source/UI/Lists/UIListBoxTemplate.h, Source/UI/Lists/UIMemberListBox.h, Source/UI/Lists/UITabControl.h, Source/UI/Lists/UITagListBox.h, Source/UI/Lists/UITreeView.h, Source/UI/Menu/UIMenuIconWnd.h, Source/UI/Navigation/UINavigationV4Wnd.h, Source/UI/ProbabilityTable/UIProbabilityTable.h, Source/UI/Quest/UIQuestDisplay.h, Source/UI/Quest/UIRenewQuestUI.h, Source/UI/Quest/UIRenewQuestWnd.h, Source/UI/Rodex/UIRodexComposeWnd.h, Source/UI/Rodex/UIRodexInboxWnd.h, Source/UI/RuneSystem/UIRuneSystemWindows.h, Source/UI/RuneSystem/UIRuneSystemWnd.h, Source/UI/Shop/UIMerchantItemMyShopWnd.h, Source/UI/Shop/UIMerchantItemPurchaseMSGWnd.h, Source/UI/Shop/UIMerchantItemPurchaseWnd.h, Source/UI/Shop/UIMerchantItemShopWnd.h, Source/UI/Shop/UIMerchantMirrorItemWnd.h, Source/UI/Shop/UIMerchantShopMakeWnd.h, Source/UI/Shop/UIMerchantShopTitle.h, Source/UI/Skill/UISkillDescribeWnd.h, Source/UI/Skill/UISkillListWnd.h, Source/UI/SkillDelayInfo/SkillDelayInfo.h, Source/UI/StylingShop/UIStylingShopWnd.h, Source/UI/Text/CreateLineInfo.h, Source/UI/Text/UIAchWnd.h, Source/UI/Text/UIBalloonText.h, Source/UI/Text/UINameBalloonText.h, Source/UI/Text/UIStaticTextControl.h, Source/UI/Text/UIString.h, Source/UI/Text/UITextViewerControl.h, Source/UI/UIBarGraph.h, Source/UI/UIBartermarketWnd.h, Source/UI/UIChangeMaterialWnd.h, Source/UI/UIGradeEnchantWnd.h, Source/UI/UILapineScrollBar.h, Source/UI/UIMacroBlackListCheckWnd.h, Source/UI/UIMacroDetectorWnd.h, Source/UI/UIMacroReport.h, Source/UI/UIMacroUserInfoWnd.h, Source/UI/UIPreviewEquipWnd.h, Source/UI/UIRefiningWnd.h, Source/UI/UIScrollWnd.h, Source/UI/UISlotBitmap.h, Source/UI/Window/FuncDrawWNDChar.h, Source/UI/Window/UIBattleMsgOptionWnd.h, Source/UI/Window/UIChatRoomWnd.h, Source/UI/Window/UICollectionSystemWnd.h, Source/UI/Window/UIControl.h, Source/UI/Window/UIHomunInfoWnd.h, Source/UI/Window/UIHotKeyWnd.h, Source/UI/Window/UIJobListWnd.h, Source/UI/Window/UILoginOTPWnd.h, Source/UI/Window/UILoginWnd.h, Source/UI/Window/UIMakeCharWnd.h, Source/UI/Window/UIMonsterDisplayWnd.h, Source/UI/Window/UIMonsterInfoWnd.h, Source/UI/Window/UINavigationHelpWnd.h, Source/UI/Window/UINavigationWnd.h, Source/UI/Window/UINewMakeCharWnd.h, Source/UI/Window/UINewSelectCharWnd.h, Source/UI/Window/UINoticeWnd.h, Source/UI/Window/UIPetInfoWnd.h, Source/UI/Window/UIRegisterMgr.h, Source/UI/Window/UIRoMapWnd.h, Source/UI/Window/UIRodexContentsWnd.h, Source/UI/Window/UISecondCostumeWnd.h, Source/UI/Window/UISeekPartyMBWnd.h, Source/UI/Window/UISeekPartyWnd.h, Source/UI/Window/UISelCharForUServerWnd.h, Source/UI/Window/UISerachStoreInfoWnd.h, Source/UI/Window/UITransMenuWnd.h, Source/UI/Window/UIWindow.h, Source/UI/Window/UIWindowMgr.h, Source/UI/Window/UIWindowMgr.inl, Source/Utility/Lexicon/LexiconSerializer.h.
2026-11-08 16:44:36 +00:00

335 lines
10 KiB
C++

#include "Contents/ReputeMgr.h"
#include "UI/Window/UIEnums.h"
#include "UI/Window/WindowId.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 "Resource/MSGSTRINGID.h"
#include <algorithm>
#include <cstring>
#include <utility>
// OFFSET: 0x0050AE30
// FUNCTION: fn_00894
bool JsonCppLoader::GetReputeGroupData(std::map<int, ReputeGroupRecord>* out) {
if (!this->loaded) {
this->Fail("초기화가 되어야 합니다.");
return false;
}
const JsonValue* groups = nullptr;
if (const JsonObject* root = this->document.ObjectRange()) {
for (const JsonMember& entry : *root) {
if (entry.first == "ReputeGroup") {
groups = &entry.second;
break;
}
}
}
if (groups == nullptr) {
this->Fail("키에 해당하는 데이터가 없습니다. (key : %s)", "ReputeGroup");
return false;
}
const JsonObject* members = groups->ObjectRange();
const JsonObject none;
for (const JsonMember& member : members ? *members : none) {
const std::string name = member.first;
const JsonValue node = member.second;
ReputeGroupRecord record;
this->GetStringValue(node, "ID", &record.id);
this->GetStringValue(node, "Name", &record.name);
this->GetIntVectorValue(node, "ReputeList", &record.reputes);
if (!out->insert(std::make_pair(std::stoi(name), record)).second) {
this->Fail("중복키가 입력되었습니다. (name : %s)", name.c_str());
return false;
}
}
return this->succeeded;
}
// OFFSET: 0x0050B830
// FUNCTION: fn_00895
bool JsonCppLoader::GetReputeInfoData(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::LoadReputeGroupData(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;
}
JsonCppLoader loader;
const auto* data = static_cast<const unsigned char*>(file.GetData());
bool parsed;
{
std::vector<unsigned char> buffer(data, data + file.GetSize());
parsed = loader.Load(buffer, true);
}
if (!parsed) {
return false;
}
std::map<int, ReputeGroupRecord> records;
if (!loader.GetReputeGroupData(&records)) {
return false;
}
groups.clear();
std::for_each(records.begin(), records.end(), GroupInserter{this, &groups});
return true;
}
// OFFSET: 0x0060E090
// FUNCTION: fn_04295
bool CReputeMgr::LoadReputeInfoData(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;
}
JsonCppLoader loader;
const auto* data = static_cast<const unsigned char*>(file.GetData());
bool parsed;
{
std::vector<unsigned char> buffer(data, data + file.GetSize());
parsed = loader.Load(buffer, true);
}
if (!parsed) {
return false;
}
std::map<int, ReputeInfoRecord> records;
if (!loader.GetReputeInfoData(&records)) {
return false;
}
infos.clear();
std::for_each(records.begin(), records.end(), InfoInserter{this, &infos});
return true;
}
// OFFSET: 0x0060C5D0
// FUNCTION: fn_04283
CReputeMgr::CReputeMgr() {
}
// OFFSET: 0x0060D8B0
// FUNCTION: fn_04290
std::vector<std::string> CReputeMgr::GetGroupNames() const {
std::vector<std::string> names;
std::for_each(this->m_groups.begin(), this->m_groups.end(), [&names](const std::pair<const std::uint64_t, ReputeGroup>& entry) {
std::pair<const std::uint64_t, ReputeGroup> group = entry;
names.push_back(group.second.name);
});
return names;
}
// OFFSET: 0x0060D930
// FUNCTION: fn_04291
std::vector<const ReputeInfo*> CReputeMgr::GetGroupReputes(const std::string& groupName) const {
std::vector<const ReputeInfo*> reputes;
for (auto group = this->m_groups.begin(); group != this->m_groups.end(); ++group) {
if (group->second.name == groupName) {
for (auto id = group->second.reputes.begin(); id != group->second.reputes.end(); ++id) {
auto found = this->m_infos.find(*id);
if (found == this->m_infos.end()) {
continue;
}
const ReputeVisibility visibility = found->second.visibility;
if (visibility == REPUTE_VISIBLE || (visibility == REPUTE_VISIBLE_WITH_POINT && found->second.point != 0)) {
reputes.push_back(&found->second);
}
}
}
}
return reputes;
}
// OFFSET: 0x0060DAB0
// FUNCTION: fn_04292
std::vector<const ReputeInfo*> CReputeMgr::GetAllReputes() const {
std::vector<const ReputeInfo*> reputes;
for (auto group = this->m_groups.begin(); group != this->m_groups.end(); ++group) {
for (auto id = group->second.reputes.begin(); id != group->second.reputes.end(); ++id) {
auto found = this->m_infos.find(*id);
if (found == this->m_infos.end()) {
continue;
}
const ReputeVisibility visibility = found->second.visibility;
if (visibility == REPUTE_VISIBLE || (visibility == REPUTE_VISIBLE_WITH_POINT && found->second.point != 0)) {
reputes.push_back(&found->second);
}
}
}
return reputes;
}
// OFFSET: 0x0060DBF0
// FUNCTION: fn_04293
bool CReputeMgr::Load() {
if (!this->LoadReputeInfoData(this->m_infos)) {
ShowErrorDialog(GetRenderSystemHolder()->system, "Failed : LoadReputeInfoData", 0);
return false;
}
if (!this->LoadReputeGroupData(this->m_groups)) {
return false;
}
return true;
}
// OFFSET: 0x0060E4A0
// FUNCTION: fn_04296
void CReputeMgr::OpenRepute(std::uint64_t groupId, std::uint64_t reputeId) {
UIWindow* window = g_windowMgr.EnsureWindow(WID_REPUTEWND);
if (!window) {
return;
}
const unsigned int groupIdLow = static_cast<unsigned int>(groupId);
const unsigned int groupIdHigh = static_cast<unsigned int>(groupId >> 32);
if (groupIdLow == 0 && groupIdHigh == 0) {
window->SendMsg(nullptr, UM_TAB, reinterpret_cast<std::intptr_t>(LookupMessage(MSI_ENCHANT)), 0, 0, 0);
} else {
auto group = this->m_groups.find(groupId);
if (group != this->m_groups.end()) {
window->SendMsg(nullptr, UM_TAB, reinterpret_cast<std::intptr_t>(group->second.name.c_str()), 0, 0, 0);
}
}
auto info = this->m_infos.find(reputeId);
if (info != this->m_infos.end()) {
info->second.updated = true;
window->Invalidate();
}
}
// OFFSET: 0x0060E5B0
// FUNCTION: fn_04297
void CReputeMgr::SetPoint(std::uint64_t id, std::int64_t point) {
auto found = this->m_infos.find(id);
if (found != this->m_infos.end()) {
found->second.point = point;
}
}
// OFFSET: 0x0060E610
// FUNCTION: fn_04298
std::vector<const ReputeInfo*> CReputeMgr::FindReputes(const std::string& keyword) const {
std::vector<const ReputeInfo*> reputes;
for (auto entry = this->m_infos.begin(); entry != this->m_infos.end(); ++entry) {
const ReputeInfo& info = entry->second;
if (info.name.find(keyword) == std::string::npos) {
continue;
}
if (info.visibility == REPUTE_VISIBLE || (info.visibility == REPUTE_VISIBLE_WITH_POINT && info.point != 0)) {
reputes.push_back(&info);
}
}
return reputes;
}
// OFFSET: 0x0060E830
// FUNCTION: fn_04299
void CReputeMgr::SetPointsReceived(bool received) {
this->m_waitingForPoints = !received;
if (received == true) {
UIWindow* window = g_windowMgr.LookupWindow(WID_REPUTEWND);
if (window) {
window->SendMsg(nullptr, UM_REFRESH_REPUTE_FILTER, 0, 0, 0, 0);
}
}
}
// OFFSET: 0x0060D440
// FUNCTION: fn_04287
void CReputeMgr::InfoInserter::operator()(const std::pair<int, ReputeInfoRecord>& entry) const {
ReputeInfo info;
info.name = FromUtf8(entry.second.name, g_textCodePage);
info.maxPointPositive = entry.second.maxPointPositive;
info.maxPointNegative = entry.second.maxPointNegative;
const std::string invisible = FromUtf8(entry.second.invisible, g_textCodePage);
const char* text = invisible.c_str();
if (invisible.size() == 12 && text[0] == 'V' && text[1] == 'I' && text[2] == 'S' && text[3] == 'I' &&
text[4] == 'B' && text[5] == 'L' && text[6] == 'E' && text[7] == '_' && text[8] == 'T' &&
text[9] == 'R' && text[10] == 'U' && text[11] == 'E') {
info.visibility = REPUTE_VISIBLE;
} else if (invisible == "VISIBLE_FALSE") {
info.visibility = REPUTE_HIDDEN;
} else {
info.visibility = REPUTE_VISIBLE_WITH_POINT;
}
(*this->dest)[entry.first] = info;
}
// OFFSET: 0x0060D060
// FUNCTION: fn_04286
void CReputeMgr::GroupInserter::operator()(const std::pair<int, ReputeGroupRecord>& entry) const {
ReputeGroup group;
group.name = static_cast<const std::string&>(FromUtf8(entry.second.name, g_textCodePage));
group.reputes = std::vector<std::uint64_t>(entry.second.reputes.begin(), entry.second.reputes.end());
(*this->dest)[static_cast<std::uint64_t>(entry.first)] = group;
}