using Noesis; using StellarConquest.Model.Extensions; using StellarConquest.Model.Factions; using StellarConquest.Model.Players; using System; using UnityEngine; using EventArgs = Noesis.EventArgs; using Grid = Noesis.Grid; using GUI = Noesis.GUI; using Random = UnityEngine.Random; namespace StellarConquest.Presentation.Unity.UI { public partial class IdentitySelectionControl : UserControl, ICharacterCreationControl { public CharacterCreationScreen CharacterCreationScreen { get; set; } private TextBox _PlayerNameTextBox; private RenderControl _RenderControl; private bool _RenderControlCreated = false; private GameObject _CharacterGameObject; private CharacterCustomization _CharacterCustomization; private SpeciesType _Species = SpeciesType.HumanMale; private VariationType _Variation = VariationType.Other; private OutfitType _Outfit = OutfitType.Colonist; private Button _LeftSpeciesButton; private Button _RightSpeciesButton; private Button _LeftVariationButton; private Button _RightVariationButton; private Button _LeftOutfitButton; private Button _RightOutfitButton; private Button _LeftHairStyleButton; private Button _RightHairStyleButton; private Button _LeftHairColorButton; private Button _RightHairColorButton; private Button _LeftHeadButton; private Button _RightHeadButton; private Button _LeftTorsoButton; private Button _RightTorsoButton; private Button _LeftPantsButton; private Button _RightPantsButton; private Button _LeftBootsButton; private Button _RightBootsButton; private Button _LeftTopArmorButton; private Button _RightTopArmorButton; private Button _LeftBottomArmorButton; private Button _RightBottomArmorButton; private Button _LeftInsigniaStyleButton; private Button _RightInsigniaStyleButton; private Button _LeftInsigniaColorButton; private Button _RightInsigniaColorButton; private Button _RandomizeButton; private Grid _OutfitGrid; private Grid _HeadGrid; private Grid _HairStyleGrid; private Grid _HairColorGrid; private Grid _BootsGrid; private Grid _TopArmorGrid; private Grid _BottomArmorGrid; private Grid _InsigniaStyleGrid; private Grid _InsigniaColorGrid; private Vector3 _BodyPosition = new Vector3(0, -0.45f, 0.85f); private Vector3 _HeadPosition = new Vector3(0, -0.78f, 0.315f); private Vector3 _TorsoPosition = new Vector3(0, -0.63f, 0.4f); private Vector3 _PantsPosition = new Vector3(0, -0.33f, 0.4f); private Vector3 _BootsPosition = new Vector3(0, -0.21f, 0.4f); public IdentitySelectionControl() { if (!Application.isPlaying) return; this.Initialized += OnInitialized; this.InitializeComponent(); } private void InitializeComponent() { GUI.LoadComponent(this, "Assets/User Interface/Screens/Character Creation/Identity/IdentitySelectionControl.xaml"); FrameworkElement root = this.Content as FrameworkElement; _PlayerNameTextBox = root.FindName("_PlayerNameTextBox") as TextBox; _RenderControl = root.FindName("_RenderControl") as RenderControl; _LeftSpeciesButton = root.FindName("_LeftSpeciesButton") as Button; _RightSpeciesButton = root.FindName("_RightSpeciesButton") as Button; _LeftOutfitButton = root.FindName("_LeftOutfitButton") as Button; _RightOutfitButton = root.FindName("_RightOutfitButton") as Button; _LeftVariationButton = root.FindName("_LeftVariationButton") as Button; _RightVariationButton = root.FindName("_RightVariationButton") as Button; _LeftHairStyleButton = root.FindName("_LeftHairStyleButton") as Button; _RightHairStyleButton = root.FindName("_RightHairStyleButton") as Button; _LeftHairColorButton = root.FindName("_LeftHairColorButton") as Button; _RightHairColorButton = root.FindName("_RightHairColorButton") as Button; _LeftHeadButton = root.FindName("_LeftHeadButton") as Button; _RightHeadButton = root.FindName("_RightHeadButton") as Button; _LeftTorsoButton = root.FindName("_LeftTorsoButton") as Button; _RightTorsoButton = root.FindName("_RightTorsoButton") as Button; _LeftPantsButton = root.FindName("_LeftPantsButton") as Button; _RightPantsButton = root.FindName("_RightPantsButton") as Button; _LeftBootsButton = root.FindName("_LeftBootsButton") as Button; _RightBootsButton = root.FindName("_RightBootsButton") as Button; _LeftTopArmorButton = root.FindName("_LeftTopArmorButton") as Button; _RightTopArmorButton = root.FindName("_RightTopArmorButton") as Button; _LeftBottomArmorButton = root.FindName("_LeftBottomArmorButton") as Button; _RightBottomArmorButton = root.FindName("_RightBottomArmorButton") as Button; _LeftInsigniaStyleButton = root.FindName("_LeftInsigniaStyleButton") as Button; _RightInsigniaStyleButton = root.FindName("_RightInsigniaStyleButton") as Button; _LeftInsigniaColorButton = root.FindName("_LeftInsigniaColorButton") as Button; _RightInsigniaColorButton = root.FindName("_RightInsigniaColorButton") as Button; _RandomizeButton = root.FindName("_RandomizeButton") as Button; _OutfitGrid = root.FindName("_OutfitGrid") as Grid; _HeadGrid = root.FindName("_HeadGrid") as Grid; _HairStyleGrid = root.FindName("_HairStyleGrid") as Grid; _HairColorGrid = root.FindName("_HairColorGrid") as Grid; _BootsGrid = root.FindName("_BootsGrid") as Grid; _TopArmorGrid = root.FindName("_TopArmorGrid") as Grid; _BottomArmorGrid = root.FindName("_BottomArmorGrid") as Grid; _InsigniaStyleGrid = root.FindName("_InsigniaStyleGrid") as Grid; _InsigniaColorGrid = root.FindName("_InsigniaColorGrid") as Grid; // species _LeftSpeciesButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); PreviousSpecies(); _RenderControl.SetPosition(_BodyPosition); }; _RightSpeciesButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); NextSpecies(); _RenderControl.SetPosition(_BodyPosition); }; // variation _LeftVariationButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); PreviousVariation(); _RenderControl.SetPosition(_BodyPosition); }; _RightVariationButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); NextVariation(); _RenderControl.SetPosition(_BodyPosition); }; // outfit _LeftOutfitButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); PreviousOutfit(); _RenderControl.SetPosition(_BodyPosition); }; _RightOutfitButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); NextOutfit(); _RenderControl.SetPosition(_BodyPosition); }; // aesthetic attributes _LeftHairStyleButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.PreviousHairStyle(); _RenderControl.SetPosition(_HeadPosition); }; _RightHairStyleButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.NextHairStyle(); _RenderControl.SetPosition(_HeadPosition); }; _LeftHairColorButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.PreviousHairColor(); _RenderControl.SetPosition(_HeadPosition); }; _RightHairColorButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.NextHairColor(); _RenderControl.SetPosition(_HeadPosition); }; _LeftHeadButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.PreviousHead(); _RenderControl.SetPosition(_HeadPosition); }; _RightHeadButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.NextHead(); _RenderControl.SetPosition(_HeadPosition); }; _LeftTorsoButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.PreviousTorso(); _RenderControl.SetPosition(_TorsoPosition); }; _RightTorsoButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.NextTorso(); _RenderControl.SetPosition(_TorsoPosition); }; _LeftPantsButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.PreviousPants(); _RenderControl.SetPosition(_PantsPosition); }; _RightPantsButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.NextPants(); _RenderControl.SetPosition(_PantsPosition); }; _LeftBootsButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.PreviousBoots(); _RenderControl.SetPosition(_BootsPosition); }; _RightBootsButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.NextBoots(); _RenderControl.SetPosition(_BootsPosition); }; _LeftTopArmorButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.PreviousTopArmor(); _RenderControl.SetPosition(_TorsoPosition); }; _RightTopArmorButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.NextTopArmor(); _RenderControl.SetPosition(_TorsoPosition); }; _LeftBottomArmorButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.PreviousBottomArmor(); _RenderControl.SetPosition(_PantsPosition); }; _RightBottomArmorButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.NextBottomArmor(); _RenderControl.SetPosition(_PantsPosition); }; _LeftInsigniaStyleButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.PreviousPinStyle(); _RenderControl.SetPosition(_HeadPosition); }; _RightInsigniaStyleButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.NextPinStyle(); _RenderControl.SetPosition(_HeadPosition); }; _LeftInsigniaColorButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.PreviousPinColor(); _RenderControl.SetPosition(_HeadPosition); }; _RightInsigniaColorButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); _CharacterCustomization.NextPinColor(); _RenderControl.SetPosition(_HeadPosition); }; _RandomizeButton.Click += (sender, e) => { GameState.Instance.StaticAudioEffects.ButtonClick(); Randomize(); _RenderControl.SetPosition(_BodyPosition); }; #if (UNITY_EDITOR) _PlayerNameTextBox.Text = "Tester " + Random.Range(1000, 9999); #endif _PlayerNameTextBox.GotFocus += (sender, e) => _RenderControl.SetPosition(_BodyPosition); } private void OnInitialized(object sender, EventArgs args) { _PlayerNameTextBox.TextChanged += (sender2, e2) => Validate(); } public void Show() { Validate(); if (!_RenderControlCreated) { _RenderControlCreated = true; Load(_Species, _Variation, _Outfit); } else { ConfigureRenderControl(); _RenderControl.Enable(); } } public void Hide() { CharacterCreationScreen.CharacterSheet.PlayerName = _PlayerNameTextBox.Text; CharacterCreationScreen.CharacterSheet.RaceId = BaseFaction.GetFactionDefaultRaceId(CharacterCreationScreen.CharacterSheet.FactionId); CharacterCreationScreen.CharacterSheet.Appearance = _CharacterCustomization.GetConfiguration(); _RenderControl.Disable(); } private void Validate() { string text = _PlayerNameTextBox.Text; bool isValid = !string.IsNullOrEmpty(text) && text.Trim().Length >= 4; CharacterCreationScreen.SetNextButtonState(isValid); } private void Load(SpeciesType species, VariationType variation, OutfitType outfit) { switch (species) { case SpeciesType.HumanMale: _OutfitGrid.Visibility = Visibility.Visible; _HeadGrid.Visibility = Visibility.Visible; _HairStyleGrid.Visibility = Visibility.Visible; _HairColorGrid.Visibility = Visibility.Visible; break; case SpeciesType.HumanFemale: _OutfitGrid.Visibility = Visibility.Collapsed; _HeadGrid.Visibility = Visibility.Visible; _HairStyleGrid.Visibility = Visibility.Visible; _HairColorGrid.Visibility = Visibility.Visible; break; case SpeciesType.KethMale: _OutfitGrid.Visibility = Visibility.Visible; _HeadGrid.Visibility = Visibility.Collapsed; _HairStyleGrid.Visibility = Visibility.Collapsed; _HairColorGrid.Visibility = Visibility.Collapsed; break; case SpeciesType.Synthetic: break; case SpeciesType.Ouster: break; default: break; } switch (outfit) { case OutfitType.Colonist: _BootsGrid.Visibility = Visibility.Collapsed; _TopArmorGrid.Visibility = Visibility.Collapsed; _BottomArmorGrid.Visibility = Visibility.Collapsed; _InsigniaStyleGrid.Visibility = Visibility.Collapsed; _InsigniaColorGrid.Visibility = Visibility.Collapsed; break; case OutfitType.Imperium: _BootsGrid.Visibility = Visibility.Visible; _TopArmorGrid.Visibility = Visibility.Collapsed; _BottomArmorGrid.Visibility = Visibility.Collapsed; _InsigniaStyleGrid.Visibility = Visibility.Visible; _InsigniaColorGrid.Visibility = Visibility.Visible; break; case OutfitType.Soldier: _BootsGrid.Visibility = Visibility.Visible; _TopArmorGrid.Visibility = Visibility.Visible; _BottomArmorGrid.Visibility = Visibility.Visible; _InsigniaStyleGrid.Visibility = Visibility.Collapsed; _InsigniaColorGrid.Visibility = Visibility.Collapsed; break; default: break; } PlayerAppearance previousAppearance = null; AnimatorStateInfo? previousAnimatorState = null; if (_CharacterGameObject != null) { CharacterCustomization previousCharacterCustomization = _CharacterCustomization.GetComponent(); previousAppearance = previousCharacterCustomization.GetConfiguration(); previousAnimatorState = previousCharacterCustomization.GetAnimatorState(); GameObject.Destroy(_CharacterGameObject); } _CharacterGameObject = Factory.Instance.CreatePlayer(species, variation, outfit); _CharacterCustomization = _CharacterGameObject.AddComponent(); _CharacterCustomization.SetController("character identity controller"); if (previousAppearance != null) _CharacterCustomization.SetConfiguration(previousAppearance); else _CharacterCustomization.ResetConfiguration(); // resume animation time if (previousAnimatorState.HasValue) UnityDispatcher.Instance.Invoke(() => _CharacterCustomization.SetAnimatorState(previousAnimatorState.Value)); ConfigureRenderControl(); _RenderControl.Enable(); } private void ConfigureRenderControl() { _RenderControl.SetTargetGameObject(_CharacterGameObject, new Vector3(0.5f, 0.5f, 0.5f), _BodyPosition, Quaternion.Euler(0, 180, 0)); _RenderControl.ConfigureCameraEffects(true, false, true); _RenderControl.ConfigureLight(LightType.Directional, 0.92f, true, Vector3.zero, Quaternion.Euler(45, -20, 0)); } private void NextSpecies() { _Species++; if (_Species > SpeciesType.KethMale) _Species = 0; ClampOutfit(0); Load(_Species, _Variation, _Outfit); } private void PreviousSpecies() { _Species--; if (_Species < 0 || _Species > _Species.GetMaxValue()) // compare as non-negative byte (i.e. negative is 255) _Species = SpeciesType.KethMale; ClampOutfit(0); Load(_Species, _Variation, _Outfit); } private void NextVariation() { } private void PreviousVariation() { } private void NextOutfit() { _Outfit++; if (_Outfit > _Outfit.GetMaxValue()) _Outfit = 0; ClampOutfit(1); Load(_Species, _Variation, _Outfit); } private void PreviousOutfit() { _Outfit--; if (_Outfit < 0 || _Outfit > _Outfit.GetMaxValue()) // compare as non-negative byte (i.e. negative is 255) _Outfit = _Outfit.GetMaxValue(); ClampOutfit(-1); Load(_Species, _Variation, _Outfit); } private void ClampOutfit(int value) { switch (_Species) { case SpeciesType.HumanMale: // do nothing -- all outfits supported break; case SpeciesType.HumanFemale: _Outfit = OutfitType.Imperium; break; case SpeciesType.KethMale: if (_Outfit == OutfitType.Colonist) { if (value == -1) _Outfit = OutfitType.Soldier; else if (value == 1) _Outfit = OutfitType.Imperium; else if (value == 0) _Outfit = OutfitType.Soldier; } break; case SpeciesType.Synthetic: case SpeciesType.Ouster: default: throw new ArgumentOutOfRangeException(); } } private void Randomize() { _Species = (SpeciesType)Random.Range(0, 3); _Outfit = (OutfitType)Random.Range(0, 3); ClampOutfit(0); Load(_Species, _Variation, _Outfit); _CharacterCustomization.SetRandomConfiguration(Random.Range(int.MinValue, int.MaxValue), true, true); } public void FocusChanged() { if (_RenderControl != null) _RenderControl.SetPosition(_BodyPosition); } } }