diff --git a/src/client/ClientServices.cpp b/src/client/ClientServices.cpp index da6060a..93744f0 100644 --- a/src/client/ClientServices.cpp +++ b/src/client/ClientServices.cpp @@ -12,6 +12,7 @@ ClientConnection* g_clientConnection; char ClientServices::s_accountName[1280]; +CHARACTER_INFO ClientServices::s_characterInfo; RealmResponse* ClientServices::s_clientRealmResponse; ClientConnection* ClientServices::s_currentConnection; CVar* ClientServices::s_darkPortalVar; @@ -266,6 +267,12 @@ void ClientServices::SetAccountName(const char* accountName) { SStrCopy(ClientServices::s_accountName, accountName, sizeof(ClientServices::s_accountName)); } +void ClientServices::SetCharacterInfo(const CHARACTER_INFO* info) { + STORM_ASSERT(info); + + ClientServices::s_characterInfo = *info; +} + void ClientServices::SetMessageHandler(NETMESSAGE msgId, MESSAGE_HANDLER handler, void* param) { STORM_ASSERT(handler); STORM_ASSERT(ClientServices::s_currentConnection); diff --git a/src/client/ClientServices.hpp b/src/client/ClientServices.hpp index 93968f2..f925154 100644 --- a/src/client/ClientServices.hpp +++ b/src/client/ClientServices.hpp @@ -13,6 +13,7 @@ class ClientServices : public LoginResponse { public: // Static variables static char s_accountName[1280]; + static CHARACTER_INFO s_characterInfo; static RealmResponse* s_clientRealmResponse; static ClientConnection* s_currentConnection; static CVar* s_darkPortalVar; @@ -42,6 +43,7 @@ class ClientServices : public LoginResponse { static void Logon(const char* accountName, const char* password); static void SelectRealm(const char* realmName); static void SetAccountName(const char* accountName); + static void SetCharacterInfo(const CHARACTER_INFO* info); static void SetMessageHandler(NETMESSAGE msgId, MESSAGE_HANDLER handler, void* param); static int32_t SetSelectedRealmInfo(int32_t a1); diff --git a/src/glue/CCharacterSelection.cpp b/src/glue/CCharacterSelection.cpp index 236e4d8..7c4ed13 100644 --- a/src/glue/CCharacterSelection.cpp +++ b/src/glue/CCharacterSelection.cpp @@ -7,6 +7,7 @@ #include "ui/CSimpleModelFFX.hpp" TSGrowableArray CCharacterSelection::s_characterList; +int32_t CCharacterSelection::s_enterWorldIndex; CSimpleModelFFX* CCharacterSelection::s_modelFrame; uint32_t CCharacterSelection::s_restrictHuman; uint32_t CCharacterSelection::s_restrictDwarf; @@ -35,6 +36,14 @@ void CCharacterSelection::EnumerateCharactersCallback(const CHARACTER_INFO& info // TODO } +const CharacterSelectionDisplay* CCharacterSelection::GetSelectedCharacter() { + if (CCharacterSelection::s_selectionIndex < 0 || CCharacterSelection::s_selectionIndex >= CCharacterSelection::s_characterList.Count()) { + return nullptr; + } + + return &CCharacterSelection::s_characterList[CCharacterSelection::s_selectionIndex]; +} + void CCharacterSelection::OnGetCharacterList() { CCharacterSelection::s_characterList.SetCount(0); diff --git a/src/glue/CCharacterSelection.hpp b/src/glue/CCharacterSelection.hpp index 0bcbf3c..ff8eb8d 100644 --- a/src/glue/CCharacterSelection.hpp +++ b/src/glue/CCharacterSelection.hpp @@ -15,6 +15,7 @@ class CCharacterSelection { public: // Static variables static TSGrowableArray s_characterList; + static int32_t s_enterWorldIndex; static CSimpleModelFFX* s_modelFrame; static uint32_t s_restrictHuman; static uint32_t s_restrictDwarf; @@ -32,6 +33,7 @@ class CCharacterSelection { static void ClearCharacterList(); static void ClearCharacterModel(); static void EnumerateCharactersCallback(const CHARACTER_INFO& info, void* param); + static const CharacterSelectionDisplay* GetSelectedCharacter(); static void OnGetCharacterList(); static void RenderPrep(); static void SetBackgroundModel(const char* modelPath); diff --git a/src/glue/CGlueMgr.cpp b/src/glue/CGlueMgr.cpp index 5c8c4be..161ca7f 100644 --- a/src/glue/CGlueMgr.cpp +++ b/src/glue/CGlueMgr.cpp @@ -52,6 +52,7 @@ int32_t CGlueMgr::m_accountMsgAvailable; char CGlueMgr::m_accountName[1280]; float CGlueMgr::m_aspect; bool CGlueMgr::m_authenticated; +const CharacterSelectionDisplay* CGlueMgr::m_characterInfo; char CGlueMgr::m_currentScreen[64]; int32_t CGlueMgr::m_disconnectPending; int32_t CGlueMgr::m_displayingQueueDialog; @@ -112,7 +113,95 @@ void CGlueMgr::ChangeRealm(const REALM_INFO* realmInfo) { } void CGlueMgr::EnterWorld() { - // TODO + if (!ClientServices::GetSelectedRealm()) { + return; + } + + auto character = CCharacterSelection::GetSelectedCharacter(); + CGlueMgr::m_characterInfo = character; + + if (!character) { + return; + } + + CCharacterSelection::s_enterWorldIndex = CCharacterSelection::s_selectionIndex; + + if (!ClientServices::Connection()->IsConnected()) { + return; + } + + // Validate character flags + + auto flags = CGlueMgr::m_characterInfo->info.flags; + + if (flags & 0x4) { + // TODO + // auto errorToken = ClientServices::GetErrorToken(84); + // auto errorText = FrameScript_GetText(errorToken, -1, GENDER_NOT_APPLICABLE); + // FrameScript_SignalEvent(3, "%s%s", "OKAY", errorText); + + return; + } + + if (flags & 0x1000000) { + // TODO + // auto errorToken = ClientServices::GetErrorToken(85); + // auto errorText = FrameScript_GetText(errorToken, -1, GENDER_NOT_APPLICABLE); + // FrameScript_SignalEvent(3, "%s%s", "OKAY", errorText); + + return; + } + + if (flags & 0x4000) { + FrameScript_SignalEvent(23, "%s", "CHAR_RENAME_DESCRIPTION"); + + return; + } + + if (!(flags & 0x2000000)) { + if (NameNeedsDeclension(CURRENT_LANGUAGE, CGlueMgr::m_characterInfo->info.name)) { + FrameScript_SignalEvent(24, nullptr); + + return; + } + } + + // Validate expansion + + auto raceRec = g_chrRacesDB.GetRecord(character->info.raceID); + auto classRec = g_chrClassesDB.GetRecord(character->info.classID); + + if ( + !raceRec + || !classRec + || ClientServices::Connection()->m_accountExpansion < raceRec->m_requiredExpansion + || ClientServices::Connection()->m_accountExpansion < classRec->m_requiredExpansion + ) { + // TODO + // auto errorToken = ClientServices::GetErrorToken(82); + // auto errorText = FrameScript_GetText(errorToken, -1, GENDER_NOT_APPLICABLE); + // FrameScript_SignalEvent(3, "%s%s", "OKAY", errorText); + + return; + } + + char indexStr[32]; + SStrPrintf(indexStr, sizeof(indexStr), "%d", CCharacterSelection::s_selectionIndex); + // TODO g_lastCharacterIndex->Set(indexStr, 1, 0, 0, 1); + + ClientServices::SetAccountName(CGlueMgr::m_accountName); + ClientServices::SetCharacterInfo(&CGlueMgr::m_characterInfo->info); + + // TODO game tip + // TODO loading screen + // TODO save all cvars + + if (ClientServices::LoginConnection()->GetLoginServerType() == 0) { + ClientServices::LoginConnection()->Logoff(); + } + + CGlueMgr::m_idleState = IDLE_ENTER_WORLD; + CGlueMgr::m_showedDisconnect = 0; } void CGlueMgr::DisplayLoginStatus() { diff --git a/src/glue/CGlueMgr.hpp b/src/glue/CGlueMgr.hpp index 83b3f04..4358f03 100644 --- a/src/glue/CGlueMgr.hpp +++ b/src/glue/CGlueMgr.hpp @@ -7,6 +7,7 @@ class CDataStore; class CSimpleTop; +struct CharacterSelectionDisplay; class CGlueMgr { public: @@ -36,6 +37,7 @@ class CGlueMgr { static char m_accountName[]; static float m_aspect; static bool m_authenticated; + static const CharacterSelectionDisplay* m_characterInfo; static char m_currentScreen[]; static int32_t m_disconnectPending; static int32_t m_displayingQueueDialog; diff --git a/src/glue/Character.cpp b/src/glue/Character.cpp index 871a292..3e38192 100644 --- a/src/glue/Character.cpp +++ b/src/glue/Character.cpp @@ -1,5 +1,11 @@ #include "glue/Character.hpp" +bool NameNeedsDeclension(WOW_LOCALE locale, const char* name) { + // TODO + + return false; +} + void ValidateNameInitialize(int32_t localeMask, int32_t charsetMask) { // TODO } diff --git a/src/glue/Character.hpp b/src/glue/Character.hpp index d6e40ae..0750a7b 100644 --- a/src/glue/Character.hpp +++ b/src/glue/Character.hpp @@ -1,8 +1,11 @@ #ifndef GLUE_CHARACTER_HPP #define GLUE_CHARACTER_HPP +#include "util/Locale.hpp" #include +bool NameNeedsDeclension(WOW_LOCALE locale, const char* name); + void ValidateNameInitialize(int32_t localeMask, int32_t charsetMask); #endif