diff --git a/src/glue/CCharacterCreation.cpp b/src/glue/CCharacterCreation.cpp index 712fbae..9eeaed2 100644 --- a/src/glue/CCharacterCreation.cpp +++ b/src/glue/CCharacterCreation.cpp @@ -15,7 +15,8 @@ uint32_t CCharacterCreation::m_prevHairColorIndex; uint32_t CCharacterCreation::m_prevHairStyleIndex; uint32_t CCharacterCreation::m_prevFacialFeatureIndex; CCharacterComponent* CCharacterCreation::m_character = nullptr; -TSGrowableArray CCharacterCreation::m_races; +TSGrowableArray CCharacterCreation::m_classes; +TSGrowableArray CCharacterCreation::m_races; void CCharacterCreation::Initialize() { CCharacterCreation::m_charFacing = 0.0; @@ -27,10 +28,8 @@ void CCharacterCreation::Initialize() { bool weirdCondition = false; - do - { - for (int32_t raceIndex = 0; raceIndex < g_chrRacesDB.GetNumRecords(); ++raceIndex) - { + do { + for (int32_t raceIndex = 0; raceIndex < g_chrRacesDB.GetNumRecords(); ++raceIndex) { auto raceRecord = g_chrRacesDB.GetRecordByIndex(raceIndex); if (!raceRecord || (raceRecord->m_flags & 1) != 0) { continue; @@ -55,8 +54,7 @@ void CCharacterCreation::Initialize() { continue; } - uint32_t raceID = raceRecord->m_ID; - CCharacterCreation::m_races.Add(1, &raceID); + CCharacterCreation::m_races.Add(1, &raceRecord->m_ID); factionSwitch = factionSwitch2; } @@ -108,6 +106,28 @@ void CCharacterCreation::GetRandomRaceAndSex(ComponentData* data) { } void CCharacterCreation::CalcClasses(uint32_t raceID) { + uint32_t count = 0; + + for (int32_t i = 0; i < g_charBaseInfoDB.GetNumRecords(); ++i) { + auto record = g_charBaseInfoDB.GetRecordByIndex(i); + if (record && record->m_raceID == raceID) { + ++count; + } + } + + CCharacterCreation::m_classes.SetCount(count); + + uint32_t index = 0; + + for (int32_t i = 0; i < g_charBaseInfoDB.GetNumRecords(); ++i) { + auto record = g_charBaseInfoDB.GetRecordByIndex(i); + if (!record || record->m_raceID != raceID) { + continue; + } + + CCharacterCreation::m_classes[index] = g_chrClassesDB.GetRecord(record->m_classID); + ++index; + } } void CCharacterCreation::InitCharacterComponent(ComponentData* data, int32_t randomize) { diff --git a/src/glue/CCharacterCreation.hpp b/src/glue/CCharacterCreation.hpp index 79a2d22..579d72d 100644 --- a/src/glue/CCharacterCreation.hpp +++ b/src/glue/CCharacterCreation.hpp @@ -9,6 +9,7 @@ class CSimpleModelFFX; class CM2Model; class ComponentData; class CCharacterComponent; +class ChrClassesRec; class CCharacterCreation { @@ -24,7 +25,8 @@ class CCharacterCreation { static uint32_t m_prevHairStyleIndex; static uint32_t m_prevFacialFeatureIndex; static CCharacterComponent* m_character; - static TSGrowableArray m_races; + static TSGrowableArray m_classes; + static TSGrowableArray m_races; // Static functions static void Initialize(); diff --git a/src/ui/ScriptFunctionsCharCreate.cpp b/src/ui/ScriptFunctionsCharCreate.cpp index 3e91140..17b7809 100644 --- a/src/ui/ScriptFunctionsCharCreate.cpp +++ b/src/ui/ScriptFunctionsCharCreate.cpp @@ -58,19 +58,93 @@ int32_t Script_GetNameForRace(lua_State* L) { } int32_t Script_GetFactionForRace(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + if (!lua_isnumber(L, 1)) { + return luaL_error(L, "Usage: GetFactionForRace(index)"); + } + + uint32_t index = static_cast(lua_tonumber(L, 1)) - 1; + int32_t raceID = 0; + if (index < CCharacterCreation::m_races.Count()) { + raceID = CCharacterCreation::m_races[index]; + } + + auto raceRecord = g_chrRacesDB.GetRecord(raceID); + if (raceRecord) { + auto factionTemplateRecord = g_factionTemplateDB.GetRecord(raceRecord->m_factionID); + if (factionTemplateRecord) { + for (int32_t i = 0; i < g_factionGroupDB.GetNumRecords(); ++i) { + auto factionGroupRecord = g_factionGroupDB.GetRecordByIndex(i); + if (!factionGroupRecord || factionGroupRecord->m_maskID == 0) { + continue; + } + + if (((1 << factionGroupRecord->m_maskID) & factionTemplateRecord->m_factionGroup) != 0) { + lua_pushstring(L, factionGroupRecord->m_name); + lua_pushstring(L, factionGroupRecord->m_internalName); + return 2; + } + } + } + } + + lua_pushnil(L); + lua_pushnil(L); + return 2; } int32_t Script_GetAvailableRaces(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + for (uint32_t i = 0; i < CCharacterCreation::m_races.Count(); ++i) { + auto raceRecord = g_chrRacesDB.GetRecord(CCharacterCreation::m_races[i]); + auto raceName = CGUnit_C::GetDisplayRaceNameFromRecord( + raceRecord, + CCharacterCreation::m_character->m_data.m_info.sexID); + + lua_pushstring(L, raceName); + lua_pushstring(L, raceRecord ? raceRecord->m_clientFileString : nullptr); + // TODO: Expansion Check + lua_pushnumber(L, 1.0); + } + return CCharacterCreation::m_races.Count() * 3; } int32_t Script_GetAvailableClasses(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + for (int32_t i = 0; i < g_chrClassesDB.GetNumRecords(); ++i) { + auto record = g_chrClassesDB.GetRecordByIndex(i); + auto className = CGUnit_C::GetDisplayClassNameFromRecord( + record, + CCharacterCreation::m_character->m_data.m_info.sexID); + if (className) { + lua_pushstring(L, className); + lua_pushstring(L, record->m_filename); + // TODO: Expansion Check + lua_pushnumber(L, 1.0); + } else { + lua_pushnil(L); + lua_pushnil(L); + lua_pushnil(L); + } + } + return g_chrClassesDB.GetNumRecords() * 3; } int32_t Script_GetClassesForRace(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + for (uint32_t i = 0; i < CCharacterCreation::m_classes.Count(); ++i) { + auto record = CCharacterCreation::m_classes[i]; + auto className = CGUnit_C::GetDisplayClassNameFromRecord( + record, + CCharacterCreation::m_character->m_data.m_info.sexID); + if (className) { + lua_pushstring(L, className); + lua_pushstring(L, record->m_filename); + // TODO: Expansion Check + lua_pushnumber(L, 1.0); + } else { + lua_pushnil(L); + lua_pushnil(L); + lua_pushnil(L); + } + } + return CCharacterCreation::m_classes.Count() * 3; } int32_t Script_GetHairCustomization(lua_State* L) {