diff --git a/src/glue/CCharacterCreation.cpp b/src/glue/CCharacterCreation.cpp index ab7b3df..b275e23 100644 --- a/src/glue/CCharacterCreation.cpp +++ b/src/glue/CCharacterCreation.cpp @@ -254,8 +254,75 @@ void CCharacterCreation::RandomizeCharFeatures() { CCharacterCreation::m_prevFacialFeatureIndex = info.facialFeatureID; } -void CCharacterCreation::SetSelectedRace(int32_t raceID) { - // TODO +void CCharacterCreation::SetSelectedRace(int32_t raceIndex) { + if (raceIndex < 0 || + raceIndex >= CCharacterCreation::m_races.Count() || + raceIndex == CCharacterCreation::m_raceIndex) { + return; + } + + auto previousRace = CCharacterCreation::m_races[CCharacterCreation::m_raceIndex]; + auto sexID = CCharacterCreation::m_character->m_data.m_info.sexID; + + auto preferences = CCharacterCreation::m_charPreferences[2 * previousRace + sexID]; + if (!preferences) { + preferences = NEW(CHARACTER_CREATE_INFO); + CCharacterCreation::m_charPreferences[2 * previousRace + sexID] = preferences; + } + + CCharacterCreation::m_character->GetInfo(preferences); + CCharacterCreation::m_raceIndex = raceIndex; + + ComponentData data; + + if (CCharacterCreation::m_existingCharacterIndex >= 0) { + auto display = CCharacterSelection::GetCharacterDisplay(CCharacterCreation::m_existingCharacterIndex); + if (display && display->m_characterInfo.sexID == sexID && + (display->m_characterInfo.customizeFlags & 1)) { + data.m_info.raceID = display->m_characterInfo.raceID; + data.m_info.sexID = display->m_characterInfo.sexID; + data.m_info.classID = display->m_characterInfo.classID; + data.m_info.skinID = display->m_characterInfo.skinID; + data.m_info.hairStyleID = display->m_characterInfo.hairStyleID; + data.m_info.hairColorID = display->m_characterInfo.hairColorID; + data.m_info.facialFeatureID = display->m_characterInfo.facialHairStyleID; + data.m_info.faceID = display->m_characterInfo.faceID; + + CCharacterCreation::InitCharacterComponent(&data, 0); + CCharacterCreation::SetSelectedSex(display->m_characterInfo.sexID); + + // TODO: CNameGen::LoadNames + CCharacterCreation::Dress(); + CCharacterCreation::Sub4E6AE0(CCharacterCreation::m_character, 1); + return; + } + } + + auto raceID = CCharacterCreation::m_races[CCharacterCreation::m_raceIndex]; + preferences = CCharacterCreation::m_charPreferences[2 * raceID + sexID]; + if (preferences) { + data.m_info = *preferences; + CCharacterCreation::CalcClasses(data.m_info.raceID); + if (!CCharacterCreation::IsRaceClassValid(data.m_info.raceID, CCharacterCreation::m_selectedClassID)) { + CCharacterCreation::m_selectedClassID = CCharacterCreation::GetRandomClassID(); + } + data.m_info.classID = CCharacterCreation::m_selectedClassID; + CCharacterComponent::ValidateComponentData(&data); + CCharacterCreation::InitCharacterComponent(&data, 0); + } else { + data.m_info.sexID = sexID; + data.m_info.raceID = raceID; + CCharacterCreation::CalcClasses(data.m_info.raceID); + if (!CCharacterCreation::IsRaceClassValid(data.m_info.raceID, CCharacterCreation::m_selectedClassID)) { + CCharacterCreation::SetSelectedClass(CCharacterCreation::GetRandomClassID()); + } + data.m_info.classID = CCharacterCreation::m_selectedClassID; + CCharacterCreation::InitCharacterComponent(&data, 1); + } + + // TODO: CNameGen::LoadNames + CCharacterCreation::Dress(); + CCharacterCreation::Sub4E6AE0(CCharacterCreation::m_character, 1); } void CCharacterCreation::SetSelectedSex(int32_t sexID) { diff --git a/src/glue/CCharacterCreation.hpp b/src/glue/CCharacterCreation.hpp index ef8d326..a9e322a 100644 --- a/src/glue/CCharacterCreation.hpp +++ b/src/glue/CCharacterCreation.hpp @@ -50,7 +50,7 @@ class CCharacterCreation { static void Dress(); static void InitCharacterComponent(ComponentData* data, int32_t randomize); static void RandomizeCharFeatures(); - static void SetSelectedRace(int32_t raceID); + static void SetSelectedRace(int32_t raceIndex); static void SetSelectedSex(int32_t sexID); static void SetSelectedClass(int32_t classID); static void CycleCharCustomization(CHAR_CUSTOMIZATION_TYPE customization, int32_t delta); diff --git a/src/ui/CSimpleCheckbox.cpp b/src/ui/CSimpleCheckbox.cpp index 64b455d..cbf79a1 100644 --- a/src/ui/CSimpleCheckbox.cpp +++ b/src/ui/CSimpleCheckbox.cpp @@ -1,5 +1,6 @@ #include "ui/CSimpleCheckbox.hpp" #include "ui/CSimpleCheckboxScript.hpp" +#include "ui/CSimpleTexture.hpp" int32_t CSimpleCheckbox::s_metatable; int32_t CSimpleCheckbox::s_objectType; @@ -23,14 +24,53 @@ void CSimpleCheckbox::RegisterScriptMethods(lua_State* L) { FrameScript_Object::FillScriptMethodTable(L, SimpleCheckboxMethods, NUM_SIMPLE_CHECKBOX_SCRIPT_METHODS); } -CSimpleCheckbox::CSimpleCheckbox(CSimpleFrame* parent) : CSimpleButton(parent) { - // TODO +CSimpleCheckbox::CSimpleCheckbox(CSimpleFrame* parent) + : CSimpleButton(parent) { } int32_t CSimpleCheckbox::GetScriptMetaTable() { return CSimpleCheckbox::s_metatable; } +void CSimpleCheckbox::Enable(int32_t enabled) { + this->CSimpleButton::Enable(enabled); + this->SetChecked(this->m_checked, 1); +} + +void CSimpleCheckbox::SetChecked(int32_t state, int32_t force) { + if (state == this->m_checked && !force) { + return; + } + + this->m_checked = state; + if (this->m_checkedTexture) { + this->m_checkedTexture->Hide(); + } + + if (this->m_disabledTexture) { + this->m_disabledTexture->Hide(); + } + + if (this->m_checked) { + if (!this->m_disabledTexture || this->m_state) { + if (this->m_checkedTexture) { + this->m_checkedTexture->Show(); + } + } else { + this->m_disabledTexture->Show(); + } + } +} + +int32_t CSimpleCheckbox::GetChecked() { + return this->m_checked; +} + +void CSimpleCheckbox::OnClick(const char* btn, int32_t a3) { + this->SetChecked(this->m_checked == 0, 0); + this->CSimpleButton::OnClick(btn, a3); +} + bool CSimpleCheckbox::IsA(int32_t type) { return type == CSimpleCheckbox::s_objectType || type == CSimpleButton::s_objectType diff --git a/src/ui/CSimpleCheckbox.hpp b/src/ui/CSimpleCheckbox.hpp index 3435844..4a86152 100644 --- a/src/ui/CSimpleCheckbox.hpp +++ b/src/ui/CSimpleCheckbox.hpp @@ -15,10 +15,17 @@ class CSimpleCheckbox : public CSimpleButton { static void RegisterScriptMethods(lua_State* L); // Member variables + int32_t m_checked = 0; + CSimpleTexture* m_checkedTexture = nullptr; + CSimpleTexture* m_disabledTexture = nullptr; // Virtual member functions virtual bool IsA(int32_t type); virtual int32_t GetScriptMetaTable(); + virtual void Enable(int32_t enabled); + virtual void SetChecked(int32_t state, int32_t force); + virtual int32_t GetChecked(); + virtual void OnClick(const char* btn, int32_t a3); // Member functions CSimpleCheckbox(CSimpleFrame* parent); diff --git a/src/ui/CSimpleCheckboxScript.cpp b/src/ui/CSimpleCheckboxScript.cpp index 073c8e1..5f8717a 100644 --- a/src/ui/CSimpleCheckboxScript.cpp +++ b/src/ui/CSimpleCheckboxScript.cpp @@ -1,13 +1,26 @@ #include "ui/CSimpleCheckboxScript.hpp" +#include "ui/CSimpleCheckbox.hpp" +#include "util/Lua.hpp" +#include "util/StringTo.hpp" #include "util/Unimplemented.hpp" -#include + int32_t CSimpleCheckbox_SetChecked(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleCheckbox::GetObjectType(); + auto checkbox = static_cast(FrameScript_GetObjectThis(L, type)); + + int32_t state = StringToBOOL(L, 2, 0); + checkbox->SetChecked(state, 0); + return 0; } int32_t CSimpleCheckbox_GetChecked(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleCheckbox::GetObjectType(); + auto checkbox = static_cast(FrameScript_GetObjectThis(L, type)); + + lua_Number state = checkbox->GetChecked() ? 1.0 : 0.0; + lua_pushnumber(L, state); + return 1; } int32_t CSimpleCheckbox_GetCheckedTexture(lua_State* L) {