mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-04-18 19:12:44 +03:00
feat(glue): update Character Selection screen to support switching
This commit is contained in:
parent
bf734b5b20
commit
0c39457ed1
@ -33,6 +33,7 @@ CVar* Client::g_accountUsesTokenVar;
|
||||
CVar* Client::g_movieVar;
|
||||
CVar* Client::g_expansionMovieVar;
|
||||
CVar* Client::g_movieSubtitleVar;
|
||||
CVar* Client::g_lastCharacterIndex;
|
||||
|
||||
|
||||
HEVENTCONTEXT Client::g_clientEventContext;
|
||||
@ -83,6 +84,7 @@ void ClientRegisterConsoleCommands() {
|
||||
Client::g_movieVar = CVar::Register("movie", "Show movie on startup", 0, "1", nullptr, game);
|
||||
Client::g_expansionMovieVar = CVar::Register("expansionMovie", "Show expansion movie on startup", 0, "1", nullptr, game);
|
||||
Client::g_movieSubtitleVar = CVar::Register("movieSubtitle", "Show movie subtitles", 0, "0", nullptr, game);
|
||||
Client::g_lastCharacterIndex = CVar::Register("lastCharacterIndex", "Last character selected", 0, "0", nullptr, game);
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ namespace Client {
|
||||
extern CVar* g_movieVar;
|
||||
extern CVar* g_expansionMovieVar;
|
||||
extern CVar* g_movieSubtitleVar;
|
||||
extern CVar* g_lastCharacterIndex;
|
||||
extern HEVENTCONTEXT g_clientEventContext;
|
||||
extern char g_currentLocaleName[5];
|
||||
}
|
||||
|
@ -73,9 +73,15 @@ void ClientServices::GetRealmList() {
|
||||
}
|
||||
|
||||
void ClientServices::GetCharacterList() {
|
||||
STORM_ASSERT(ClientServices::s_currentConnection);
|
||||
ClientServices::s_currentConnection->GetCharacterList();
|
||||
}
|
||||
|
||||
void ClientServices::EnumerateCharacters(ENUMERATE_CHARACTERS_CALLBACK fcn, void* param) {
|
||||
STORM_ASSERT(ClientServices::s_currentConnection);
|
||||
ClientServices::s_currentConnection->EnumerateCharacters(fcn, param);
|
||||
}
|
||||
|
||||
void ClientServices::CharacterLogin(uint64_t id, const C3Vector& position) {
|
||||
ClientServices::s_currentConnection->CharacterLogin(id);
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ class ClientServices : public LoginResponse {
|
||||
static void SetMessageHandler(NETMESSAGE msgId, MESSAGE_HANDLER handler, void* param);
|
||||
static void GetRealmList();
|
||||
static void GetCharacterList();
|
||||
static void EnumerateCharacters(ENUMERATE_CHARACTERS_CALLBACK fcn, void* param);
|
||||
static void CharacterLogin(uint64_t id, const C3Vector& position);
|
||||
static REALM_INFO* GetRealmInfoByIndex(int32_t index);
|
||||
static const char* GetSelectedRealmName();
|
||||
|
@ -2,33 +2,48 @@
|
||||
#include "model/CM2Shared.hpp"
|
||||
#include "ui/CSimpleModelFFX.hpp"
|
||||
#include "client/ClientServices.hpp"
|
||||
#include "client/Client.hpp"
|
||||
#include "console/CVar.hpp"
|
||||
#include "net/Connection.hpp"
|
||||
|
||||
CSimpleModelFFX* CCharacterSelection::m_modelFrame = nullptr;
|
||||
uint32_t CCharacterSelection::m_characterCount = 0;
|
||||
float CCharacterSelection::m_charFacing = 0.0f;
|
||||
uint32_t CCharacterSelection::m_restrictHuman = 0;
|
||||
uint32_t CCharacterSelection::m_restrictDwarf = 0;
|
||||
uint32_t CCharacterSelection::m_restrictGnome = 0;
|
||||
uint32_t CCharacterSelection::m_restrictNightElf = 0;
|
||||
uint32_t CCharacterSelection::m_restrictDraenei = 0;
|
||||
uint32_t CCharacterSelection::m_restrictOrc = 0;
|
||||
uint32_t CCharacterSelection::m_restrictTroll = 0;
|
||||
uint32_t CCharacterSelection::m_restrictTauren = 0;
|
||||
uint32_t CCharacterSelection::m_restrictUndead = 0;
|
||||
uint32_t CCharacterSelection::m_restrictBloodElf = 0;
|
||||
TSGrowableArray<CharacterSelectionDisplay> CCharacterSelection::s_characterList;
|
||||
CSimpleModelFFX* CCharacterSelection::s_modelFrame;
|
||||
float CCharacterSelection::s_charFacing = 0.0f;
|
||||
int32_t CCharacterSelection::m_selectionIndex = 0;
|
||||
|
||||
|
||||
void CCharacterSelection::RenderPrep() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCharacterSelection::SetBackgroundModel(const char* modelPath) {
|
||||
if (!CCharacterSelection::s_modelFrame || !modelPath || !*modelPath) {
|
||||
if (!CCharacterSelection::m_modelFrame || !modelPath || !*modelPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto model = CCharacterSelection::s_modelFrame->m_model;
|
||||
auto model = CCharacterSelection::m_modelFrame->m_model;
|
||||
|
||||
// Check if already set
|
||||
if (model && !SStrCmpI(modelPath, model->m_shared->m_filePath, STORM_MAX_STR)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CCharacterSelection::s_modelFrame->SetModel(modelPath);
|
||||
CCharacterSelection::m_modelFrame->SetModel(modelPath);
|
||||
|
||||
// TODO BYTE1(CCharacterSelection::m_modelFrame->simplemodelffx_dword510[3]) = 1;
|
||||
|
||||
model = CCharacterSelection::s_modelFrame->m_model;
|
||||
model = CCharacterSelection::m_modelFrame->m_model;
|
||||
|
||||
if (model) {
|
||||
// TODO lighting callback + arg
|
||||
@ -37,8 +52,18 @@ void CCharacterSelection::SetBackgroundModel(const char* modelPath) {
|
||||
}
|
||||
}
|
||||
|
||||
void CCharacterSelection::EnumerateCharactersCallback(CHARACTER_INFO& info, void* param) {
|
||||
auto character = CCharacterSelection::s_characterList.New();
|
||||
character->m_characterInfo = info;
|
||||
// TODO: LoadAddOnEnableState(a1 + 8);
|
||||
}
|
||||
|
||||
void CCharacterSelection::ShowCharacter() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCharacterSelection::SetCharFacing(float facing) {
|
||||
// TODO:
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCharacterSelection::ClearCharacterList() {
|
||||
@ -46,20 +71,42 @@ void CCharacterSelection::ClearCharacterList() {
|
||||
|
||||
void CCharacterSelection::UpdateCharacterList() {
|
||||
// TODO: ClearAddOnEnableState(0);
|
||||
// TODO: Proper implementation
|
||||
|
||||
auto& received = ClientServices::Connection()->m_characterList;
|
||||
CCharacterSelection::s_characterList.SetCount(received.Count());
|
||||
for (uint32_t i = 0; i < received.Count(); ++i) {
|
||||
CCharacterSelection::s_characterList[i].m_characterInfo = received[i];
|
||||
}
|
||||
CCharacterSelection::s_characterList.SetCount(0);
|
||||
|
||||
if (CCharacterSelection::GetNumCharacters()) {
|
||||
int32_t currentIndex = 0;
|
||||
FrameScript_SignalEvent(8, "%d", currentIndex + 1);
|
||||
CCharacterSelection::m_restrictHuman = 0;
|
||||
CCharacterSelection::m_restrictDwarf = 0;
|
||||
CCharacterSelection::m_restrictGnome = 0;
|
||||
CCharacterSelection::m_restrictNightElf = 0;
|
||||
CCharacterSelection::m_restrictDraenei = 0;
|
||||
CCharacterSelection::m_restrictOrc = 0;
|
||||
CCharacterSelection::m_restrictTroll = 0;
|
||||
CCharacterSelection::m_restrictTauren = 0;
|
||||
CCharacterSelection::m_restrictUndead = 0;
|
||||
CCharacterSelection::m_restrictBloodElf = 0;
|
||||
|
||||
ClientServices::EnumerateCharacters(&CCharacterSelection::EnumerateCharactersCallback, nullptr);
|
||||
|
||||
if (CCharacterSelection::s_characterList.Count()) {
|
||||
// TODO: Apply restrictions (m_restrictHuman, etc)
|
||||
// TODO: CRealmList::m_preferredCategory = 0;
|
||||
|
||||
int32_t selectionIndex = Client::g_lastCharacterIndex->GetInt();
|
||||
if (selectionIndex < 0 || selectionIndex >= CCharacterSelection::s_characterList.Count()) {
|
||||
selectionIndex = 0;
|
||||
}
|
||||
|
||||
CCharacterSelection::m_selectionIndex = selectionIndex;
|
||||
CCharacterSelection::ShowCharacter();
|
||||
|
||||
FrameScript_SignalEvent(8, "%d", CCharacterSelection::m_selectionIndex + 1);
|
||||
} else {
|
||||
int32_t currentIndex = 0;
|
||||
FrameScript_SignalEvent(8, "%d", currentIndex + 1);
|
||||
CCharacterSelection::m_selectionIndex = 0;
|
||||
CCharacterSelection::ShowCharacter();
|
||||
FrameScript_SignalEvent(8, "%d", CCharacterSelection::m_selectionIndex + 1);
|
||||
if (CCharacterSelection::m_modelFrame) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
FrameScript_SignalEvent(7, nullptr);
|
||||
}
|
||||
|
@ -13,13 +13,27 @@ struct CharacterSelectionDisplay {
|
||||
class CCharacterSelection {
|
||||
public:
|
||||
// Static variables
|
||||
static CSimpleModelFFX* m_modelFrame;
|
||||
static uint32_t m_characterCount;
|
||||
static float m_charFacing;
|
||||
static uint32_t m_restrictHuman;
|
||||
static uint32_t m_restrictDwarf;
|
||||
static uint32_t m_restrictGnome;
|
||||
static uint32_t m_restrictNightElf;
|
||||
static uint32_t m_restrictDraenei;
|
||||
static uint32_t m_restrictOrc;
|
||||
static uint32_t m_restrictTroll;
|
||||
static uint32_t m_restrictTauren;
|
||||
static uint32_t m_restrictUndead;
|
||||
static uint32_t m_restrictBloodElf;
|
||||
static TSGrowableArray<CharacterSelectionDisplay> s_characterList;
|
||||
static CSimpleModelFFX* s_modelFrame;
|
||||
static float s_charFacing;
|
||||
static int32_t m_selectionIndex;
|
||||
|
||||
// Static functions
|
||||
static void RenderPrep();
|
||||
static void SetBackgroundModel(const char* modelPath);
|
||||
static void EnumerateCharactersCallback(CHARACTER_INFO& info, void* param);
|
||||
static void ShowCharacter();
|
||||
static void SetCharFacing(float facing);
|
||||
static void ClearCharacterList();
|
||||
static void UpdateCharacterList();
|
||||
|
@ -1285,5 +1285,7 @@ struct CHARACTER_INFO {
|
||||
uint8_t firstLogin;
|
||||
};
|
||||
|
||||
typedef void (*ENUMERATE_CHARACTERS_CALLBACK)(CHARACTER_INFO&, void*);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -141,6 +141,13 @@ void ClientConnection::GetCharacterList() {
|
||||
}
|
||||
}
|
||||
|
||||
void ClientConnection::EnumerateCharacters(ENUMERATE_CHARACTERS_CALLBACK fcn, void* param) {
|
||||
STORM_ASSERT(fcn);
|
||||
for (uint32_t i = 0; i < this->m_characterList.Count(); ++i) {
|
||||
fcn(this->m_characterList[i], param);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientConnection::CharacterLogin(uint64_t id) {
|
||||
this->Initiate(COP_LOGIN_CHARACTER, 76, nullptr);
|
||||
if (this->m_connected) {
|
||||
|
@ -28,6 +28,7 @@ class ClientConnection : public RealmConnection {
|
||||
void AccountLogin_Finish(int32_t authResult);
|
||||
void AccountLogin_Queued();
|
||||
void GetCharacterList();
|
||||
void EnumerateCharacters(ENUMERATE_CHARACTERS_CALLBACK fcn, void* param);
|
||||
void CharacterLogin(uint64_t id);
|
||||
void Cancel(int32_t errorCode);
|
||||
void Cleanup();
|
||||
|
@ -19,7 +19,7 @@ int32_t Script_SetCharSelectModelFrame(lua_State* L) {
|
||||
auto frame = CScriptObject::GetScriptObjectByName(name, type);
|
||||
|
||||
if (frame) {
|
||||
CCharacterSelection::s_modelFrame = static_cast<CSimpleModelFFX*>(frame);
|
||||
CCharacterSelection::m_modelFrame = static_cast<CSimpleModelFFX*>(frame);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -54,7 +54,7 @@ int32_t Script_GetCharacterInfo(lua_State* L) {
|
||||
luaL_error(L, "Usage: GetCharacterInfo(index)");
|
||||
}
|
||||
|
||||
int index = static_cast<int>(lua_tonumber(L, 1)) - 1;
|
||||
int32_t index = static_cast<int32_t>(lua_tonumber(L, 1)) - 1;
|
||||
if (index < 0 || index > CCharacterSelection::GetNumCharacters()) {
|
||||
lua_pushnil(L); // name
|
||||
lua_pushnil(L); // race
|
||||
@ -108,7 +108,19 @@ int32_t Script_GetCharacterInfo(lua_State* L) {
|
||||
}
|
||||
|
||||
int32_t Script_SelectCharacter(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED(0);
|
||||
if (!lua_isnumber(L, 1)) {
|
||||
luaL_error(L, "Usage: SelectCharacter(index)");
|
||||
}
|
||||
|
||||
int32_t index = static_cast<int32_t>(lua_tonumber(L, 1)) - 1;
|
||||
if (index < 1 || index >= CCharacterSelection::GetNumCharacters()) {
|
||||
index = 0;
|
||||
}
|
||||
|
||||
CCharacterSelection::m_selectionIndex = index;
|
||||
CCharacterSelection::ShowCharacter();
|
||||
FrameScript_SignalEvent(8u, "%d", CCharacterSelection::m_selectionIndex + 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_DeleteCharacter(lua_State* L) {
|
||||
@ -131,7 +143,7 @@ int32_t Script_UpdateSelectionCustomizationScene(lua_State* L) {
|
||||
|
||||
int32_t Script_GetCharacterSelectFacing(lua_State* L) {
|
||||
// Radian to Degree
|
||||
lua_pushnumber(L, CCharacterSelection::s_charFacing * 57.29578f);
|
||||
lua_pushnumber(L, CCharacterSelection::m_charFacing * 57.29578f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user