whoa/src/glue/CCharacterSelection.cpp

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);
}