2023-01-02 13:17:18 -06:00
|
|
|
#include "glue/CCharacterSelection.hpp"
|
2025-04-06 00:17:11 +04:00
|
|
|
#include "model/CM2Model.hpp"
|
2023-02-19 21:39:21 -06:00
|
|
|
#include "model/CM2Shared.hpp"
|
|
|
|
|
#include "ui/CSimpleModelFFX.hpp"
|
2025-03-29 23:43:21 +04:00
|
|
|
#include "client/ClientServices.hpp"
|
2025-04-05 01:42:43 +04:00
|
|
|
#include "client/Client.hpp"
|
|
|
|
|
#include "console/CVar.hpp"
|
2025-03-29 23:43:21 +04:00
|
|
|
#include "net/Connection.hpp"
|
2025-04-06 00:17:11 +04:00
|
|
|
#include "clientobject/Player_C.hpp"
|
|
|
|
|
#include "db/Db.hpp"
|
2023-01-02 13:17:18 -06:00
|
|
|
|
2025-04-05 01:42:43 +04:00
|
|
|
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;
|
2023-01-02 13:17:18 -06:00
|
|
|
TSGrowableArray<CharacterSelectionDisplay> CCharacterSelection::s_characterList;
|
2025-04-05 01:42:43 +04:00
|
|
|
int32_t CCharacterSelection::m_selectionIndex = 0;
|
|
|
|
|
|
2023-02-19 21:39:21 -06:00
|
|
|
|
2025-04-06 00:17:11 +04:00
|
|
|
CharacterSelectionDisplay::CharacterSelectionDisplay()
|
|
|
|
|
: m_characterModel(nullptr) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-02-22 21:37:37 -06:00
|
|
|
void CCharacterSelection::RenderPrep() {
|
|
|
|
|
// TODO
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-19 21:39:21 -06:00
|
|
|
void CCharacterSelection::SetBackgroundModel(const char* modelPath) {
|
2025-04-05 01:42:43 +04:00
|
|
|
if (!CCharacterSelection::m_modelFrame || !modelPath || !*modelPath) {
|
2023-02-19 21:39:21 -06:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-05 01:42:43 +04:00
|
|
|
auto model = CCharacterSelection::m_modelFrame->m_model;
|
2023-02-19 21:39:21 -06:00
|
|
|
|
|
|
|
|
// Check if already set
|
|
|
|
|
if (model && !SStrCmpI(modelPath, model->m_shared->m_filePath, STORM_MAX_STR)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-05 01:42:43 +04:00
|
|
|
CCharacterSelection::m_modelFrame->SetModel(modelPath);
|
2023-02-19 21:39:21 -06:00
|
|
|
|
|
|
|
|
// TODO BYTE1(CCharacterSelection::m_modelFrame->simplemodelffx_dword510[3]) = 1;
|
|
|
|
|
|
2025-04-05 01:42:43 +04:00
|
|
|
model = CCharacterSelection::m_modelFrame->m_model;
|
2023-02-19 21:39:21 -06:00
|
|
|
|
|
|
|
|
if (model) {
|
|
|
|
|
// TODO lighting callback + arg
|
|
|
|
|
|
|
|
|
|
model->IsDrawable(1, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-03-29 23:37:24 +04:00
|
|
|
|
2025-04-05 01:42:43 +04:00
|
|
|
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() {
|
2025-04-06 00:17:11 +04:00
|
|
|
auto index = CCharacterSelection::m_selectionIndex;
|
|
|
|
|
if (index < 0 || index >= CCharacterSelection::GetNumCharacters()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-04-05 01:42:43 +04:00
|
|
|
// TODO
|
2025-04-06 00:17:11 +04:00
|
|
|
|
|
|
|
|
CCharacterSelection::m_charFacing = 0.0;
|
|
|
|
|
|
|
|
|
|
auto& character = CCharacterSelection::s_characterList[index];
|
|
|
|
|
|
|
|
|
|
if (character.m_characterModel) {
|
|
|
|
|
// TODO
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto rec = Player_C_GetModelName(character.m_characterInfo.raceID, character.m_characterInfo.sexID);
|
|
|
|
|
STORM_ASSERT(rec);
|
|
|
|
|
if (!rec->m_modelName) {
|
|
|
|
|
// TODO
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto scene = CCharacterSelection::m_modelFrame->GetScene();
|
|
|
|
|
character.m_characterModel = scene->CreateModel(rec->m_modelName, 0);
|
2025-04-05 01:42:43 +04:00
|
|
|
}
|
|
|
|
|
|
2025-03-29 23:37:24 +04:00
|
|
|
void CCharacterSelection::SetCharFacing(float facing) {
|
2025-04-06 00:17:11 +04:00
|
|
|
if (!CCharacterSelection::m_characterCount || !CCharacterSelection::GetNumCharacters()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto character = CCharacterSelection::s_characterList[CCharacterSelection::m_selectionIndex];
|
|
|
|
|
if (character.m_characterModel) {
|
|
|
|
|
character.m_characterModel->SetWorldTransform(C3Vector(), facing, 1.0);
|
|
|
|
|
}
|
2025-03-29 23:37:24 +04:00
|
|
|
}
|
2025-03-29 23:43:21 +04:00
|
|
|
|
|
|
|
|
void CCharacterSelection::ClearCharacterList() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CCharacterSelection::UpdateCharacterList() {
|
|
|
|
|
// TODO: ClearAddOnEnableState(0);
|
|
|
|
|
|
2025-04-05 01:42:43 +04:00
|
|
|
CCharacterSelection::s_characterList.SetCount(0);
|
|
|
|
|
|
|
|
|
|
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();
|
2025-03-29 23:43:21 +04:00
|
|
|
|
2025-04-05 01:42:43 +04:00
|
|
|
FrameScript_SignalEvent(8, "%d", CCharacterSelection::m_selectionIndex + 1);
|
2025-03-29 23:43:21 +04:00
|
|
|
} else {
|
2025-04-05 01:42:43 +04:00
|
|
|
CCharacterSelection::m_selectionIndex = 0;
|
|
|
|
|
CCharacterSelection::ShowCharacter();
|
|
|
|
|
FrameScript_SignalEvent(8, "%d", CCharacterSelection::m_selectionIndex + 1);
|
|
|
|
|
if (CCharacterSelection::m_modelFrame) {
|
|
|
|
|
// TODO
|
|
|
|
|
}
|
2025-03-29 23:43:21 +04:00
|
|
|
}
|
|
|
|
|
FrameScript_SignalEvent(7, nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t CCharacterSelection::GetNumCharacters() {
|
2025-04-06 00:17:11 +04:00
|
|
|
return CCharacterSelection::s_characterList.Count();
|
2025-03-29 23:43:21 +04:00
|
|
|
}
|