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.
790 lines
24 KiB
C++
790 lines
24 KiB
C++
#include "Client/Mode/ModeMessage.h"
|
|
#include "Contents/WorldView/WorldViewData.h"
|
|
#include "Client/Application/ApplicationWindow.h"
|
|
#include "Client/Mode/CMode.h"
|
|
#include "Client/Mode/ModeMgr.h"
|
|
#include "Client/Session.h"
|
|
#include "Contents/MessageTable.h"
|
|
#include "Render/Renderer.h"
|
|
#include "Render/Textures/Texture.h"
|
|
#include "Render/Textures/TextureCache.h"
|
|
#include "Script/LuaScript.h"
|
|
#include "UI/Window/UIRoMapWnd.h"
|
|
|
|
#include "Resource/MSGSTRINGID.h"
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
|
|
// INLINED
|
|
static bool AreaContains(int left, int top, int right, int bottom, int x, int y) {
|
|
return left < x && right > x && top < y && bottom > y;
|
|
}
|
|
|
|
// INLINED
|
|
static __forceinline WorldViewRecord* FindRecord(std::vector<WorldViewRecord>& records, const char* name) {
|
|
const std::string key(name);
|
|
for (std::vector<WorldViewRecord>::iterator it = records.begin(); it != records.end(); ++it) {
|
|
if (it->name == key) {
|
|
return &*it;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
// OFFSET: 0x00612C70
|
|
// FUNCTION: fn_04345
|
|
__declspec(noinline) CWorldViewWorld::CWorldViewWorld(const char* name, const char* imageName) {
|
|
this->name = name;
|
|
this->imageName = imageName;
|
|
}
|
|
|
|
// OFFSET: 0x00613050
|
|
// FUNCTION: fn_04346
|
|
__declspec(noinline) CWorldViewField::CWorldViewField(WorldViewArea area, const char* name, const char* unknown2, const char* unknown3) {
|
|
this->left = area.left;
|
|
this->top = area.top;
|
|
this->right = area.right;
|
|
this->bottom = area.bottom;
|
|
this->areaFlags = area.areaFlags;
|
|
if (name) {
|
|
this->name = name;
|
|
}
|
|
if (unknown2) {
|
|
this->fieldName = unknown2;
|
|
}
|
|
if (unknown3) {
|
|
this->description = unknown3;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00613360
|
|
// FUNCTION: fn_04349
|
|
CWorldViewWorld::~CWorldViewWorld() {
|
|
for (std::vector<CWorldViewMap*>::iterator it = this->maps.begin(); it != this->maps.end(); ++it) {
|
|
delete *it;
|
|
}
|
|
this->maps.clear();
|
|
}
|
|
|
|
// OFFSET: 0x006135C0
|
|
// FUNCTION: fn_04350
|
|
void CWorldViewWorld::AddField(int mapId, const char* name, CWorldViewField* field) {
|
|
CWorldViewMap* map = nullptr;
|
|
for (std::vector<CWorldViewMap*>::iterator it = this->maps.begin(); it != this->maps.end(); ++it) {
|
|
if ((*it)->id == mapId) {
|
|
map = *it;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!map) {
|
|
map = new CWorldViewMap;
|
|
if (name) {
|
|
map->name = name;
|
|
map->displayName = name;
|
|
}
|
|
map->id = mapId;
|
|
map->left = field->left;
|
|
map->top = field->top;
|
|
map->right = field->right;
|
|
map->bottom = field->bottom;
|
|
map->areaFlags = field->areaFlags;
|
|
this->maps.push_back(map);
|
|
}
|
|
|
|
if (field->left < map->left) {
|
|
map->left = field->left;
|
|
}
|
|
if (field->top < map->top) {
|
|
map->top = field->top;
|
|
}
|
|
if (map->right < field->right) {
|
|
map->right = field->right;
|
|
}
|
|
if (map->bottom < field->bottom) {
|
|
map->bottom = field->bottom;
|
|
}
|
|
map->fields.push_back(field);
|
|
}
|
|
|
|
// OFFSET: 0x006137B0
|
|
// FUNCTION: fn_04351
|
|
__declspec(noinline) bool CWorldViewWorld::LoadTexture() {
|
|
std::string path = "유저인터페이스\\";
|
|
path += this->imageName;
|
|
this->texture = g_texMgr.Load(path.c_str(), 0, true, true, false);
|
|
return this->texture != nullptr;
|
|
}
|
|
|
|
// OFFSET: 0x00613AB0
|
|
// FUNCTION: fn_04352
|
|
CWorldViewField* CWorldViewWorld::FieldAt(unsigned int& mapIndex, int x, int y) {
|
|
const unsigned int count = this->maps.size();
|
|
for (unsigned int index = 0; index < count; ++index) {
|
|
const CWorldViewMap* map = this->maps[index];
|
|
bool hit;
|
|
if (map->id < 100 && !map->fields.empty()) {
|
|
const CWorldViewField* first = map->fields.front();
|
|
hit = AreaContains(first->left, first->top, first->right, first->bottom, x, y);
|
|
} else {
|
|
hit = AreaContains(map->left, map->top, map->right, map->bottom, x, y);
|
|
}
|
|
|
|
if (hit) {
|
|
mapIndex = index;
|
|
CWorldViewMap* found = this->maps[index];
|
|
if (!found) {
|
|
return nullptr;
|
|
}
|
|
for (std::vector<CWorldViewField*>::iterator it = found->fields.begin(); it != found->fields.end(); ++it) {
|
|
CWorldViewField* field = *it;
|
|
if (AreaContains(field->left, field->top, field->right, field->bottom, x, y)) {
|
|
return field;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
// OFFSET: 0x00613B80
|
|
// FUNCTION: fn_04353
|
|
__declspec(noinline) CWorldViewField* CWorldViewWorld::FindField(unsigned int& mapIndex, const char* name) {
|
|
const unsigned int count = this->maps.size();
|
|
for (unsigned int index = 0; index < count; ++index) {
|
|
CWorldViewMap* map = this->maps[index];
|
|
for (std::vector<CWorldViewField*>::iterator it = map->fields.begin(); it != map->fields.end(); ++it) {
|
|
CWorldViewField* field = *it;
|
|
if (std::strcmp(field->name.c_str(), name) == 0) {
|
|
if (field) {
|
|
mapIndex = index;
|
|
return field;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
// OFFSET: 0x00613C30
|
|
// FUNCTION: fn_04354
|
|
__declspec(noinline) CWorldViewField* CWorldViewWorld::FindField(const char* name) {
|
|
for (std::vector<CWorldViewMap*>::iterator it = this->maps.begin(); it != this->maps.end(); ++it) {
|
|
if (CWorldViewField* field = (*it)->FindField(name)) {
|
|
return field;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
// OFFSET: 0x00613CB0
|
|
// FUNCTION: fn_04355
|
|
__declspec(noinline) CWorldViewField* CWorldViewMap::FindField(const char* name) {
|
|
for (std::vector<CWorldViewField*>::iterator it = this->fields.begin(); it != this->fields.end(); ++it) {
|
|
CWorldViewField* field = *it;
|
|
if (std::strcmp(field->name.c_str(), name) == 0) {
|
|
return field;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
// OFFSET: 0x00613DD0
|
|
// FUNCTION: fn_04356
|
|
__declspec(noinline) CWorldViewMap* CWorldViewWorld::FindMap(int id) {
|
|
for (std::vector<CWorldViewMap*>::iterator it = this->maps.begin(); it != this->maps.end(); ++it) {
|
|
if (id == (*it)->id) {
|
|
return *it;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
// OFFSET: 0x00613E00
|
|
// FUNCTION: fn_04357
|
|
CWorldViewMap* CWorldViewWorld::MapAt(unsigned int& mapIndex, int x, int y) {
|
|
for (unsigned int index = 0; index < this->maps.size(); ++index) {
|
|
if (this->maps[index]->id < 100) {
|
|
if (this->maps[index]->fields.empty()) {
|
|
if (AreaContains(this->maps[index]->left, this->maps[index]->top, this->maps[index]->right, this->maps[index]->bottom, x, y)) {
|
|
mapIndex = index;
|
|
return this->maps[index];
|
|
}
|
|
} else {
|
|
const CWorldViewField* first = this->maps[index]->fields.front();
|
|
if (AreaContains(first->left, first->top, first->right, first->bottom, x, y)) {
|
|
mapIndex = index;
|
|
return this->maps[index];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
// OFFSET: 0x00613F10
|
|
// FUNCTION: fn_04358
|
|
__declspec(noinline) void CWorldViewWorld::Draw(int, int x, int y, int width, int height) {
|
|
std::string path = "유저인터페이스\\";
|
|
path += this->imageName;
|
|
this->texture = g_texMgr.Load(path.c_str(), 0, true, true, false);
|
|
this->texture->Stretch(x, y, width, height);
|
|
}
|
|
|
|
// OFFSET: 0x006145E0
|
|
// FUNCTION: fn_04367
|
|
CWorldViewMgr::CWorldViewMgr() {
|
|
this->screenScale = 0;
|
|
this->dungeonColor = 0;
|
|
this->dungeonOverlayColor = 0;
|
|
this->dungeonFontColor = 0xFFFFFFFF;
|
|
this->dungeonFontOutline = 0xFF000000;
|
|
this->dungeonSelectColor = 0xFFFFFFFF;
|
|
this->dungeonSelectTextColor = 0xFFFFFFFF;
|
|
this->mobLevelColor = 0xFFFFFFFF;
|
|
this->mobLevelOutline = 0xFF000000;
|
|
this->mobColor = 0xFFFFFFFF;
|
|
this->mobOutline = 0xFF000000;
|
|
this->boxLineColor = 0x282828;
|
|
|
|
const std::string base = "유저인터페이스\\worldview_interface\\wv_Sreach";
|
|
for (int index = 0; index < 16; ++index) {
|
|
this->searchColors[index] = 0xEEFFFFFF;
|
|
this->searchImages[index] = base + "NoImage.bmp";
|
|
}
|
|
|
|
this->searchImages[0] = base + "Map.bmp";
|
|
this->searchImages[1] = base + "Mob1.bmp";
|
|
this->searchImages[2] = base + "Mob2.bmp";
|
|
this->searchImages[3] = base + "Mob3.bmp";
|
|
this->searchImages[4] = base + "Mob4.bmp";
|
|
this->searchImages[5] = base + "Mob5.bmp";
|
|
this->searchImages[10] = base + "Npc.bmp";
|
|
this->searchImages[11] = base + "Npc_Mob1.bmp";
|
|
this->searchImages[12] = base + "Npc_Mob2.bmp";
|
|
this->searchImages[13] = base + "Npc_Mob3.bmp";
|
|
this->searchImages[14] = base + "Npc_Mob4.bmp";
|
|
this->searchImages[15] = base + "Npc_Mob5.bmp";
|
|
|
|
this->runColor = 0;
|
|
this->runFontColor = 0xFF000000;
|
|
for (int index = 0; index < 4; ++index) {
|
|
this->dungeonFontSize[index] = 10;
|
|
this->mobLevelFont[index] = 10;
|
|
this->mobFont[index] = 10;
|
|
this->runFont[index] = 10;
|
|
}
|
|
}
|
|
|
|
// INLINED
|
|
static void ScaleArea(int* area, int textureWidth, int textureHeight) {
|
|
if (!area) {
|
|
return;
|
|
}
|
|
|
|
const float scaleX = static_cast<float>(g_renderer->viewport.width) / static_cast<float>(textureWidth);
|
|
const float scaleY = static_cast<float>(g_renderer->viewport.height - 17) / static_cast<float>(textureHeight);
|
|
area[0] = static_cast<int>(static_cast<float>(area[0]) * scaleX + 0.5);
|
|
area[1] = static_cast<int>(static_cast<float>(area[1]) * scaleY + 0.5) + 17;
|
|
area[2] = static_cast<int>(static_cast<float>(area[2]) * scaleX + 0.5);
|
|
area[3] = static_cast<int>(static_cast<float>(area[3]) * scaleY + 0.5) + 17;
|
|
}
|
|
|
|
// OFFSET: 0x006166E0
|
|
// FUNCTION: fn_04374
|
|
bool CWorldViewMgr::ScaleToScreen() {
|
|
for (std::vector<CWorldViewWorld*>::iterator it = this->worlds.begin(); it != this->worlds.end(); ++it) {
|
|
CWorldViewWorld* world = *it;
|
|
if (!world->texture) {
|
|
continue;
|
|
}
|
|
|
|
const int textureWidth = world->texture->Width();
|
|
const int textureHeight = world->texture->Height();
|
|
for (std::vector<CWorldViewMap*>::iterator map = world->maps.begin(); map != world->maps.end(); ++map) {
|
|
ScaleArea(&(*map)->left, textureWidth, textureHeight);
|
|
for (std::vector<CWorldViewField*>::iterator field = (*map)->fields.begin(); field != (*map)->fields.end(); ++field) {
|
|
if (*field) {
|
|
ScaleArea(&(*field)->left, textureWidth, textureHeight);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// GLOBAL: gl_25167
|
|
static int gl_25167 = 0;
|
|
|
|
// OFFSET: 0x006168F0
|
|
// FUNCTION: fn_04375
|
|
void CWorldViewMgr::LoadTextures() {
|
|
const int width = g_renderer->viewport.width;
|
|
if (width > 640) {
|
|
if (width <= 800) {
|
|
this->screenScale = 1;
|
|
} else {
|
|
this->screenScale = (width > 1024) + 2;
|
|
}
|
|
}
|
|
|
|
for (std::vector<CWorldViewWorld*>::iterator it = this->worlds.begin(); it != this->worlds.end(); ++it) {
|
|
(*it)->LoadTexture();
|
|
}
|
|
|
|
if (g_session.mapPositionsScaled == 0) {
|
|
g_session.mapPositionsScaled = this->ScaleToScreen();
|
|
g_session.ScaleMapPositions();
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00616970
|
|
// FUNCTION: fn_04376
|
|
unsigned int CWorldViewMgr::FindWorld(int mapId) {
|
|
std::string name;
|
|
if (mapId == -1) {
|
|
CMode* mode = g_modeMgr.GetGameMode();
|
|
if (!mode) {
|
|
return 0;
|
|
}
|
|
const std::string modeName(reinterpret_cast<const char*>(mode->SendMsg(MM_QUERYRSWNAME, 0, 0, 0, 0)));
|
|
name = modeName;
|
|
}
|
|
|
|
for (unsigned int index = 0; index < this->worlds.size(); ++index) {
|
|
if (this->worlds[index]->FindField(name.c_str())) {
|
|
return index;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// OFFSET: 0x00616C20
|
|
// FUNCTION: fn_04377
|
|
__declspec(noinline) void CWorldViewMgr::ResetSelection() {
|
|
this->selection.worldIndex = 0;
|
|
this->selection.mapIndex = 0;
|
|
this->selection.name.clear();
|
|
this->selection.left = 0;
|
|
this->selection.top = 0;
|
|
this->selection.right = 0;
|
|
this->selection.bottom = 0;
|
|
this->selection.relatedNames.clear();
|
|
}
|
|
|
|
// OFFSET: 0x00616CC0
|
|
// FUNCTION: fn_04378
|
|
bool CWorldViewMgr::SelectField(const char* name) {
|
|
this->ResetSelection();
|
|
if (!name) {
|
|
return false;
|
|
}
|
|
|
|
unsigned int mapIndex = static_cast<unsigned int>(-1);
|
|
for (unsigned int index = 0; index < this->worlds.size(); ++index) {
|
|
CWorldViewField* field = this->worlds[index]->FindField(mapIndex, name);
|
|
if (field && this->worlds[index]->maps[mapIndex]->id >= 100) {
|
|
this->selection.mapIndex = mapIndex;
|
|
this->selection.worldIndex = index;
|
|
this->selection.name = field->name;
|
|
this->selection.left = field->left;
|
|
this->selection.top = field->top;
|
|
this->selection.right = field->right;
|
|
this->selection.bottom = field->bottom;
|
|
this->selection.areaFlags = field->areaFlags;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// OFFSET: 0x00616D80
|
|
// FUNCTION: fn_04379
|
|
void CWorldViewMgr::Draw(int unused, int x, int y, int width, int height) {
|
|
if (this->currentWorld < 0) {
|
|
this->currentWorld = 0;
|
|
}
|
|
|
|
const unsigned int count = this->worlds.size();
|
|
if (count <= static_cast<unsigned int>(this->currentWorld)) {
|
|
this->currentWorld = count - 1;
|
|
}
|
|
|
|
this->worlds[this->currentWorld]->Draw(unused, x, y, width, height);
|
|
}
|
|
|
|
// OFFSET: 0x00616DD0
|
|
// FUNCTION: fn_04380
|
|
bool CWorldViewMgr::AddMark(const char* name) {
|
|
if (!name) {
|
|
return false;
|
|
}
|
|
|
|
if (FindRecord(this->marks, name)) {
|
|
return true;
|
|
}
|
|
|
|
unsigned int mapIndex = static_cast<unsigned int>(-1);
|
|
for (unsigned int index = 0; index < this->worlds.size(); ++index) {
|
|
CWorldViewField* field = this->worlds[index]->FindField(mapIndex, name);
|
|
if (field && this->worlds[index]->maps[mapIndex]->id >= 100) {
|
|
WorldViewRecord mark;
|
|
mark.mapIndex = mapIndex;
|
|
mark.level = 0;
|
|
mark.worldIndex = index;
|
|
mark.name = field->name;
|
|
mark.areaFlags = field->areaFlags;
|
|
mark.left = field->left;
|
|
mark.top = field->top;
|
|
mark.right = field->right;
|
|
mark.bottom = field->bottom;
|
|
this->marks.push_back(mark);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// OFFSET: 0x00617070
|
|
// FUNCTION: fn_04381
|
|
void CWorldViewMgr::ClearMarks() {
|
|
this->marks.clear();
|
|
}
|
|
|
|
// OFFSET: 0x006171D0
|
|
// FUNCTION: fn_04382
|
|
WorldViewRecord* CWorldViewMgr::MarkAt(unsigned int index, bool currentWorldOnly) {
|
|
if (static_cast<int>(index) >= 0 && this->marks.size() > index) {
|
|
WorldViewRecord* mark = &this->marks[index];
|
|
if (!currentWorldOnly || mark->worldIndex == this->currentWorld) {
|
|
return mark;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
// OFFSET: 0x00617220
|
|
// FUNCTION: fn_04383
|
|
int* CWorldViewMgr::MarkAreaAt(unsigned int index, bool currentWorldOnly) {
|
|
if (static_cast<int>(index) >= 0 && this->marks.size() > index) {
|
|
WorldViewRecord* mark = &this->marks[index];
|
|
if (!currentWorldOnly || mark->worldIndex == this->currentWorld) {
|
|
return &mark->left;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
// OFFSET: 0x00617270
|
|
// FUNCTION: fn_04384
|
|
int CWorldViewMgr::MarkCount() {
|
|
return static_cast<int>(this->marks.size());
|
|
}
|
|
|
|
// OFFSET: 0x00617290
|
|
// FUNCTION: fn_04385
|
|
int CWorldViewMgr::SelectCurrentWorld() {
|
|
return this->currentWorld = this->FindWorld(-1);
|
|
}
|
|
|
|
// OFFSET: 0x006172E0
|
|
// FUNCTION: fn_04386
|
|
bool CWorldViewMgr::AddLevel(const char* name, int level) {
|
|
if (!name) {
|
|
return false;
|
|
}
|
|
|
|
if (WorldViewRecord* found = FindRecord(this->levels, name)) {
|
|
if (level != 0) {
|
|
const int current = found->level;
|
|
if (level == 10000) {
|
|
if (current < 10000) {
|
|
found->level = current + 10000;
|
|
}
|
|
} else if (current < 10000) {
|
|
if (current < level) {
|
|
found->level = level;
|
|
}
|
|
} else if (current - 10000 < level) {
|
|
found->level = level + 10000;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
unsigned int mapIndex = static_cast<unsigned int>(-1);
|
|
for (unsigned int index = 0; index < this->worlds.size(); ++index) {
|
|
CWorldViewField* field = this->worlds[index]->FindField(mapIndex, name);
|
|
if (field && this->worlds[index]->maps[mapIndex]->id >= 100) {
|
|
WorldViewRecord record;
|
|
record.mapIndex = mapIndex;
|
|
record.worldIndex = index;
|
|
record.name = field->name;
|
|
record.areaFlags = field->areaFlags;
|
|
record.left = field->left;
|
|
record.top = field->top;
|
|
record.right = field->right;
|
|
record.bottom = field->bottom;
|
|
record.level = level;
|
|
this->levels.push_back(record);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// OFFSET: 0x006175D0
|
|
// FUNCTION: fn_04387
|
|
void CWorldViewMgr::ClearLevels() {
|
|
this->levels.clear();
|
|
}
|
|
|
|
// OFFSET: 0x00617730
|
|
// FUNCTION: fn_04388
|
|
int* CWorldViewMgr::LevelAreaAt(int& kind, unsigned int index, bool currentWorldOnly) {
|
|
if (static_cast<int>(index) >= 0 && this->levels.size() > index && (!currentWorldOnly || this->levels[index].worldIndex == this->currentWorld)) {
|
|
int base = 10;
|
|
int value = this->levels[index].level;
|
|
if (value < 10000) {
|
|
base = kind;
|
|
}
|
|
value %= 10000;
|
|
|
|
if (value > 99) {
|
|
kind = base + 5;
|
|
return &this->levels[index].left;
|
|
}
|
|
if (value > 49) {
|
|
kind = base + 4;
|
|
return &this->levels[index].left;
|
|
}
|
|
if (value >= 20 && value < 50) {
|
|
kind = base + 3;
|
|
return &this->levels[index].left;
|
|
}
|
|
if (value >= 5 && value < 20) {
|
|
kind = base + 2;
|
|
return &this->levels[index].left;
|
|
}
|
|
kind = base + (value >= 1 && value < 5 ? 1 : 0);
|
|
return &this->levels[index].left;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
// OFFSET: 0x00617860
|
|
// FUNCTION: fn_04389
|
|
int CWorldViewMgr::LevelCount() {
|
|
return static_cast<int>(this->levels.size());
|
|
}
|
|
|
|
// OFFSET: 0x00617940
|
|
// FUNCTION: fn_04390
|
|
CWorldViewWorld* CWorldViewMgr::CurrentWorld() {
|
|
return this->worlds[this->currentWorld];
|
|
}
|
|
|
|
// OFFSET: 0x00617950
|
|
// FUNCTION: fn_04391
|
|
bool __stdcall IsMapDisplayNameTranslated(const char* mapName) {
|
|
const std::string placeholder = LookupMessage(MSI_NOWHERE);
|
|
const std::string displayName = g_session.GetMapDisplayName(mapName);
|
|
return placeholder != displayName;
|
|
}
|
|
|
|
// OFFSET: 0x00615450
|
|
// FUNCTION: fn_04373
|
|
void CWorldViewMgr::Load(LuaScript& script) {
|
|
if (!script.Load("Lua Files\\worldviewdata\\worldviewdata_Language", true, false) ||
|
|
!script.Load("Lua Files\\worldviewdata\\worldviewdata_list", true, false) ||
|
|
!script.Load("Lua Files\\worldviewdata\\worldviewdata_table", true, false) ||
|
|
!script.Load("Lua Files\\worldviewdata\\worldviewdata_f", true, false) ||
|
|
!script.Load("Lua Files\\worldviewdata\\worldviewdata_Info", true, false)) {
|
|
return;
|
|
}
|
|
|
|
WorldViewArea area = {};
|
|
for (int worldIndex = 1; worldIndex < 400; ++worldIndex) {
|
|
const char* worldName = nullptr;
|
|
const char* mapTable = nullptr;
|
|
const char* fieldTable = nullptr;
|
|
const char* imageName = nullptr;
|
|
if (!script.Call("queryWorld_List", "d>ssss", worldIndex, &worldName, &mapTable, &fieldTable, &imageName)) {
|
|
char error[260] = {};
|
|
std::sprintf(error, "queryWorld_List // Line %d 읽기 실패", worldIndex);
|
|
MessageBoxA(hWnd, error, "Error", 0);
|
|
break;
|
|
}
|
|
if (!worldName) {
|
|
break;
|
|
}
|
|
|
|
CWorldViewWorld* world = new CWorldViewWorld(worldName, imageName);
|
|
this->worlds.push_back(world);
|
|
if (mapTable) {
|
|
const std::string tableName(mapTable);
|
|
if (!tableName.empty()) {
|
|
for (int index = 1; index < 400; ++index) {
|
|
int mapId = -1;
|
|
const char* mapName = nullptr;
|
|
const char* fieldName = nullptr;
|
|
const char* description = nullptr;
|
|
area.left = -1;
|
|
area.top = -1;
|
|
area.right = -1;
|
|
area.bottom = -1;
|
|
if (!script.Call("querymaptable_load", "sd>dsddddss", mapTable, index, &mapId, &mapName,
|
|
&area.left, &area.top, &area.right, &area.bottom, &fieldName, &description)) {
|
|
char error[260] = {};
|
|
std::sprintf(error, "querymaptable_load // %s Line %d 읽기 실패", mapTable, worldIndex);
|
|
MessageBoxA(hWnd, error, "Error", 0);
|
|
break;
|
|
}
|
|
if (!mapName) {
|
|
break;
|
|
}
|
|
if (IsMapDisplayNameTranslated(mapName)) {
|
|
CWorldViewField* field = new CWorldViewField(area, mapName, fieldName, description);
|
|
world->AddField(mapId, mapName, field);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (fieldTable) {
|
|
const std::string tableName(fieldTable);
|
|
if (!tableName.empty()) {
|
|
for (int index = 1; index < 400; ++index) {
|
|
int mapId = -1;
|
|
const char* mapName = nullptr;
|
|
const char* displayName = nullptr;
|
|
area.left = -1;
|
|
area.top = -1;
|
|
area.right = -1;
|
|
area.bottom = -1;
|
|
if (!script.Call("queryfieldtable_load", "sd>dddddss", fieldTable, index, &mapId,
|
|
&area.left, &area.top, &area.right, &area.bottom, &mapName, &displayName)) {
|
|
char error[260] = {};
|
|
std::sprintf(error, "queryfieldtable_load // %s Line %d 읽기 실패", fieldTable, worldIndex);
|
|
MessageBoxA(hWnd, error, "Error", 0);
|
|
break;
|
|
}
|
|
if (!mapName) {
|
|
break;
|
|
}
|
|
if (CWorldViewMap* map = world->FindMap(mapId)) {
|
|
map->displayName = displayName;
|
|
map->name = mapName;
|
|
map->left = area.left;
|
|
map->top = area.top;
|
|
map->right = area.right;
|
|
map->bottom = area.bottom;
|
|
map->areaFlags = area.areaFlags;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int red = 0;
|
|
int green = 0;
|
|
int blue = 0;
|
|
int fourth = 0;
|
|
int fifth = 0;
|
|
int sixth = 0;
|
|
int alpha = 0;
|
|
if (script.Call("Get_Worldview_info_Dungeon", ">dddd", &red, &green, &blue, &this->dungeonOverlayColor)) {
|
|
const std::uint32_t opacity = g_worldViewMgr.dungeonOverlayColor << 24;
|
|
this->dungeonColor = opacity + RGB(blue, green, red);
|
|
this->dungeonOverlayColor = opacity + 0xFFFFFF;
|
|
}
|
|
if (script.Call("Get_Worldview_info_Dungeon_FontColor", ">dddddd", &red, &green, &blue, &fourth, &fifth, &sixth)) {
|
|
this->dungeonFontColor = RGB(red, green, blue);
|
|
this->dungeonFontOutline = RGB(fourth, fifth, sixth);
|
|
}
|
|
if (script.Call("Get_Worldview_info_Dungeon_FontSize", ">dddd", &red, &green, &blue, &fourth)) {
|
|
this->dungeonFontSize[0] = red;
|
|
this->dungeonFontSize[1] = green;
|
|
this->dungeonFontSize[2] = blue;
|
|
this->dungeonFontSize[3] = fourth;
|
|
}
|
|
if (script.Call("Get_Worldview_info_Dungeon_SelectColor", ">ddd", &red, &green, &blue)) {
|
|
this->dungeonSelectTextColor = RGB(red, green, blue);
|
|
this->dungeonSelectColor = RGB(blue, green, red);
|
|
}
|
|
if (script.Call("Get_Worldview_info_Mob_Color", ">dddddd", &red, &green, &blue, &fourth, &fifth, &sixth)) {
|
|
this->mobColor = RGB(red, green, blue);
|
|
this->mobOutline = RGB(fourth, fifth, sixth);
|
|
}
|
|
if (script.Call("Get_Worldview_info_Mob_font", ">dddd", &red, &green, &blue, &fourth)) {
|
|
this->mobFont[0] = red;
|
|
this->mobFont[1] = green;
|
|
this->mobFont[2] = blue;
|
|
this->mobFont[3] = fourth;
|
|
}
|
|
if (script.Call("Get_Worldview_info_MobLv_Color", ">dddddd", &red, &green, &blue, &fourth, &fifth, &sixth)) {
|
|
this->mobLevelColor = RGB(red, green, blue);
|
|
this->mobLevelOutline = RGB(fourth, fifth, sixth);
|
|
}
|
|
if (script.Call("Get_Worldview_info_MobLv_font", ">dddd", &red, &green, &blue, &fourth)) {
|
|
this->mobLevelFont[0] = red;
|
|
this->mobLevelFont[1] = green;
|
|
this->mobLevelFont[2] = blue;
|
|
this->mobLevelFont[3] = fourth;
|
|
}
|
|
if (script.Call("Get_Worldview_info_BoxLine_Color", ">ddd", &red, &green, &blue)) {
|
|
this->boxLineColor = RGB(blue, green, red);
|
|
}
|
|
if (script.Call("Get_Worldview_info_Sreach_Alpha", ">ddddddd", &red, &green, &blue, &fourth, &fifth, &sixth, &alpha)) {
|
|
this->searchColors[0] = static_cast<std::uint32_t>(red) << 24;
|
|
this->searchColors[1] = static_cast<std::uint32_t>(green) << 24;
|
|
this->searchColors[2] = static_cast<std::uint32_t>(blue) << 24;
|
|
this->searchColors[3] = static_cast<std::uint32_t>(fourth) << 24;
|
|
this->searchColors[4] = static_cast<std::uint32_t>(fifth) << 24;
|
|
this->searchColors[5] = static_cast<std::uint32_t>(sixth) << 24;
|
|
this->searchColors[10] = static_cast<std::uint32_t>(alpha) << 24;
|
|
for (int index = 0; index < 16; ++index) {
|
|
if (script.Call("Get_Worldview_info_Sreach_Color", "d>ddd", index, &red, &green, &blue)) {
|
|
this->searchColors[index] += RGB(blue, green, red);
|
|
}
|
|
}
|
|
this->searchColors[11] = this->searchColors[1];
|
|
this->searchColors[12] = this->searchColors[2];
|
|
this->searchColors[13] = this->searchColors[3];
|
|
this->searchColors[14] = this->searchColors[4];
|
|
this->searchColors[15] = this->searchColors[5];
|
|
}
|
|
if (script.Call("Get_Worldview_info_Run", ">dddd", &red, &green, &blue, &alpha)) {
|
|
this->runColor = (static_cast<std::uint32_t>(alpha) << 24) + RGB(blue, green, red);
|
|
}
|
|
if (script.Call("Get_Worldview_info_Run_fontColor", ">dddddd", &red, &green, &blue, &fourth, &fifth, &sixth)) {
|
|
this->runFontColor = RGB(red, green, blue);
|
|
this->runFontOutline = RGB(fourth, fifth, sixth);
|
|
}
|
|
if (script.Call("Get_Worldview_info_Run_font", ">dddd", &red, &green, &blue, &fourth)) {
|
|
this->runFont[0] = red;
|
|
this->runFont[1] = green;
|
|
this->runFont[2] = blue;
|
|
this->runFont[3] = fourth;
|
|
}
|
|
if (script.Call("Get_Worldview_info_SelectBox_Color", ">dddd", &red, &green, &blue, &fourth)) {
|
|
this->selectBoxColor = (static_cast<std::uint32_t>(fourth) << 24) + RGB(blue, green, red);
|
|
}
|
|
}
|