#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 "ui/CSimpleModelFFX.hpp" int32_t CCharacterSelection::s_characterCount; TSGrowableArray 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->m_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->m_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].m_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]; // Create character component and pet model if (!character->m_component) { character->CreateModelData(); } if (!character->m_component) { return; } // Attach character display to model frame auto parent = CCharacterSelection::s_modelFrame->m_model; if (!parent) { return; } auto characterModel = character->m_component->m_data.model; auto petModel = character->m_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->m_component, 0); } 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); }