From 77cb9ed9664a64d4fe4953caa5327d2cf489b8ef Mon Sep 17 00:00:00 2001 From: VDm Date: Sun, 18 May 2025 01:52:28 +0400 Subject: [PATCH] feat(ui): add background support for character creation screen --- src/glue/CCharacterCreation.cpp | 7 +++ src/glue/CCharacterCreation.hpp | 1 + src/net/Types.hpp | 2 +- src/ui/ScriptFunctionsCharCreate.cpp | 89 ++++++++++++++++++++++++++-- 4 files changed, 92 insertions(+), 7 deletions(-) diff --git a/src/glue/CCharacterCreation.cpp b/src/glue/CCharacterCreation.cpp index 9eeaed2..c1dd388 100644 --- a/src/glue/CCharacterCreation.cpp +++ b/src/glue/CCharacterCreation.cpp @@ -5,6 +5,7 @@ #include "clientobject/Player_C.hpp" #include "db/Db.hpp" +int32_t CCharacterCreation::m_selectedClassID; int32_t CCharacterCreation::m_existingCharacterIndex; int32_t CCharacterCreation::m_raceIndex; CSimpleModel* CCharacterCreation::m_charCustomizeFrame; @@ -95,6 +96,12 @@ void CCharacterCreation::ResetCharCustomizeInfo() { // TODO CCharacterCreation::m_raceIndex = -1; + for (uint32_t i = 0; i < CCharacterCreation::m_races.Count(); ++i) { + if (CCharacterCreation::m_races[i] == CCharacterCreation::m_character->m_data.m_info.raceID) { + CCharacterCreation::m_raceIndex = i; + break; + } + } // TODO } diff --git a/src/glue/CCharacterCreation.hpp b/src/glue/CCharacterCreation.hpp index 579d72d..13521a3 100644 --- a/src/glue/CCharacterCreation.hpp +++ b/src/glue/CCharacterCreation.hpp @@ -15,6 +15,7 @@ class ChrClassesRec; class CCharacterCreation { public: // Static variables + static int32_t m_selectedClassID; static int32_t m_existingCharacterIndex; static int32_t m_raceIndex; static CSimpleModel* m_charCustomizeFrame; diff --git a/src/net/Types.hpp b/src/net/Types.hpp index 35c58f3..bc4fecb 100644 --- a/src/net/Types.hpp +++ b/src/net/Types.hpp @@ -1289,7 +1289,7 @@ struct CHARACTER_INFO { struct CHARACTER_CREATE_INFO { uint32_t raceID; uint32_t sexID; - uint32_t unk; + uint32_t classID; uint32_t hairColorID; uint32_t skinID; uint32_t faceID; diff --git a/src/ui/ScriptFunctionsCharCreate.cpp b/src/ui/ScriptFunctionsCharCreate.cpp index 17b7809..3135ea9 100644 --- a/src/ui/ScriptFunctionsCharCreate.cpp +++ b/src/ui/ScriptFunctionsCharCreate.cpp @@ -148,23 +148,73 @@ int32_t Script_GetClassesForRace(lua_State* L) { } int32_t Script_GetHairCustomization(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + int32_t raceID = 0; + + if (CCharacterCreation::m_raceIndex >= 0 && CCharacterCreation::m_raceIndex < CCharacterCreation::m_races.Count()) { + raceID = CCharacterCreation::m_races[CCharacterCreation::m_raceIndex]; + } + + auto record = g_chrRacesDB.GetRecord(raceID); + lua_pushstring(L, record ? record->m_hairCustomization : "NORMAL"); + return 1; } int32_t Script_GetFacialHairCustomization(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + int32_t raceID = 0; + + if (CCharacterCreation::m_raceIndex >= 0 && CCharacterCreation::m_raceIndex < CCharacterCreation::m_races.Count()) { + raceID = CCharacterCreation::m_races[CCharacterCreation::m_raceIndex]; + } + + auto record = g_chrRacesDB.GetRecord(raceID); + if (record) { + auto sexID = CCharacterCreation::m_character->m_data.m_info.sexID; + lua_pushstring(L, record->m_facialHairCustomization[sexID]); + } else { + lua_pushstring(L, "NORMAL"); + } + return 1; } int32_t Script_GetSelectedRace(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + lua_pushnumber(L, CCharacterCreation::m_raceIndex + 1.0); + return 1; } int32_t Script_GetSelectedSex(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + // TODO: g_glueFrameScriptGenders[CCharacterCreation::m_character->m_data.m_info.sexID] + lua_pushnumber(L, 2.0); + return 1; } int32_t Script_GetSelectedClass(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto record = g_chrClassesDB.GetRecord(CCharacterCreation::m_selectedClassID); + if (!record) { + return 0; + } + auto className = CGUnit_C::GetDisplayClassNameFromRecord( + record, + CCharacterCreation::m_character->m_data.m_info.sexID); + + lua_pushstring(L, className); + lua_pushstring(L, record->m_filename); + + int32_t index = 0; + + for (int32_t i = 0; i < g_chrClassesDB.GetNumRecords(); ++i) { + record = g_chrClassesDB.GetRecordByIndex(i); + if (record && record->m_ID == CCharacterCreation::m_selectedClassID) { + index = i; + } + } + + lua_pushnumber(L, index + 1); + // TODO: uint8_t roles = CGLookingForGroup::GetClassRoles(CCharacterCreation::m_selectedClassID); + uint8_t roles = 0; + lua_pushboolean(L, roles & 2); + lua_pushboolean(L, roles & 4); + lua_pushboolean(L, roles & 8); + return 6; } int32_t Script_SetSelectedRace(lua_State* L) { @@ -240,7 +290,34 @@ int32_t Script_IsRaceClassRestricted(lua_State* L) { } int32_t Script_GetCreateBackgroundModel(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + // TODO + if (false /* SFile::IsTrial() */) { + lua_pushstring(L, "CharacterSelect"); + return 1; + } + + if (CCharacterCreation::m_selectedClassID == 6) { + auto record = g_chrClassesDB.GetRecord(6); + if (record) { + lua_pushstring(L, record->m_filename); + return 1; + } + } else { + int32_t raceID = CCharacterCreation::m_character->m_data.m_info.raceID; + if (raceID == 7) { + raceID = 3; + } else if (raceID == 8) { + raceID = 2; + } + + auto record = g_chrRacesDB.GetRecord(raceID); + if (record) { + lua_pushstring(L, record->m_clientFileString); + return 1; + } + } + lua_pushstring(L, ""); + return 1; } FrameScript_Method FrameScript::s_ScriptFunctions_CharCreate[NUM_SCRIPT_FUNCTIONS_CHAR_CREATE] = {