mirror of
https://github.com/whoahq/whoa.git
synced 2026-02-01 00:02:45 +03:00
292 lines
9.0 KiB
C++
292 lines
9.0 KiB
C++
#include "glue/CCharacterSelection.hpp"
|
|
#include "client/ClientServices.hpp"
|
|
#include "component/CCharacterComponent.hpp"
|
|
#include "db/Db.hpp"
|
|
#include "glue/CGlueLoading.hpp"
|
|
#include "glue/CGlueMgr.hpp"
|
|
#include "glue/CRealmList.hpp"
|
|
#include "glue/Types.hpp"
|
|
#include "model/CM2Shared.hpp"
|
|
#include "net/Connection.hpp"
|
|
#include "object/client/Player_C.hpp"
|
|
#include "ui/CSimpleModelFFX.hpp"
|
|
|
|
int32_t CCharacterSelection::s_characterCount;
|
|
TSGrowableArray<CharacterSelectionDisplay> CCharacterSelection::s_characterList;
|
|
float CCharacterSelection::s_charFacing;
|
|
int32_t CCharacterSelection::s_enterWorldIndex;
|
|
CSimpleModelFFX* CCharacterSelection::s_modelFrame;
|
|
uint32_t CCharacterSelection::s_restrictHuman;
|
|
uint32_t CCharacterSelection::s_restrictDwarf;
|
|
uint32_t CCharacterSelection::s_restrictGnome;
|
|
uint32_t CCharacterSelection::s_restrictNightElf;
|
|
uint32_t CCharacterSelection::s_restrictDraenei;
|
|
uint32_t CCharacterSelection::s_restrictOrc;
|
|
uint32_t CCharacterSelection::s_restrictTroll;
|
|
uint32_t CCharacterSelection::s_restrictTauren;
|
|
uint32_t CCharacterSelection::s_restrictUndead;
|
|
uint32_t CCharacterSelection::s_restrictBloodElf;
|
|
int32_t CCharacterSelection::s_selectionIndex;
|
|
|
|
void CCharacterSelection::ClearCharacterList() {
|
|
CCharacterSelection::s_characterList.SetCount(0);
|
|
|
|
CCharacterSelection::ClearCharacterModel();
|
|
|
|
CCharacterSelection::s_selectionIndex = 0;
|
|
CCharacterSelection::ShowCharacter();
|
|
|
|
FrameScript_SignalEvent(UPDATE_SELECTED_CHARACTER, "%d", CCharacterSelection::s_selectionIndex + 1);
|
|
|
|
if (CCharacterSelection::s_modelFrame) {
|
|
CCharacterSelection::s_modelFrame->SetCameraByIndex(0);
|
|
}
|
|
|
|
FrameScript_SignalEvent(CHARACTER_LIST_UPDATE, nullptr);
|
|
}
|
|
|
|
void CCharacterSelection::ClearCharacterModel() {
|
|
if (!CCharacterSelection::s_modelFrame) {
|
|
return;
|
|
}
|
|
|
|
auto model = CCharacterSelection::s_modelFrame->m_model;
|
|
|
|
if (model) {
|
|
model->DetachAllChildrenById(0);
|
|
|
|
// Might be an inlined function (perhaps ClearPetModel)
|
|
model->DetachAllChildrenById(1);
|
|
}
|
|
}
|
|
|
|
void CCharacterSelection::EnumerateCharactersCallback(const CHARACTER_INFO& info, void* param) {
|
|
auto display = CCharacterSelection::s_characterList.New();
|
|
display->info = info;
|
|
|
|
// TODO
|
|
}
|
|
|
|
const CharacterSelectionDisplay* CCharacterSelection::GetCharacterDisplay(int32_t index) {
|
|
if (index < 0 || index >= CCharacterSelection::s_characterList.Count()) {
|
|
return nullptr;
|
|
}
|
|
|
|
return &CCharacterSelection::s_characterList[index];
|
|
}
|
|
|
|
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);
|
|
|
|
CCharacterSelection::ClearCharacterModel();
|
|
|
|
CGlueMgr::GetCharacterList();
|
|
}
|
|
|
|
void CCharacterSelection::RenderPrep() {
|
|
auto character = CCharacterSelection::GetSelectedCharacter();
|
|
if (!character) {
|
|
return;
|
|
}
|
|
|
|
auto component = character->component;
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->RenderPrep(0);
|
|
}
|
|
|
|
void CCharacterSelection::SetBackgroundModel(const char* modelPath) {
|
|
if (!CCharacterSelection::s_modelFrame || !modelPath || !*modelPath) {
|
|
return;
|
|
}
|
|
|
|
auto model = CCharacterSelection::s_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);
|
|
|
|
// TODO BYTE1(CCharacterSelection::m_modelFrame->simplemodelffx_dword510[3]) = 1;
|
|
|
|
model = CCharacterSelection::s_modelFrame->m_model;
|
|
|
|
if (model) {
|
|
// TODO lighting callback + arg
|
|
|
|
model->IsDrawable(1, 1);
|
|
}
|
|
}
|
|
|
|
void CCharacterSelection::SetFacing(float facing) {
|
|
if (!CCharacterSelection::s_characterCount) {
|
|
return;
|
|
}
|
|
|
|
CCharacterSelection::s_charFacing = facing;
|
|
|
|
if (!CCharacterSelection::s_characterList.Count()) {
|
|
return;
|
|
}
|
|
|
|
auto component = CCharacterSelection::s_characterList[CCharacterSelection::s_selectionIndex].component;
|
|
auto model = component->m_data.model;
|
|
|
|
if (!model) {
|
|
return;
|
|
}
|
|
|
|
C3Vector position = { 0.0f, 0.0f, 0.0f };
|
|
model->SetWorldTransform(position, facing, 1.0f);
|
|
}
|
|
|
|
void CCharacterSelection::ShowCharacter() {
|
|
if (CCharacterSelection::s_selectionIndex < 0 || CCharacterSelection::s_selectionIndex >= CCharacterSelection::s_characterList.Count()) {
|
|
return;
|
|
}
|
|
|
|
CCharacterSelection::ClearCharacterModel();
|
|
|
|
CCharacterSelection::s_charFacing = 0.0f;
|
|
|
|
auto character = &CCharacterSelection::s_characterList[CCharacterSelection::s_selectionIndex];
|
|
|
|
if (character->component) {
|
|
auto parent = CCharacterSelection::s_modelFrame->m_model;
|
|
|
|
if (!parent) {
|
|
return;
|
|
}
|
|
|
|
auto characterModel = character->component->m_data.model;
|
|
auto petModel = character->petModel;
|
|
|
|
characterModel->AttachToParent(parent, 0, nullptr, 0);
|
|
|
|
CCharacterSelection::SetFacing(0.0f);
|
|
|
|
if (petModel) {
|
|
petModel->AttachToParent(parent, 1, nullptr, 0);
|
|
}
|
|
|
|
// TODO a2 may be 1 in some circumstances
|
|
CGlueLoading::StartLoad(character->component, 0);
|
|
|
|
return;
|
|
}
|
|
|
|
auto modelData = Player_C_GetModelName(character->info.raceID, character->info.sexID);
|
|
if (!modelData || !modelData->m_modelName) {
|
|
return;
|
|
}
|
|
|
|
character->component = CCharacterComponent::AllocComponent();
|
|
|
|
ComponentData componentData = {};
|
|
componentData.raceID = character->info.raceID;
|
|
componentData.sexID = character->info.sexID;
|
|
componentData.skinColorID = character->info.skinColorID;
|
|
componentData.faceID = character->info.faceID;
|
|
componentData.hairStyleID = character->info.hairStyleID;
|
|
componentData.hairColorID = character->info.hairColorID;
|
|
componentData.facialHairStyleID = character->info.facialHairStyleID;
|
|
|
|
auto scene = CCharacterSelection::s_modelFrame->GetScene();
|
|
auto model = scene->CreateModel(modelData->m_modelName, 0);
|
|
|
|
componentData.flags |= 0x2;
|
|
componentData.model = model;
|
|
|
|
character->component->Init(&componentData, nullptr);
|
|
|
|
// TODO lighting callback/arg
|
|
|
|
character->component->m_data.model->SetBoneSequence(
|
|
0xFFFFFFFF,
|
|
0,
|
|
0xFFFFFFFF,
|
|
0,
|
|
1.0f,
|
|
1,
|
|
1
|
|
);
|
|
|
|
// TODO load pet model
|
|
|
|
CCharacterSelection::s_characterCount++;
|
|
|
|
// TODO
|
|
}
|
|
|
|
void CCharacterSelection::UpdateCharacterList() {
|
|
// TODO
|
|
|
|
CCharacterSelection::s_characterList.SetCount(0);
|
|
|
|
CCharacterSelection::s_restrictHuman = 0;
|
|
CCharacterSelection::s_restrictDwarf = 0;
|
|
CCharacterSelection::s_restrictGnome = 0;
|
|
CCharacterSelection::s_restrictNightElf = 0;
|
|
CCharacterSelection::s_restrictDraenei = 0;
|
|
CCharacterSelection::s_restrictOrc = 0;
|
|
CCharacterSelection::s_restrictTroll = 0;
|
|
CCharacterSelection::s_restrictTauren = 0;
|
|
CCharacterSelection::s_restrictUndead = 0;
|
|
CCharacterSelection::s_restrictBloodElf = 0;
|
|
|
|
// Enumerate characters
|
|
|
|
ClientServices::Connection()->EnumerateCharacters(CCharacterSelection::EnumerateCharactersCallback, nullptr);
|
|
|
|
// No characters
|
|
|
|
if (CCharacterSelection::s_characterList.Count() == 0) {
|
|
CCharacterSelection::s_selectionIndex = 0;
|
|
CCharacterSelection::ShowCharacter();
|
|
|
|
FrameScript_SignalEvent(8, "%d", CCharacterSelection::s_selectionIndex + 1);
|
|
|
|
CCharacterSelection::ClearCharacterModel();
|
|
|
|
FrameScript_SignalEvent(7, nullptr);
|
|
|
|
return;
|
|
}
|
|
|
|
// At least one character
|
|
|
|
CCharacterSelection::s_restrictHuman = ClientServices::Connection()->m_restrictHuman;
|
|
CCharacterSelection::s_restrictDwarf = ClientServices::Connection()->m_restrictDwarf;
|
|
CCharacterSelection::s_restrictGnome = ClientServices::Connection()->m_restrictGnome;
|
|
CCharacterSelection::s_restrictNightElf = ClientServices::Connection()->m_restrictNightElf;
|
|
CCharacterSelection::s_restrictDraenei = ClientServices::Connection()->m_restrictDraenei;
|
|
CCharacterSelection::s_restrictOrc = ClientServices::Connection()->m_restrictOrc;
|
|
CCharacterSelection::s_restrictTroll = ClientServices::Connection()->m_restrictTroll;
|
|
CCharacterSelection::s_restrictTauren = ClientServices::Connection()->m_restrictTauren;
|
|
CCharacterSelection::s_restrictUndead = ClientServices::Connection()->m_restrictUndead;
|
|
CCharacterSelection::s_restrictBloodElf = ClientServices::Connection()->m_restrictBloodElf;
|
|
|
|
CRealmList::s_preferredCategory = 0;
|
|
|
|
// TODO g_lastCharacterIndex stuff
|
|
int32_t selectionIndex = 0;
|
|
|
|
CCharacterSelection::s_selectionIndex = selectionIndex;
|
|
CCharacterSelection::ShowCharacter();
|
|
|
|
FrameScript_SignalEvent(8, "%d", CCharacterSelection::s_selectionIndex + 1);
|
|
FrameScript_SignalEvent(7, nullptr);
|
|
}
|