using System; using System.Text; using BrewMonster.Network; using CSNetwork; using CSNetwork.GPDataType; using CSNetwork.Protocols; using CSNetwork.Protocols.RPCData; using TMPro; using UnityEngine; using UnityEngine.UI; using BrewMonster.Scripts; namespace BrewMonster.UI { /// /// UI screen for creating a new character. /// Equivalent to CDlgCreateGenderName + CDlgCreateProfession in C++. /// public class CreateCharacterScreen : MonoBehaviour { [SerializeField] private GameObject professionSelectionPanel; [SerializeField] private Button[] professionButtons; [SerializeField] private Button maleGenderButton; [SerializeField] private Button femaleGenderButton; [SerializeField] private TMP_InputField nameInputField; [SerializeField] private Button confirmButton; [SerializeField] private Button cancelButton; [SerializeField] private Button backButton; private int _currentProfession = -1; private int _currentGender = -1; private Action _onCreateComplete; private Action _onCancel; // Static array matching s_bShowMale[NUM_PROFESSION] from original C++ code (EC_ProfConfigs.cpp) // true = show male, false = show female private static readonly bool[] s_bShowMale = new bool[] { true, // 0: Warrior (武侠) false, // 1: Mage (法师) false, // 2: Priest (巫师) false, // 3: Assassin (妖精) true, // 4: Orc (妖兽) true, // 5: Monk (刺客) true, // 6: Elf (羽芒) false, // 7: Elf (羽灵) true, // 8: Ling (剑灵) false, // 9: Ling (魅灵) true, // 10: Oboro (夜影) false, // 11: Oboro (月仙) }; private void Start() { if (confirmButton != null) confirmButton.onClick.AddListener(OnConfirmClicked); if (cancelButton != null) cancelButton.onClick.AddListener(OnCancelClicked); if (backButton != null) backButton.onClick.AddListener(OnCancelClicked); if (maleGenderButton != null) maleGenderButton.onClick.AddListener(() => OnGenderSelected(GENDER.GENDER_MALE)); if (femaleGenderButton != null) femaleGenderButton.onClick.AddListener(() => OnGenderSelected(GENDER.GENDER_FEMALE)); // Setup profession buttons if (professionButtons != null) { for (int i = 0; i < professionButtons.Length && i < 12; i++) { int prof = i; // Capture for closure if (professionButtons[i] != null) professionButtons[i].onClick.AddListener(() => OnProfessionSelected(prof)); } } if (nameInputField != null) { nameInputField.onSubmit.AddListener((text) => { if (CanConfirm()) OnConfirmClicked(); }); } } public void Show(Action onCreateComplete, Action onCancel) { _onCreateComplete = onCreateComplete; _onCancel = onCancel; _currentProfession = -1; _currentGender = -1; gameObject.SetActive(true); if (nameInputField != null) { nameInputField.text = ""; nameInputField.Select(); } UpdateConfirmButtonState(); } public void Hide() { gameObject.SetActive(false); } private void OnProfessionSelected(int profession) { if (profession < 0 || profession >= (int)Profession.NUM_PROFESSION) return; _currentProfession = profession; // Update UI to show selected profession if (professionButtons != null) { for (int i = 0; i < professionButtons.Length; i++) { if (professionButtons[i] != null) { // Visual feedback for selected profession var colors = professionButtons[i].colors; colors.normalColor = (i == profession) ? Color.yellow : Color.white; professionButtons[i].colors = colors; } } } // Auto-select gender based on profession (matching original C++ logic from EC_ProfConfigs.cpp) // This matches the s_bShowMale array in CanShowOnCreate function int autoGender = GetDefaultGenderForProfession(profession); OnGenderSelected(autoGender); UpdateConfirmButtonState(); } /// /// Gets the default gender for a profession based on the original C++ logic. /// Matches the s_bShowMale array from EC_ProfConfigs.cpp CanShowOnCreate function. /// private int GetDefaultGenderForProfession(int profession) { if (profession >= 0 && profession < s_bShowMale.Length) { return s_bShowMale[profession] ? GENDER.GENDER_MALE : GENDER.GENDER_FEMALE; } // Fallback to male if profession is invalid return GENDER.GENDER_MALE; } private void OnGenderSelected(int gender) { if (gender != GENDER.GENDER_MALE && gender != GENDER.GENDER_FEMALE) return; _currentGender = gender; // Update UI to show selected gender if (maleGenderButton != null) { var colors = maleGenderButton.colors; colors.normalColor = (gender == GENDER.GENDER_MALE) ? Color.yellow : Color.white; maleGenderButton.colors = colors; } if (femaleGenderButton != null) { var colors = femaleGenderButton.colors; colors.normalColor = (gender == GENDER.GENDER_FEMALE) ? Color.yellow : Color.white; femaleGenderButton.colors = colors; } UpdateConfirmButtonState(); } private void OnConfirmClicked() { if (!CanConfirm()) return; string characterName = nameInputField != null ? nameInputField.text : ""; if (string.IsNullOrWhiteSpace(characterName)) { Debug.LogWarning("Character name cannot be empty"); return; } // Create RoleInfo using helper method RoleInfo roleInfo = GameSession.CreateNewRoleInfo(characterName, _currentProfession, _currentGender); // Create role via network Debug.Log($"Calling CreateRoleAsync for character: {characterName}, profession: {_currentProfession}, gender: {_currentGender}"); UnityGameSession.CreateRoleAsync(roleInfo, new Octets(), (createdRole) => { if (createdRole != null) { Debug.Log($"Character created successfully: {characterName}, RoleID: {createdRole.roleid}"); Hide(); _onCreateComplete?.Invoke(createdRole); } else { Debug.LogError($"Failed to create character: {characterName}. Check GameSession logs for error details."); // TODO: Show error message to user } }); } private void OnCancelClicked() { Hide(); _onCancel?.Invoke(); } private bool CanConfirm() { if (_currentProfession < 0 || _currentProfession >= (int)Profession.NUM_PROFESSION) return false; if (_currentGender != GENDER.GENDER_MALE && _currentGender != GENDER.GENDER_FEMALE) return false; string name = nameInputField != null ? nameInputField.text : ""; if (string.IsNullOrWhiteSpace(name)) return false; return true; } private void UpdateConfirmButtonState() { if (confirmButton != null) { confirmButton.interactable = CanConfirm(); } } private void Update() { // Update confirm button state in case name changes if (nameInputField != null && nameInputField.isFocused) { UpdateConfirmButtonState(); } } } }