#region license // This file is part of Vocaluxe. // // Vocaluxe is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Vocaluxe is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Vocaluxe. If not, see . #endregion using System; using System.Collections.Generic; using VocaluxeLib.Profile; namespace VocaluxeLib.Menu { public abstract class CMenuPartyNameSelection : CMenuParty { private bool _AllPlayerSelected { get { for (var team = 0; team < _NumTeams; team++) { if (_TeamList[team].Count < _NumPlayerTeams[team]) { return false; } } return true; } } protected bool _Teams = true; protected int _NumTeams = -1; protected int _NumPlayer = -1; protected int[] _NumPlayerTeams; protected bool _AllowChangePlayerNum = true; protected bool _AllowChangeTeamNum = true; protected bool _ChangePlayerNumDynamic = true; protected bool _ChangeTeamNumDynamic = true; private int _CurrentTeam; private bool _AvatarsChanged; private bool _ProfilesChanged; private bool _SelectingKeyboardActive; private bool _SelectingFast; private int _SelectingFastPlayerNr; private Guid _SelectedProfileId = Guid.Empty; private CStatic _ChooseAvatarStatic; private int _OldMouseX; private int _OldMouseY; private const string _ButtonNext = "ButtonNext"; private const string _ButtonBack = "ButtonBack"; private const string _ButtonRandom = "ButtonRandom"; private const string _ButtonIncreaseTeams = "ButtonIncreaseTeams"; private const string _ButtonDecreaseTeams = "ButtonDecreaseTeams"; private const string _ButtonIncreasePlayer = "ButtonIncreasePlayer"; private const string _ButtonDecreasePlayer = "ButtonDecreasePlayer"; private const string _SelectSlideTeams = "SelectSlideTeams"; private const string _SelectSlidePlayer = "SelectSlidePlayer"; private const string _NameSelection = "NameSelection"; protected List[] _TeamList; public override void Init() { base.Init(); _ThemeButtons = new string[] { _ButtonBack, _ButtonNext, _ButtonRandom, _ButtonIncreaseTeams, _ButtonDecreaseTeams, _ButtonIncreasePlayer, _ButtonDecreasePlayer }; _ThemeSelectSlides = new string[] { _SelectSlideTeams, _SelectSlidePlayer }; _ThemeNameSelections = new string[] { _NameSelection }; _ChooseAvatarStatic = GetNewStatic(); _ChooseAvatarStatic.Visible = false; _ChooseAvatarStatic.Aspect = EAspect.Crop; CBase.Profiles.AddProfileChangedCallback(_OnProfileChanged); } public void SetPartyModeData(int numPlayer) { SetPartyModeData(1, numPlayer, new int[] { numPlayer }); _CurrentTeam = 0; } public void SetPartyModeData(int numTeams, int numPlayer, int[] numPlayerTeams) { _NumTeams = numTeams; _NumPlayer = numPlayer; _NumPlayerTeams = numPlayerTeams; _TeamList = new List[_NumTeams > 0 ? _NumTeams : 1]; if (_NumTeams != _NumPlayerTeams.Length) { _NumPlayerTeams = new int[_NumTeams]; } for (var i = 0; i < _TeamList.Length; i++) { _TeamList[i] = new List(); } _UpdateSlides(); _LoadProfiles(); _UpdateButtonVisibility(); _UpdateButtonState(); _UpdateNextButtonVisibility(); } public void SetPartyModeProfiles(List[] teamProfiles) { _TeamList = teamProfiles; for (var t = 0; t < _TeamList.Length; t++) { foreach (var id in _TeamList[t]) { _NameSelections[_NameSelection].UseProfile(id); } } _UpdateSlides(); _UpdateNextButtonVisibility(); } public override bool HandleInput(SKeyEvent keyEvent) { //Check if selecting with keyboard is active if (_SelectingKeyboardActive) { //Handle left/right/up/down _NameSelections[_NameSelection].HandleInput(keyEvent); var numPressed = -1; var resetSelection = false; switch (keyEvent.Key) { case Keys.Enter: //Check, if a player is selected if (_NameSelections[_NameSelection].SelectedId != Guid.Empty) { _SelectedProfileId = _NameSelections[_NameSelection].SelectedId; if (!CBase.Profiles.IsProfileIdValid(_SelectedProfileId)) { return true; } _AddPlayer(_CurrentTeam, _SelectedProfileId); } //Started selecting with 'P' if (_SelectingFast) { if (!_ChangePlayerNumDynamic && _TeamList[_CurrentTeam].Count == _NumPlayerTeams[_CurrentTeam]) { resetSelection = true; } else if (_TeamList[_CurrentTeam].Count == _PartyMode.MaxPlayersPerTeam) { resetSelection = true; } } else if (!_SelectingFast) { resetSelection = true; } break; case Keys.Escape: case Keys.Back: resetSelection = true; break; case Keys.D1: case Keys.NumPad1: numPressed = 1; break; case Keys.D2: case Keys.NumPad2: numPressed = 2; break; case Keys.D3: case Keys.NumPad3: numPressed = 3; break; case Keys.D4: case Keys.NumPad4: numPressed = 4; break; case Keys.D5: case Keys.NumPad5: numPressed = 5; break; case Keys.D6: case Keys.NumPad6: numPressed = 6; break; case Keys.D7: case Keys.NumPad7: numPressed = 7; break; case Keys.D8: case Keys.NumPad8: numPressed = 8; break; case Keys.D9: case Keys.NumPad9: numPressed = 9; break; } if (numPressed > 0 || resetSelection) { if (numPressed == _SelectingFastPlayerNr || resetSelection) { //Reset all values _SelectingFastPlayerNr = 0; _SelectingKeyboardActive = false; _NameSelections[_NameSelection].FastSelection(false, -1); } else if (numPressed <= _NumPlayerTeams[_CurrentTeam]) { _SelectingFastPlayerNr = numPressed; _NameSelections[_NameSelection].FastSelection(true, numPressed); } _SelectingFast = false; } } else { base.HandleInput(keyEvent); var numPressed = 0; switch (keyEvent.Key) { case Keys.Back: case Keys.Escape: Back(); break; case Keys.Enter: if (_Buttons[_ButtonBack].Selected) { Back(); } if (_Buttons[_ButtonNext].Selected) { Next(); } if (_Buttons[_ButtonRandom].Selected) { _SelectRandom(); } if (_Buttons[_ButtonIncreaseTeams].Selected) { IncreaseTeamNum(); } if (_Buttons[_ButtonDecreaseTeams].Selected) { DecreaseTeamNum(); } if (_Buttons[_ButtonIncreasePlayer].Selected) { IncreasePlayerNum(_CurrentTeam); } if (_Buttons[_ButtonDecreasePlayer].Selected) { DecreasePlayerNum(_CurrentTeam); } break; case Keys.Delete: if (_SelectSlides[_SelectSlidePlayer].Selected && _SelectSlides[_SelectSlidePlayer].NumValues > 0) { var index = _SelectSlides[_SelectSlidePlayer].Selection; _RemovePlayerByIndex(_CurrentTeam, index); _UpdatePlayerSlide(); } break; case Keys.Left: case Keys.Right: if (_SelectSlides[_SelectSlideTeams].Selected) { _OnChangeTeamSlide(); } break; case Keys.P: if (!_SelectingKeyboardActive) { _SelectingFastPlayerNr = _CurrentTeam + 1; _SelectingFast = true; //_ResetPlayerSelections(); } break; case Keys.D1: case Keys.NumPad1: numPressed = 1; break; case Keys.D2: case Keys.NumPad2: numPressed = 2; break; case Keys.D3: case Keys.NumPad3: numPressed = 3; break; case Keys.D4: case Keys.NumPad4: numPressed = 4; break; case Keys.D5: case Keys.NumPad5: numPressed = 5; break; case Keys.D6: case Keys.NumPad6: numPressed = 6; break; case Keys.D7: case Keys.NumPad7: numPressed = 7; break; case Keys.D8: case Keys.NumPad8: numPressed = 8; break; case Keys.D9: case Keys.NumPad9: numPressed = 9; break; case Keys.Subtract: if (_SelectSlides[_SelectSlideTeams].Selected) { DecreaseTeamNum(); } else if (_SelectSlides[_SelectSlidePlayer].Selected) { DecreasePlayerNum(_CurrentTeam); } break; case Keys.Add: if (_SelectSlides[_SelectSlideTeams].Selected) { IncreaseTeamNum(); } else if (_SelectSlides[_SelectSlidePlayer].Selected) { IncreasePlayerNum(_CurrentTeam); } break; } if (numPressed > 0) { if (_ChangeTeamNumDynamic && numPressed < _PartyMode.MaxTeams && numPressed > _SelectSlides[_SelectSlideTeams].NumValues) { while (numPressed < _PartyMode.MaxTeams) { IncreaseTeamNum(); } } if (numPressed <= _SelectSlides[_SelectSlideTeams].NumValues) { _SelectSlides[_SelectSlideTeams].SelectedTag = numPressed; } } } if (_SelectingFastPlayerNr > 0 && _SelectingFastPlayerNr <= _NumPlayerTeams[_CurrentTeam]) { _SelectingKeyboardActive = true; _NameSelections[_NameSelection].FastSelection(true, _SelectingFastPlayerNr); } return true; } public override bool HandleMouse(SMouseEvent mouseEvent) { var stopSelectingFast = false; if (_SelectingFast) { _NameSelections[_NameSelection].HandleMouse(mouseEvent); } else { base.HandleMouse(mouseEvent); } //Check if LeftButton is hold and Select-Mode inactive if (mouseEvent.LBH && _SelectedProfileId == Guid.Empty && !_SelectingFast) { //Save mouse-coords _OldMouseX = mouseEvent.X; _OldMouseY = mouseEvent.Y; //Check if mouse if over tile if (_NameSelections[_NameSelection].IsOverTile(mouseEvent)) { //Get player-number of tile _SelectedProfileId = _NameSelections[_NameSelection].TilePlayerId(mouseEvent); if (_SelectedProfileId != Guid.Empty) { //Update of Drag/Drop-Texture var selectedPlayer = _NameSelections[_NameSelection].TilePlayerAvatar(mouseEvent); _ChooseAvatarStatic.Visible = true; _ChooseAvatarStatic.MaxRect = selectedPlayer.Rect; _ChooseAvatarStatic.Z = CBase.Settings.GetZNear(); _ChooseAvatarStatic.Color = new SColorF(1, 1, 1, 1); _ChooseAvatarStatic.Texture = selectedPlayer.Texture; } } } //Check if LeftButton is hold and Select-Mode active if (mouseEvent.LBH && _SelectedProfileId != Guid.Empty && !_SelectingFast) { //Update coords for Drag/Drop-Texture _ChooseAvatarStatic.X += mouseEvent.X - _OldMouseX; _ChooseAvatarStatic.Y += mouseEvent.Y - _OldMouseY; _OldMouseX = mouseEvent.X; _OldMouseY = mouseEvent.Y; } // LeftButton isn't hold anymore, but Select-Mode is still active -> "Drop" of Avatar else if (_SelectedProfileId != Guid.Empty && !_SelectingFast) { //Check if mouse is in drop-area if (CHelper.IsInBounds(_SelectSlides[_SelectSlidePlayer].Rect, mouseEvent)) { if (!CBase.Profiles.IsProfileIdValid(_SelectedProfileId)) { return true; } _AddPlayer(_CurrentTeam, _SelectedProfileId); } //Reset variables _SelectedProfileId = Guid.Empty; _ChooseAvatarStatic.Visible = false; } if (mouseEvent.LB && _SelectingFast) { if (_NameSelections[_NameSelection].IsOverTile(mouseEvent)) { //Get player-number of tile _SelectedProfileId = _NameSelections[_NameSelection].TilePlayerId(mouseEvent); if (_SelectedProfileId != Guid.Empty) { if (!CBase.Profiles.IsProfileIdValid(_SelectedProfileId)) { return true; } _AddPlayer(_CurrentTeam, _SelectedProfileId); if (!_ChangePlayerNumDynamic && _TeamList[_CurrentTeam].Count == _NumPlayerTeams[_CurrentTeam]) { stopSelectingFast = true; } else if (_TeamList[_CurrentTeam].Count == _PartyMode.MaxPlayersPerTeam) { stopSelectingFast = true; } } else { stopSelectingFast = true; } } } else if (mouseEvent.LB && _IsMouseOverCurSelection(mouseEvent)) { if (_Buttons[_ButtonBack].Selected) { Back(); } if (_Buttons[_ButtonNext].Selected) { Next(); } if (_Buttons[_ButtonRandom].Selected) { _SelectRandom(); } if (_Buttons[_ButtonIncreaseTeams].Selected) { IncreaseTeamNum(); } if (_Buttons[_ButtonDecreaseTeams].Selected) { DecreaseTeamNum(); } if (_Buttons[_ButtonIncreasePlayer].Selected) { IncreasePlayerNum(_CurrentTeam); } if (_Buttons[_ButtonDecreasePlayer].Selected) { DecreasePlayerNum(_CurrentTeam); } if (_SelectSlides[_SelectSlideTeams].Selected) { _OnChangeTeamSlide(); } //Update Tiles-List _NameSelections[_NameSelection].UpdateList(); } if (mouseEvent.LD && _NameSelections[_NameSelection].IsOverTile(mouseEvent) && !_SelectingFast) { _SelectedProfileId = _NameSelections[_NameSelection].TilePlayerId(mouseEvent); if (_SelectedProfileId != Guid.Empty) { if (!CBase.Profiles.IsProfileIdValid(_SelectedProfileId)) { return true; } _AddPlayer(_CurrentTeam, _SelectedProfileId); } } if (mouseEvent.RB && _SelectingFast) { stopSelectingFast = true; } else if (mouseEvent.RB) { var exit = true; if (_SelectSlides[_SelectSlidePlayer].Selected && _TeamList[_CurrentTeam].Count > _SelectSlides[_SelectSlidePlayer].Selection) { var currentSelection = _SelectSlides[_SelectSlidePlayer].Selection; var id = _TeamList[_CurrentTeam][currentSelection]; _RemovePlayer(_CurrentTeam, id); _UpdatePlayerSlide(); exit = false; } if (exit) { Back(); } } if (mouseEvent.MB && _SelectingFast) { if (!_ChangePlayerNumDynamic && _TeamList[_CurrentTeam].Count == _NumPlayerTeams[_CurrentTeam]) { stopSelectingFast = true; } else if (_TeamList[_CurrentTeam].Count == _PartyMode.MaxPlayersPerTeam) { stopSelectingFast = true; } } else if (mouseEvent.MB) { _SelectingFast = true; _SelectingFastPlayerNr = _CurrentTeam + 1; _SelectingKeyboardActive = true; _NameSelections[_NameSelection].FastSelection(true, _SelectingFastPlayerNr); } //Check mouse-wheel for scrolling if (mouseEvent.Wheel != 0) { if (CHelper.IsInBounds(_NameSelections[_NameSelection].Rect, mouseEvent)) { var offset = _NameSelections[_NameSelection].Offset + mouseEvent.Wheel; _NameSelections[_NameSelection].UpdateList(offset); } } if (stopSelectingFast) { _SelectingFast = false; _SelectingFastPlayerNr = 0; _SelectingKeyboardActive = false; _NameSelections[_NameSelection].FastSelection(false, -1); } return true; } public override void LoadTheme(string xmlPath) { base.LoadTheme(xmlPath); _SelectSlides[_SelectSlidePlayer].DrawTextures = true; _SelectSlides[_SelectSlidePlayer].SelectByHovering = true; _AddStatic(_ChooseAvatarStatic); } public override bool UpdateGame() { if (_ProfilesChanged || _AvatarsChanged) { _LoadProfiles(); } return true; } public override void OnShow() { _NameSelections[_NameSelection].Init(); base.OnShow(); _UpdateButtonVisibility(); _UpdateButtonState(); _UpdateNextButtonVisibility(); } public abstract void Back(); public abstract void Next(); public void IncreaseTeamNum() { if (!_AllowChangeTeamNum) { return; } if (_NumTeams + 1 <= _PartyMode.MaxTeams) { _NumTeams++; var numPlayerTeams = _NumPlayerTeams; var teamList = _TeamList; _NumPlayerTeams = new int[_NumTeams]; _TeamList = new List[_NumTeams]; for (var i = 0; i < _NumPlayerTeams.Length; i++) { if (i < numPlayerTeams.Length) { _NumPlayerTeams[i] = numPlayerTeams[i]; _TeamList[i] = teamList[i]; } else { //Get average num players per teams as default player number _NumPlayerTeams[i] = _NumPlayer / (_NumTeams - 1); _NumPlayer += _NumPlayerTeams[i]; _TeamList[i] = new List(); } } } _UpdateButtonState(); _UpdateTeamSlide(); } public void DecreaseTeamNum() { if (!_AllowChangeTeamNum) { return; } if (_NumTeams - 1 >= _PartyMode.MinTeams) { _NumTeams--; } _UpdateButtonState(); _UpdateTeamSlide(); } public void IncreasePlayerNum(int team) { if (!_AllowChangePlayerNum) { return; } if (_NumPlayerTeams.Length > team) { if (_NumPlayerTeams[team] + 1 <= _PartyMode.MaxPlayersPerTeam) { _NumPlayerTeams[team]++; } _UpdatePlayerSlide(); } _UpdateButtonState(); _UpdateNextButtonVisibility(); } public void DecreasePlayerNum(int team) { if (!_AllowChangePlayerNum) { return; } if (_NumPlayerTeams.Length > team) { if (_NumPlayerTeams[team] - 1 >= _PartyMode.MinPlayersPerTeam) { _NumPlayerTeams[team]--; } if (_TeamList[team].Count > _NumPlayerTeams[team]) { _RemovePlayerByIndex(team, _NumPlayerTeams[team] - 1); } _UpdatePlayerSlide(); } _UpdateButtonState(); _UpdateNextButtonVisibility(); } #region private methods private void _OnProfileChanged(EProfileChangedFlags flags) { if (EProfileChangedFlags.Avatar == (EProfileChangedFlags.Avatar & flags)) { _AvatarsChanged = true; } if (EProfileChangedFlags.Profile == (EProfileChangedFlags.Profile & flags)) { _ProfilesChanged = true; } } private void _LoadProfiles() { _NameSelections[_NameSelection].UpdateList(); _UpdateSlides(); _OnChangeTeamSlide(); _ProfilesChanged = false; _AvatarsChanged = false; } private void _UpdateSlides() { _UpdateTeamSlide(); _UpdatePlayerSlide(); } private void _OnChangeTeamSlide() { if (_CurrentTeam == _SelectSlides[_SelectSlideTeams].Selection) { return; } _CurrentTeam = _SelectSlides[_SelectSlideTeams].Selection; _UpdatePlayerSlide(); _UpdateButtonState(); } private void _UpdatePlayerSlide() { var selection = _SelectSlides[_SelectSlidePlayer].Selection; _SelectSlides[_SelectSlidePlayer].Clear(); var maxPlayers = Math.Min(_TeamList[_CurrentTeam].Count, _NumPlayerTeams[_CurrentTeam]); for (var i = 0; i < maxPlayers; i++) { var name = CBase.Profiles.GetPlayerName(_TeamList[_CurrentTeam][i]); var avatar = CBase.Profiles.GetAvatar(_TeamList[_CurrentTeam][i]); _SelectSlides[_SelectSlidePlayer].AddValue(name, avatar); } for (var i = maxPlayers; i < _NumPlayerTeams[_CurrentTeam]; i++) { _SelectSlides[_SelectSlidePlayer].AddValue("", _NameSelections[_NameSelection].TextureEmptyTile); } if (selection >= maxPlayers) { selection = maxPlayers - 1; } _SelectSlides[_SelectSlidePlayer].Selection = selection; } private void _UpdateTeamSlide() { var sel = _SelectSlides[_SelectSlideTeams].Selection; _SelectSlides[_SelectSlideTeams].Visible = _Teams; _SelectSlides[_SelectSlideTeams].Clear(); for (var i = 1; i <= _NumTeams; i++) { _SelectSlides[_SelectSlideTeams].AddValue("Team " + i, null, i); } _SelectSlides[_SelectSlideTeams].Selection = Math.Min(sel, _SelectSlides[_SelectSlideTeams].NumValues - 1); } private void _UpdateButtonVisibility() { _Buttons[_ButtonIncreaseTeams].Visible = _AllowChangeTeamNum && _Teams && _PartyMode.MinTeams != _PartyMode.MaxTeams; _Buttons[_ButtonDecreaseTeams].Visible = _AllowChangeTeamNum && _Teams && _PartyMode.MinTeams != _PartyMode.MaxTeams; _Buttons[_ButtonIncreasePlayer].Visible = _AllowChangePlayerNum; _Buttons[_ButtonDecreasePlayer].Visible = _AllowChangePlayerNum; } private void _UpdateButtonState() { _Buttons[_ButtonIncreaseTeams].Selectable = _NumTeams < _PartyMode.MaxTeams; _Buttons[_ButtonDecreaseTeams].Selectable = _NumTeams > _PartyMode.MinTeams; if (_NumPlayerTeams != null && _NumPlayerTeams.Length > _CurrentTeam) { _Buttons[_ButtonIncreasePlayer].Selectable = _NumPlayerTeams[_CurrentTeam] < _PartyMode.MaxPlayersPerTeam; _Buttons[_ButtonDecreasePlayer].Selectable = _NumPlayerTeams[_CurrentTeam] > _PartyMode.MinPlayersPerTeam; } else { _Buttons[_ButtonIncreasePlayer].Selectable = false; _Buttons[_ButtonDecreasePlayer].Selectable = false; } } private void _AddPlayer(int team, Guid profileId, bool updateElements = true) { if (profileId == Guid.Empty) { return; } if (!CBase.Profiles.IsProfileIdValid(profileId)) { return; } if (_TeamList[team].Contains(profileId)) { return; } if (_TeamList[team].Count >= _PartyMode.MaxPlayersPerTeam) { return; } var targetIndex = -1; if (_TeamList[team].Count < _NumPlayerTeams[team]) { targetIndex = _TeamList[team].Count; } else if (!_ChangePlayerNumDynamic) { targetIndex = _SelectSlides[_SelectSlidePlayer].Selection; if (targetIndex < 0 || targetIndex >= _NumPlayerTeams[team]) { targetIndex = _NumPlayerTeams[team] - 1; } } if (targetIndex < 0) { return; } if (targetIndex < _TeamList[team].Count) { var oldId = _TeamList[team][targetIndex]; _NameSelections[_NameSelection].RemoveUsedProfile(oldId); _TeamList[team][targetIndex] = profileId; } else { _TeamList[team].Add(profileId); } _NameSelections[_NameSelection].UseProfile(profileId); if (updateElements) { _UpdatePlayerSlide(); _SelectSlides[_SelectSlidePlayer].Selection = targetIndex; _UpdateNextButtonVisibility(); } } private void _RemoveAllPlayer() { for (var t = 0; t < _TeamList.Length; t++) { var ids = new List(); ids.AddRange(_TeamList[t]); foreach (var id in ids) { _RemovePlayer(t, id); } } } private void _RemovePlayerByIndex(int team, int index) { if (_TeamList[team].Count > index) { var id = _TeamList[team][index]; _TeamList[team].RemoveAt(index); _NameSelections[_NameSelection].RemoveUsedProfile(id); } _UpdateNextButtonVisibility(); } private void _RemovePlayer(int team, Guid profileId) { _TeamList[team].Remove(profileId); _NameSelections[_NameSelection].RemoveUsedProfile(profileId); _UpdateNextButtonVisibility(); } private void _SelectRandom() { _RemoveAllPlayer(); for (var t = 0; t < _NumPlayerTeams.Length; t++) { for (var p = 0; p < _NumPlayerTeams[t]; p++) { var profileId = _NameSelections[_NameSelection].GetRandomUnusedProfile(); if (profileId != Guid.Empty) { _AddPlayer(t, profileId); } } } _UpdatePlayerSlide(); _UpdateButtonVisibility(); } private void _UpdateNextButtonVisibility() { _Buttons[_ButtonNext].Visible = _AllPlayerSelected; } #endregion } }