diff --git a/Assets/PerfectWorld/Scripts/UI/Login/CreateCharacterScreen.cs b/Assets/PerfectWorld/Scripts/UI/Login/CreateCharacterScreen.cs new file mode 100644 index 0000000000..c8af5d8047 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/UI/Login/CreateCharacterScreen.cs @@ -0,0 +1,217 @@ +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; + + 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 first available gender for this profession if not selected + if (_currentGender == -1) + { + // Default to male if available, otherwise female + OnGenderSelected(GENDER.GENDER_MALE); + } + + UpdateConfirmButtonState(); + } + + 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}"); + _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(); + } + } + } +} diff --git a/Assets/PerfectWorld/Scripts/UI/Login/CreateCharacterScreen.cs.meta b/Assets/PerfectWorld/Scripts/UI/Login/CreateCharacterScreen.cs.meta new file mode 100644 index 0000000000..5a22e1e624 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/UI/Login/CreateCharacterScreen.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: aa9de023137e92348983cee3c59d620b \ No newline at end of file diff --git a/Assets/Scripts/SelecScreenCharacter.cs b/Assets/Scripts/SelecScreenCharacter.cs index 087b6a401a..bdcf91c5a2 100644 --- a/Assets/Scripts/SelecScreenCharacter.cs +++ b/Assets/Scripts/SelecScreenCharacter.cs @@ -2,6 +2,7 @@ using CSNetwork.Protocols.RPCData; using System; using System.Collections.Generic; using UnityEngine; +using UnityEngine.UI; using BrewMonster; namespace BrewMonster.UI @@ -10,15 +11,76 @@ namespace BrewMonster.UI { [SerializeField] private GameObject characterItemPrefab; [SerializeField] private RectTransform parentItems; + [SerializeField] private Button createCharacterButton; + [SerializeField] private CreateCharacterScreen createCharacterScreen; - public void InitScreen(List roleInfos, Action OnClickItemChar) + private Action _onClickItemChar; + private Action _onCreateCharacterComplete; + + private void Start() { - - foreach (RoleInfo info in roleInfos) + if (createCharacterButton != null) { - CharacterItemUI item = Instantiate(characterItemPrefab, parentItems).GetComponent(); - item.InitItem(info, OnClickItemChar); + createCharacterButton.onClick.AddListener(OnCreateCharacterClicked); } } + + public void InitScreen(List roleInfos, Action OnClickItemChar, Action onCreateCharacterComplete = null) + { + _onClickItemChar = OnClickItemChar; + _onCreateCharacterComplete = onCreateCharacterComplete; + + // Clear existing items + if (parentItems != null) + { + foreach (Transform child in parentItems) + { + Destroy(child.gameObject); + } + } + + // Create character items + if (roleInfos != null) + { + foreach (RoleInfo info in roleInfos) + { + if (characterItemPrefab != null && parentItems != null) + { + CharacterItemUI item = Instantiate(characterItemPrefab, parentItems).GetComponent(); + item.InitItem(info, OnClickItemChar); + } + } + } + } + + private void OnCreateCharacterClicked() + { + if (createCharacterScreen != null) + { + gameObject.SetActive(false); + createCharacterScreen.Show(OnCreateCharacterComplete, OnCreateCharacterCancel); + } + } + + private void OnCreateCharacterComplete(RoleInfo newRole) + { + if (createCharacterScreen != null) + { + createCharacterScreen.Hide(); + } + + gameObject.SetActive(true); + _onCreateCharacterComplete?.Invoke(); + } + + private void OnCreateCharacterCancel() + { + if (createCharacterScreen != null) + { + createCharacterScreen.Hide(); + } + + gameObject.SetActive(true); + } } }