diff --git a/Output/PartyModes/PartnerSwap.xml b/Output/PartyModes/PartnerSwap.xml new file mode 100644 index 00000000..2b7446ac --- /dev/null +++ b/Output/PartyModes/PartnerSwap.xml @@ -0,0 +1,20 @@ + + + 2 + + TR_PARTYMODE_NAME + McSchneidar + TR_PARTYMODE_DESCRIPTION + PartnerSwap + CPartyModePartnerSwap + 1 + 0 + TR_PARTYMODE_AUDIENCE + + + CPartyScreenPartnerSwapMain + CPartyScreenPartnerSwapConfig + CPartyScreenPartnerSwapNames + CPartyScreenPartnerSwapSongs + + diff --git a/Output/PartyModes/PartnerSwap/Languages/de.xml b/Output/PartyModes/PartnerSwap/Languages/de.xml new file mode 100644 index 00000000..520024ee --- /dev/null +++ b/Output/PartyModes/PartnerSwap/Languages/de.xml @@ -0,0 +1,42 @@ + + + Deutsch + Partnertausch + Singt zu zweit mit ständig wechselnden Partnern. Beide Sänger bekommen die Punkte des Paares, der beste Durchschnitt gewinnt. + Für 3 bis 12 Spieler, die gern gemeinsam singen, 2 Mikrofone nötig. + Weiter + Zurück + Start + Beenden + Ja + Nein + Song starten + Songs + Partnertausch: Konfiguration + Anzahl der Spieler + Durchgänge + Gleichklang-Bonus + Duett-Songs + Gemischt + Nur Duette + Keine Duette + Joker pro Spieler + Partnertausch: Spieler auswählen + Zufällig wählen + Partnertausch + Willst du das Spiel wirklich beenden? + Pos + Name + Songs + Ø + Durchgang + Song + Pause: + singen zum ersten Mal zusammen + singen zum %n. Mal zusammen + Letzter Song: + Gleichklang-Bonus + Bestes Paar bisher + Bestes Paar des Abends + Sieger + diff --git a/Output/PartyModes/PartnerSwap/Languages/en.xml b/Output/PartyModes/PartnerSwap/Languages/en.xml new file mode 100644 index 00000000..b904cc81 --- /dev/null +++ b/Output/PartyModes/PartnerSwap/Languages/en.xml @@ -0,0 +1,42 @@ + + + English + Partner Swap + Sing in pairs with ever-changing partners. Both singers of a pair get the pair score, the best average wins. + For 3 to 12 players who like to sing together, 2 microphones needed. + Next + Back + Start + Exit + Yes + No + Start song + Songs + Partner Swap: Configuration + Number of players + Rounds + Harmony bonus + Duet songs + Mixed + Duets only + No duets + Jokers per player + Partner Swap: Choose Players + Select random + Partner Swap + Do you really want to exit the game? + Pos + Name + Songs + Ø + Round + Song + Taking a break: + singing together for the first time + singing together for the %n. time + Last song: + Harmony bonus + Best pair so far + Best pair of the night + Winner + diff --git a/Output/PartyModes/PartnerSwap/Themes/Default.xml b/Output/PartyModes/PartnerSwap/Themes/Default.xml new file mode 100644 index 00000000..97392ded --- /dev/null +++ b/Output/PartyModes/PartnerSwap/Themes/Default.xml @@ -0,0 +1,10 @@ + + + 9 + + Default + McSchneidar + 0 + 1 + + diff --git a/Output/PartyModes/PartnerSwap/Themes/Default/Default.xml b/Output/PartyModes/PartnerSwap/Themes/Default/Default.xml new file mode 100644 index 00000000..d88d34b4 --- /dev/null +++ b/Output/PartyModes/PartnerSwap/Themes/Default/Default.xml @@ -0,0 +1,15 @@ + + + 4 + + Default + McSchneidar + 0 + 1 + + + + PartyModeIcon.png + + + diff --git a/Output/PartyModes/PartnerSwap/Themes/Default/PartyModeIcon.png b/Output/PartyModes/PartnerSwap/Themes/Default/PartyModeIcon.png new file mode 100644 index 00000000..d19b6431 Binary files /dev/null and b/Output/PartyModes/PartnerSwap/Themes/Default/PartyModeIcon.png differ diff --git a/Output/PartyModes/PartnerSwap/Themes/Default/Screens/PartyScreenPartnerSwapConfig.xml b/Output/PartyModes/PartnerSwap/Themes/Default/Screens/PartyScreenPartnerSwapConfig.xml new file mode 100644 index 00000000..bf22385a --- /dev/null +++ b/Output/PartyModes/PartnerSwap/Themes/Default/Screens/PartyScreenPartnerSwapConfig.xml @@ -0,0 +1,407 @@ + + + + PartyScreenPartnerSwapConfig + 1 + + + + Video + + + BG_Default + + + + + + + + + 0 + 60 + 1920 + 67.5 + 1 + + + + + + 960 + 75 + 0 + 40.5 + 0 + + + Center + Center + + Outline + TR_SCREENCONFIG_TITLE + + + 112.5 + 157.5 + 0 + 40.5 + 0 + + + Left + Center + + Outline + TR_SCREENCONFIG_NUMPLAYERS + + + 112.5 + 247.5 + 0 + 40.5 + 0 + + + Left + Center + + Outline + TR_SCREENCONFIG_NUMPASSES + + + 112.5 + 337.5 + 0 + 40.5 + 0 + + + Left + Center + + Outline + TR_SCREENCONFIG_HARMONYBONUS + + + 112.5 + 427.5 + 0 + 40.5 + 0 + + + Left + Center + + Outline + TR_SCREENCONFIG_DUETS + + + 112.5 + 517.5 + 0 + 40.5 + 0 + + + Left + Center + + Outline + TR_SCREENCONFIG_NUMJOKERS + + + + + + + + + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlide + SelectSlideArrowLeft + SelectSlideArrowRight + + 750 + 150 + 1050 + 75 + 0 + + + 757.5 + 157.5 + 60 + 60 + 0 + + + 1732.5 + 157.5 + 60 + 60 + 0 + + + + + + + + 40.5 + 75 + 0 + 300 + Outline + Bold + 9 + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlide + SelectSlideArrowLeft + SelectSlideArrowRight + + 750 + 240 + 1050 + 75 + 0 + + + 757.5 + 247.5 + 60 + 60 + 0 + + + 1732.5 + 247.5 + 60 + 60 + 0 + + + + + + + + 40.5 + 75 + 0 + 300 + Outline + Bold + 9 + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlide + SelectSlideArrowLeft + SelectSlideArrowRight + + 750 + 330 + 1050 + 75 + 0 + + + 757.5 + 337.5 + 60 + 60 + 0 + + + 1732.5 + 337.5 + 60 + 60 + 0 + + + + + + + + 40.5 + 75 + 0 + 300 + Outline + Bold + 9 + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlide + SelectSlideArrowLeft + SelectSlideArrowRight + + 750 + 420 + 1050 + 75 + 0 + + + 757.5 + 427.5 + 60 + 60 + 0 + + + 1732.5 + 427.5 + 60 + 60 + 0 + + + + + + + + 40.5 + 75 + 0 + 300 + Outline + Bold + 9 + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlide + SelectSlideArrowLeft + SelectSlideArrowRight + + 750 + 510 + 1050 + 75 + 0 + + + 757.5 + 517.5 + 60 + 60 + 0 + + + 1732.5 + 517.5 + 60 + 60 + 0 + + + + + + + + 40.5 + 75 + 0 + 300 + Outline + Bold + 9 + + + + + + + + + diff --git a/Output/PartyModes/PartnerSwap/Themes/Default/Screens/PartyScreenPartnerSwapMain.xml b/Output/PartyModes/PartnerSwap/Themes/Default/Screens/PartyScreenPartnerSwapMain.xml new file mode 100644 index 00000000..26070008 --- /dev/null +++ b/Output/PartyModes/PartnerSwap/Themes/Default/Screens/PartyScreenPartnerSwapMain.xml @@ -0,0 +1,738 @@ + + + + PartyScreenPartnerSwapMain + 1 + + + + Video + + + BG_Default + + + + + + + + + 0 + 60 + 1920 + 67.5 + 1 + + + + PopupBG + + + 0 + 0 + 1920 + 1080 + -1 + + + + + + 0.1 + 0.09 + 0.25 + 0.75 + + + 30 + 190 + 760 + 720 + 0.8 + + + + + + 0.1 + 0.09 + 0.25 + 0.75 + + + 1470 + 190 + 420 + 292 + 0.8 + + + + + + 1 + 0.8 + 0 + 0.18 + + + 40 + 0 + 740 + 48 + 0.6 + + + + + + + 125 + 0 + 42 + 42 + 0.4 + + + + + + + 925 + 290 + 170 + 170 + 0.4 + + + + + + + 1165 + 290 + 170 + 170 + 0.4 + + + + + + + 1585 + 260 + 90 + 90 + 0.4 + + + + + + + 1685 + 260 + 90 + 90 + 0.4 + + + + + + 960 + 75 + 0 + 40.5 + 0 + + + Center + Center + + Outline + TR_SCREENMAIN_TITLE + + + 960 + 405 + -11 + 40.5 + 570 + + + Center + Center + + Outline + TR_SCREENMAIN_POPUP_REALLYEXIT + + + 110 + 205 + 0 + 34 + 0 + + 0.75 + 0.78 + 0.85 + 1 + + + Right + Center + + Outline + TR_SCREENMAIN_HEADER_POS + + + 180 + 205 + 0 + 34 + 0 + + 0.75 + 0.78 + 0.85 + 1 + + + Left + Center + + Outline + TR_SCREENMAIN_HEADER_NAME + + + 560 + 205 + 0 + 34 + 0 + + 0.75 + 0.78 + 0.85 + 1 + + + Right + Center + + Outline + TR_SCREENMAIN_HEADER_SONGS + + + 765 + 205 + 0 + 34 + 0 + + 0.75 + 0.78 + 0.85 + 1 + + + Right + Center + + Outline + TR_SCREENMAIN_HEADER_AVERAGE + + + 110 + 0 + 0 + 36 + 0 + + + Right + Center + + Outline + + + + 180 + 0 + 0 + 36 + 300 + + + Left + Center + + Outline + + + + 560 + 0 + 0 + 36 + 0 + + + Right + Center + + Outline + + + + 765 + 0 + 0 + 36 + 0 + + + Right + Center + + Outline + + + + 1130 + 205 + 0 + 32 + 620 + + 0.75 + 0.78 + 0.85 + 1 + + + Center + Center + + Outline + + + + 1010 + 478 + 0 + 38 + 220 + + + Center + Center + + Outline + + + + 1250 + 478 + 0 + 38 + 220 + + + Center + Center + + Outline + + + + 1130 + 345 + 0 + 56 + 0 + + 1 + 0.8 + 0 + 1 + + + Center + Center + + Outline + & + + + 1130 + 535 + 0 + 30 + 620 + + 0.75 + 0.78 + 0.85 + 1 + + + Center + Center + + Outline + + + + 1130 + 575 + 0 + 30 + 620 + + 0.75 + 0.78 + 0.85 + 1 + + + Center + Center + + Outline + + + + 1130 + 660 + 0 + 32 + 640 + + + Center + Center + + Outline + + + + 1130 + 705 + 0 + 32 + 640 + + 1 + 0.8 + 0 + 1 + + + Center + Center + + Outline + + + + 1680 + 210 + 0 + 32 + 400 + + 1 + 0.8 + 0 + 1 + + + Center + Center + + Outline + TR_SCREENMAIN_BEST_PAIR + + + 1680 + 365 + 0 + 32 + 400 + + + Center + Center + + Outline + + + + 1680 + 410 + 0 + 48 + 0 + + 1 + 0.8 + 0 + 1 + + + Center + Center + + Outline + + + + 1130 + 215 + 0 + 36 + 0 + + 1 + 0.8 + 0 + 1 + + + Center + Center + + Outline + TR_SCREENMAIN_CHAMPION + + + 1130 + 262 + 0 + 64 + 600 + + 1 + 0.8 + 0 + 1 + + + Center + Center + + Outline + + + + + + + + + + + + + + + + + + + + Star + + 850 + 200 + 560 + 380 + -1 + + + 1 + 0.8 + 0 + 0.6 + + Star + 18 + 40 + + + + diff --git a/Output/PartyModes/PartnerSwap/Themes/Default/Screens/PartyScreenPartnerSwapNames.xml b/Output/PartyModes/PartnerSwap/Themes/Default/Screens/PartyScreenPartnerSwapNames.xml new file mode 100644 index 00000000..3d8c2be7 --- /dev/null +++ b/Output/PartyModes/PartnerSwap/Themes/Default/Screens/PartyScreenPartnerSwapNames.xml @@ -0,0 +1,382 @@ + + + + PartyScreenPartnerSwapNames + 1 + + + + Video + + + BG_Default + + + + + + + + + 0 + 60 + 1920 + 67.5 + 1 + + + + + + 960 + 75 + 0 + 40.5 + 0 + + + Center + Center + + Outline + TR_SCREENNAMES_TITLE + + + + + + + + + + + + + + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlide + SelectSlideArrowLeft + SelectSlideArrowRight + + 60 + 150 + 1800 + 75 + 0 + + + 67.5 + 157.5 + 60 + 60 + 0 + + + 1792.5 + 157.5 + 60 + 60 + 0 + + + + + + + + 40.5 + 75 + 0 + 300 + Outline + Bold + 2 + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlidePlayer + SelectSlideArrowLeft + SelectSlideArrowRight + + 60 + 240 + 1800 + 225 + 0 + + + 67.5 + 315 + 60 + 60 + 0 + + + 1792.5 + 315 + 60 + 60 + 0 + + + + + + + + 40.5 + 75 + 5 + 300 + Outline + Bold + 8 + + + + + + + 142.5 + 525 + 1800 + 589.5 + 0 + + CoverTile + + PlayerSelector + + 150 + 150 + 10 + 2 + 15 + 15 + + -20 + 25.5 + Outline + + + + + + + + + + + diff --git a/Output/PartyModes/PartnerSwap/Themes/Default/Screens/PartyScreenPartnerSwapSongs.xml b/Output/PartyModes/PartnerSwap/Themes/Default/Screens/PartyScreenPartnerSwapSongs.xml new file mode 100644 index 00000000..d3129f36 --- /dev/null +++ b/Output/PartyModes/PartnerSwap/Themes/Default/Screens/PartyScreenPartnerSwapSongs.xml @@ -0,0 +1,407 @@ + + + + PartyScreenPartnerSwapSongs + 1 + + + + Video + + + BG_Default + + + + + + + + + 0 + 60 + 1920 + 67.5 + 1 + + + + + + 960 + 75 + 0 + 40.5 + 0 + + + Center + Center + + Outline + TR_SCREENCONFIG_TITLE + + + 112.5 + 157.5 + 0 + 40.5 + 0 + + + Left + Center + + Outline + TR_SONGSOURCE + + + 112.5 + 435 + 0 + 40.5 + 0 + + + Left + Center + + Outline + TR_GAMEMODE + + + + + + + + + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlide + SelectSlideArrowLeft + SelectSlideArrowRight + + 750 + 150 + 1050 + 75 + 0 + + + 757.5 + 157.5 + 60 + 60 + 0 + + + 1732.5 + 157.5 + 60 + 60 + 0 + + + + + + + + 40.5 + 75 + 0 + 308 + Outline + Bold + 3 + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlide + SelectSlideArrowLeft + SelectSlideArrowRight + + 750 + 240 + 1050 + 75 + 0 + + + 757.5 + 247.5 + 60 + 60 + 0 + + + 1732.5 + 247.5 + 60 + 60 + 0 + + + + + + + + 40.5 + 75 + 0 + 900 + Outline + Bold + 3 + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlide + SelectSlideArrowLeft + SelectSlideArrowRight + + 750 + 240 + 1050 + 75 + 0 + + + 757.5 + 247.5 + 60 + 60 + 0 + + + 1732.5 + 247.5 + 60 + 60 + 0 + + + + + + + + 40.5 + 75 + 0 + 900 + Outline + Bold + 3 + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlide + SelectSlideArrowLeft + SelectSlideArrowRight + + 750 + 330 + 1050 + 75 + 0 + + + 757.5 + 337.5 + 60 + 60 + 0 + + + 1732.5 + 337.5 + 60 + 60 + 0 + + + + + + + + 40.5 + 75 + 0 + 900 + Outline + Bold + 1 + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlide + SelectSlideArrowLeft + SelectSlideArrowRight + + 750 + 435 + 1050 + 75 + 0 + + + 757.5 + 442.5 + 60 + 60 + 0 + + + 1732.5 + 442.5 + 60 + 60 + 0 + + + + + + + + 40.5 + 75 + 0 + 308 + Outline + Bold + 2 + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlide + SelectSlideArrowLeft + SelectSlideArrowRight + + 750 + 540 + 1050 + 75 + 0 + + + 757.5 + 547.5 + 60 + 60 + 0 + + + 1732.5 + 547.5 + 60 + 60 + 0 + + + + + + + + 40.5 + 75 + 0 + 308 + Outline + Bold + 5 + + + + + + + + + diff --git a/PartyModes/PartyModePartnerSwap/CPartyModePartnerSwap.cs b/PartyModes/PartyModePartnerSwap/CPartyModePartnerSwap.cs new file mode 100644 index 00000000..1fe85f75 --- /dev/null +++ b/PartyModes/PartyModePartnerSwap/CPartyModePartnerSwap.cs @@ -0,0 +1,734 @@ +#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 System.Linq; +using System.Runtime.InteropServices; +using VocaluxeLib.Menu; +using VocaluxeLib.Utils; + +[assembly: ComVisible(false)] + +namespace VocaluxeLib.PartyModes.PartnerSwap +{ + public enum EDuetSongs + { + Mixed, + DuetsOnly, + NoDuets + } + + public class CSwapPlayer + { + public Guid ProfileId; + public int TotalPoints; + public int NumSongs; + public int Jokers; + + public int Average + { + get { return NumSongs == 0 ? 0 : (int)Math.Round((double)TotalPoints / NumSongs); } + } + } + + public class CSwapPair + { + public CSwapPlayer[] Players = new CSwapPlayer[2]; + public int[] Scores = new int[2]; + public int Bonus; + public bool Sung; + + public int PairScore + { + get { return Scores[0] + Scores[1] + Bonus; } + } + } + + public abstract class CPartyScreenPartnerSwap : CMenuParty + { + protected new CPartyModePartnerSwap _PartyMode; + + public override void Init() + { + base.Init(); + _PartyMode = (CPartyModePartnerSwap)base._PartyMode; + } + } + + public sealed class CPartyModePartnerSwap : CPartyMode + { + public const int PlayersPerSong = 2; + public const int MaxJokers = 3; + public const int HarmonyRange = 500; + public const int HarmonyBonusPoints = 500; + + public override int MinMics + { + get { return PlayersPerSong; } + } + public override int MaxMics + { + get { return CBase.Config.GetMaxNumMics(); } + } + public override int MinPlayers + { + get { return 3; } + } + public override int MaxPlayers + { + get { return 12; } + } + public override int MinTeams + { + get { return 1; } + } + public override int MaxTeams + { + get { return 1; } + } + public override int MinPlayersPerTeam + { + get { return MinPlayers; } + } + public override int MaxPlayersPerTeam + { + get { return MaxPlayers; } + } + + private enum EStage + { + Config, + Songs, + Names, + Main, + SongSelection, + Singing, + MedleySinging + } + + public struct SData + { + public int NumPlayer; + public int NumPasses; + public bool HarmonyBonus; + public EDuetSongs DuetSongs; + public int NumJokers; + public List ProfileIds; + + public ESongSource SongSource; + public ESongSorting Sorting; + public int CategoryIndex; + public int PlaylistId; + + public EGameMode GameMode; + public int NumMedleySongs; + + public List Players; + public List> Passes; + public List PassBreaks; + public int PassIndex; + public int PairIndex; + public int NumSongsSung; + public CSwapPair BestPair; + public CSwapPair LastPair; + public List PreviousRanking; + + public List Songs; + } + + public SData GameData; + private EStage _Stage; + + public CPartyModePartnerSwap(int id) : base(id) + { + _ScreenSongOptions.Selection.RandomOnly = false; + _ScreenSongOptions.Selection.PartyMode = true; + _ScreenSongOptions.Selection.CategoryChangeAllowed = true; + _ScreenSongOptions.Selection.NumJokers = new int[] { 1, 1 }; + _ScreenSongOptions.Selection.TeamNames = new string[] { "foo", "bar" }; + + _ScreenSongOptions.Sorting.SearchString = string.Empty; + _ScreenSongOptions.Sorting.SearchActive = false; + _ScreenSongOptions.Sorting.DuetOptions = EDuetOptions.All; + _ScreenSongOptions.Sorting.FilterPlaylistId = -1; + + GameData = new SData + { + NumPlayer = 6, + NumPasses = 3, + HarmonyBonus = true, + DuetSongs = EDuetSongs.Mixed, + NumJokers = 1, + ProfileIds = new List(), + Sorting = CBase.Config.GetSongSorting(), + SongSource = ESongSource.TR_SONGSOURCE_ALLSONGS, + PlaylistId = 0, + CategoryIndex = 0, + GameMode = EGameMode.TR_GAMEMODE_NORMAL, + NumMedleySongs = 5, + Players = new List(), + Passes = new List>(), + PassBreaks = new List(), + PreviousRanking = new List(), + Songs = new List() + }; + } + + public override void SetDefaults() + { + _Stage = EStage.Config; + + _ScreenSongOptions.Sorting.IgnoreArticles = CBase.Config.GetIgnoreArticles(); + _ScreenSongOptions.Sorting.SongSorting = CBase.Config.GetSongSorting(); + _ScreenSongOptions.Sorting.Tabs = EOffOn.TR_CONFIG_OFF; + _ScreenSongOptions.Selection.SongIndex = -1; + _ScreenSongOptions.Selection.CategoryIndex = -1; + + if (CBase.Config.GetTabs() == EOffOn.TR_CONFIG_ON && _ScreenSongOptions.Sorting.SongSorting != ESongSorting.TR_CONFIG_NONE) + { + _ScreenSongOptions.Sorting.Tabs = EOffOn.TR_CONFIG_ON; + } + } + + public override bool Init() + { + if (!base.Init()) + { + return false; + } + + SetDefaults(); + return true; + } + + public override void UpdateGame() { } + + public static int GetMaxPasses(int numPlayer) + { + return numPlayer % 2 == 0 ? numPlayer - 1 : numPlayer; + } + + public bool IsFinished + { + get { return GameData.Passes.Count > 0 && GameData.PassIndex >= GameData.Passes.Count; } + } + + public CSwapPair CurrentPair + { + get + { + if (IsFinished || GameData.Passes.Count == 0) + { + return null; + } + + return GameData.Passes[GameData.PassIndex][GameData.PairIndex]; + } + } + + public CSwapPlayer CurrentBreak + { + get { return IsFinished || GameData.PassIndex >= GameData.PassBreaks.Count ? null : GameData.PassBreaks[GameData.PassIndex]; } + } + + public List GetRanking() + { + return GameData.Players.OrderByDescending(player => player.Average).ThenByDescending(player => player.TotalPoints).ToList(); + } + + public int GetTimesTogether(CSwapPlayer player1, CSwapPlayer player2) + { + var count = 0; + foreach (var pass in GameData.Passes) + { + foreach (var pair in pass) + { + if (pair.Sung && pair.Players.Contains(player1) && pair.Players.Contains(player2)) + { + count++; + } + } + } + + return count; + } + + private IMenu _GetNextScreen() + { + switch (_Stage) + { + case EStage.Config: + return _Screens["CPartyScreenPartnerSwapConfig"]; + case EStage.Songs: + return _Screens["CPartyScreenPartnerSwapSongs"]; + case EStage.Names: + return _Screens["CPartyScreenPartnerSwapNames"]; + case EStage.Main: + return _Screens["CPartyScreenPartnerSwapMain"]; + case EStage.SongSelection: + return CBase.Graphics.GetScreen(EScreen.Song); + case EStage.Singing: + case EStage.MedleySinging: + return CBase.Graphics.GetScreen(EScreen.Sing); + default: + throw new ArgumentException("Invalid stage: " + _Stage); + } + } + + private void _FadeToScreen() + { + CBase.Graphics.FadeTo(_GetNextScreen()); + } + + public void Next() + { + switch (_Stage) + { + case EStage.Config: + _Stage = EStage.Songs; + break; + case EStage.Songs: + _Stage = EStage.Names; + break; + case EStage.Names: + _Stage = EStage.Main; + _StartGame(); + break; + case EStage.Main: + if (CurrentPair == null) + { + return; + } + + if (GameData.GameMode == EGameMode.TR_GAMEMODE_MEDLEY) + { + _Stage = EStage.MedleySinging; + _PrepareMedleyRound(); + } + else + { + _Stage = EStage.SongSelection; + _PrepareSongSelection(); + } + + break; + case EStage.SongSelection: + _Stage = EStage.Singing; + break; + case EStage.MedleySinging: + case EStage.Singing: + _Stage = EStage.Main; + _UpdateScores(); + break; + default: + throw new ArgumentException("Invalid stage: " + _Stage); + } + + _FadeToScreen(); + } + + public void Back() + { + switch (_Stage) + { + case EStage.Config: + CBase.Graphics.FadeTo(EScreen.Party); + return; + case EStage.Songs: + _Stage = EStage.Config; + break; + case EStage.Names: + _Stage = EStage.Songs; + break; + case EStage.Main: + _Stage = EStage.Names; + break; + default: + throw new ArgumentException("Invalid stage: " + _Stage); + } + + _FadeToScreen(); + } + + public override IMenu GetStartScreen() + { + return _Screens["CPartyScreenPartnerSwapConfig"]; + } + + public override SScreenSongOptions GetScreenSongOptions() + { + return _ScreenSongOptions; + } + + public override void OnSongChange(int songIndex, ref SScreenSongOptions screenSongOptions) + { + if (_ScreenSongOptions.Selection.SelectNextRandomSong && songIndex != -1) + { + _ScreenSongOptions.Selection.SelectNextRandomSong = false; + } + + _ScreenSongOptions.Selection.SongIndex = songIndex; + + screenSongOptions = _ScreenSongOptions; + } + + public override void OnCategoryChange(int categoryIndex, ref SScreenSongOptions screenSongOptions) + { + if (categoryIndex != -1 || CBase.Config.GetTabs() == EOffOn.TR_CONFIG_OFF) + { + _ScreenSongOptions.Selection.SelectNextRandomSong = true; + _ScreenSongOptions.Selection.RandomOnly = true; + } + else + { + _ScreenSongOptions.Selection.SongIndex = -1; + _ScreenSongOptions.Selection.RandomOnly = false; + } + + _ScreenSongOptions.Selection.CategoryIndex = categoryIndex; + + screenSongOptions = _ScreenSongOptions; + } + + public override void SetSearchString(string searchString, bool visible) + { + _ScreenSongOptions.Sorting.SearchString = searchString; + _ScreenSongOptions.Sorting.SearchActive = visible; + } + + public override void JokerUsed(int teamNr) + { + if (_ScreenSongOptions.Selection.NumJokers == null || teamNr >= _ScreenSongOptions.Selection.NumJokers.Length) + { + return; + } + + var pair = CurrentPair; + if (pair != null && pair.Players[teamNr].Jokers > 0) + { + pair.Players[teamNr].Jokers--; + } + + _ScreenSongOptions.Selection.NumJokers[teamNr]--; + _ScreenSongOptions.Selection.RandomOnly = true; + _ScreenSongOptions.Selection.CategoryChangeAllowed = false; + } + + public override void SongSelected(int songId) + { + _PrepareRound(new int[] { songId }); + + Next(); + } + + public override void LeavingHighscore() + { + for (var i = 0; i < CBase.Game.GetNumSongs(); i++) + { + CBase.Songs.AddPartySongSung(CBase.Game.GetSong(i).Id); + } + + Next(); + } + + private void _StartGame() + { + CBase.Songs.ResetSongSung(); + + GameData.Players = new List(); + foreach (var profileId in GameData.ProfileIds) + { + GameData.Players.Add(new CSwapPlayer { ProfileId = profileId, Jokers = GameData.NumJokers }); + } + + var slots = new List(GameData.Players); + slots.Shuffle(); + if (slots.Count % 2 == 1) + { + slots.Add(null); + } + + GameData.Passes = new List>(); + GameData.PassBreaks = new List(); + var numPasses = Math.Max(1, Math.Min(GameData.NumPasses, GetMaxPasses(GameData.Players.Count))); + for (var pass = 0; pass < numPasses; pass++) + { + var pairs = new List(); + CSwapPlayer pause = null; + for (var i = 0; i < slots.Count / 2; i++) + { + var player1 = slots[i]; + var player2 = slots[slots.Count - 1 - i]; + if (player1 == null || player2 == null) + { + pause = player1 ?? player2; + continue; + } + + var pair = new CSwapPair(); + pair.Players[0] = player1; + pair.Players[1] = player2; + pairs.Add(pair); + } + + pairs.Shuffle(); + GameData.Passes.Add(pairs); + GameData.PassBreaks.Add(pause); + + var last = slots[slots.Count - 1]; + slots.RemoveAt(slots.Count - 1); + slots.Insert(1, last); + } + + GameData.PassIndex = 0; + GameData.PairIndex = 0; + GameData.NumSongsSung = 0; + GameData.BestPair = null; + GameData.LastPair = null; + GameData.PreviousRanking = GetRanking(); + GameData.Songs = new List(); + } + + private EDuetOptions _GetDuetOptions() + { + switch (GameData.DuetSongs) + { + case EDuetSongs.NoDuets: + return EDuetOptions.NoDuets; + case EDuetSongs.DuetsOnly: + return CBase.Songs.GetSongs().Any(song => song.IsDuet) ? EDuetOptions.Duets : EDuetOptions.All; + default: + return EDuetOptions.All; + } + } + + private void _PrepareMedleyRound() + { + var songIds = new List(); + for (var i = 0; i < GameData.NumMedleySongs; i++) + { + if (GameData.Songs.Count == 0) + { + _UpdateSongList(); + } + + if (GameData.Songs.Count == 0) + { + break; + } + + songIds.Add(GameData.Songs[0]); + GameData.Songs.RemoveAt(0); + } + + _PrepareRound(songIds.ToArray()); + } + + private void _PrepareSongSelection() + { + _ScreenSongOptions.Selection.RandomOnly = true; + _ScreenSongOptions.Selection.SelectNextRandomSong = true; + + _ScreenSongOptions.Sorting.IgnoreArticles = CBase.Config.GetIgnoreArticles(); + _ScreenSongOptions.Sorting.DuetOptions = _GetDuetOptions(); + + switch (GameData.SongSource) + { + case ESongSource.TR_SONGSOURCE_ALLSONGS: + _ScreenSongOptions.Sorting.SongSorting = CBase.Config.GetSongSorting(); + _ScreenSongOptions.Sorting.Tabs = CBase.Config.GetTabs(); + _ScreenSongOptions.Sorting.FilterPlaylistId = -1; + + _ScreenSongOptions.Selection.SongIndex = -1; + _ScreenSongOptions.Selection.CategoryIndex = -1; + _ScreenSongOptions.Selection.CategoryChangeAllowed = true; + break; + + case ESongSource.TR_SONGSOURCE_CATEGORY: + _ScreenSongOptions.Sorting.SongSorting = GameData.Sorting; + _ScreenSongOptions.Sorting.Tabs = EOffOn.TR_CONFIG_ON; + _ScreenSongOptions.Sorting.FilterPlaylistId = -1; + + _ScreenSongOptions.Selection.CategoryIndex = GameData.CategoryIndex; + _ScreenSongOptions.Selection.CategoryChangeAllowed = false; + break; + + case ESongSource.TR_SONGSOURCE_PLAYLIST: + _ScreenSongOptions.Sorting.SongSorting = CBase.Config.GetSongSorting(); + _ScreenSongOptions.Sorting.Tabs = EOffOn.TR_CONFIG_OFF; + _ScreenSongOptions.Sorting.FilterPlaylistId = GameData.PlaylistId; + + _ScreenSongOptions.Selection.CategoryChangeAllowed = false; + break; + } + + var pair = CurrentPair; + _ScreenSongOptions.Selection.NumJokers = new int[] { pair.Players[0].Jokers, pair.Players[1].Jokers }; + _ScreenSongOptions.Selection.TeamNames = new string[] + { + CBase.Profiles.GetPlayerName(pair.Players[0].ProfileId), + CBase.Profiles.GetPlayerName(pair.Players[1].ProfileId) + }; + } + + private bool _PrepareRound(int[] songIds) + { + CBase.Game.Reset(); + CBase.Game.ClearSongs(); + + CBase.Game.SetNumPlayer(PlayersPerSong); + var players = CBase.Game.GetPlayers(); + var pair = CurrentPair; + if (players == null || players.Length < PlayersPerSong || pair == null) + { + return false; + } + + for (var p = 0; p < PlayersPerSong; p++) + { + players[p].ProfileId = pair.Players[p].ProfileId; + players[p].VoiceNr = p; + } + + foreach (var songId in songIds) + { + var song = CBase.Songs.GetSongById(songId); + var gameMode = GameData.GameMode; + if (gameMode != EGameMode.TR_GAMEMODE_MEDLEY) + { + if (song.IsDuet) + { + gameMode = EGameMode.TR_GAMEMODE_DUET; + } + else if (!song.IsGameModeAvailable(gameMode)) + { + gameMode = EGameMode.TR_GAMEMODE_NORMAL; + } + } + + CBase.Game.AddSong(songId, gameMode); + } + + return true; + } + + private void _UpdateSongList() + { + if (GameData.Songs.Count > 0) + { + return; + } + + switch (GameData.SongSource) + { + case ESongSource.TR_SONGSOURCE_PLAYLIST: + for (var i = 0; i < CBase.Playlist.GetSongCount(GameData.PlaylistId); i++) + { + var id = CBase.Playlist.GetSong(GameData.PlaylistId, i).SongId; + var song = CBase.Songs.GetSongById(id); + if (song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_MEDLEY) && !song.IsDuet) + { + GameData.Songs.Add(id); + } + } + + break; + + case ESongSource.TR_SONGSOURCE_ALLSONGS: + var avSongs = CBase.Songs.GetSongs(); + GameData.Songs.AddRange(avSongs.Where(song => song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_MEDLEY) && !song.IsDuet).Select(song => song.Id)); + break; + + case ESongSource.TR_SONGSOURCE_CATEGORY: + var oldSorting = CBase.Config.GetSongSorting(); + CBase.Songs.SortSongs(GameData.Sorting, EOffOn.TR_CONFIG_ON, CBase.Config.GetIgnoreArticles(), string.Empty, EDuetOptions.NoDuets, -1); + + CBase.Songs.SetCategory(GameData.CategoryIndex); + avSongs = CBase.Songs.GetVisibleSongs(); + GameData.Songs.AddRange(avSongs.Where(song => song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_MEDLEY) && !song.IsDuet).Select(song => song.Id)); + + CBase.Songs.SetCategory(-1); + CBase.Songs.SortSongs(oldSorting, CBase.Config.GetTabs(), CBase.Config.GetIgnoreArticles(), string.Empty, EDuetOptions.NoDuets, -1); + break; + } + + GameData.Songs.Shuffle(); + } + + private void _UpdateScores() + { + var pair = CurrentPair; + if (pair == null) + { + return; + } + + var points = CBase.Game.GetPoints(); + if (points == null || points.NumRounds == 0) + { + return; + } + + var scores = new double[PlayersPerSong]; + for (var round = 0; round < points.NumRounds; round++) + { + var res = points.GetPlayer(round, PlayersPerSong); + if (res == null || res.Length < PlayersPerSong) + { + return; + } + + for (var p = 0; p < PlayersPerSong; p++) + { + scores[p] += res[p].Points; + } + } + + GameData.PreviousRanking = GetRanking(); + + for (var p = 0; p < PlayersPerSong; p++) + { + pair.Scores[p] = (int)Math.Round(scores[p] / points.NumRounds); + } + + pair.Bonus = GameData.HarmonyBonus && Math.Abs(pair.Scores[0] - pair.Scores[1]) <= HarmonyRange ? HarmonyBonusPoints : 0; + pair.Sung = true; + + foreach (var player in pair.Players) + { + player.TotalPoints += pair.PairScore; + player.NumSongs++; + } + + if (GameData.BestPair == null || pair.PairScore > GameData.BestPair.PairScore) + { + GameData.BestPair = pair; + } + + GameData.LastPair = pair; + GameData.NumSongsSung++; + + GameData.PairIndex++; + if (GameData.PairIndex >= GameData.Passes[GameData.PassIndex].Count) + { + GameData.PairIndex = 0; + GameData.PassIndex++; + } + } + } +} diff --git a/PartyModes/PartyModePartnerSwap/CPartyScreenPartnerSwapConfig.cs b/PartyModes/PartyModePartnerSwap/CPartyScreenPartnerSwapConfig.cs new file mode 100644 index 00000000..f087a5a6 --- /dev/null +++ b/PartyModes/PartyModePartnerSwap/CPartyScreenPartnerSwapConfig.cs @@ -0,0 +1,173 @@ +#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.Windows.Forms; + +namespace VocaluxeLib.PartyModes.PartnerSwap +{ + public class CPartyScreenPartnerSwapConfig : CPartyScreenPartnerSwap + { + protected override int _ScreenVersion + { + get { return 1; } + } + + private const string _SelectSlideNumPlayers = "SelectSlideNumPlayers"; + private const string _SelectSlideNumPasses = "SelectSlideNumPasses"; + private const string _SelectSlideHarmonyBonus = "SelectSlideHarmonyBonus"; + private const string _SelectSlideDuetSongs = "SelectSlideDuetSongs"; + private const string _SelectSlideNumJokers = "SelectSlideNumJokers"; + private const string _ButtonNext = "ButtonNext"; + private const string _ButtonBack = "ButtonBack"; + + public override void Init() + { + base.Init(); + + _ThemeSelectSlides = new string[] { _SelectSlideNumPlayers, _SelectSlideNumPasses, _SelectSlideHarmonyBonus, _SelectSlideDuetSongs, _SelectSlideNumJokers }; + _ThemeButtons = new string[] { _ButtonNext, _ButtonBack }; + } + + public override bool HandleInput(SKeyEvent keyEvent) + { + base.HandleInput(keyEvent); + + if (!keyEvent.KeyPressed) + { + switch (keyEvent.Key) + { + case Keys.Back: + case Keys.Escape: + _PartyMode.Back(); + break; + + case Keys.Enter: + _UpdateSlides(); + + if (_Buttons[_ButtonBack].Selected) + { + _PartyMode.Back(); + } + + if (_Buttons[_ButtonNext].Selected) + { + _PartyMode.Next(); + } + + break; + + case Keys.Left: + case Keys.Right: + _UpdateSlides(); + break; + } + } + + return true; + } + + public override bool HandleMouse(SMouseEvent mouseEvent) + { + base.HandleMouse(mouseEvent); + + if (mouseEvent.LB && _IsMouseOverCurSelection(mouseEvent)) + { + _UpdateSlides(); + if (_Buttons[_ButtonBack].Selected) + { + _PartyMode.Back(); + } + + if (_Buttons[_ButtonNext].Selected) + { + _PartyMode.Next(); + } + } + + if (mouseEvent.RB) + { + _PartyMode.Back(); + } + + return true; + } + + public override void OnShow() + { + base.OnShow(); + + _SelectSlides[_SelectSlideNumPlayers].Clear(); + for (var i = _PartyMode.MinPlayers; i <= _PartyMode.MaxPlayers; i++) + { + _SelectSlides[_SelectSlideNumPlayers].AddValue(i.ToString()); + } + + _SelectSlides[_SelectSlideNumPlayers].SelectedValue = _PartyMode.GameData.NumPlayer.ToString(); + + _UpdatePassesSlide(); + + _SelectSlides[_SelectSlideHarmonyBonus].Clear(); + _SelectSlides[_SelectSlideHarmonyBonus].AddValue(CBase.Language.Translate("TR_BUTTON_NO", PartyModeId)); + _SelectSlides[_SelectSlideHarmonyBonus].AddValue(CBase.Language.Translate("TR_BUTTON_YES", PartyModeId)); + _SelectSlides[_SelectSlideHarmonyBonus].Selection = _PartyMode.GameData.HarmonyBonus ? 1 : 0; + + _SelectSlides[_SelectSlideDuetSongs].Clear(); + _SelectSlides[_SelectSlideDuetSongs].AddValue(CBase.Language.Translate("TR_SCREENCONFIG_DUETS_MIXED", PartyModeId)); + _SelectSlides[_SelectSlideDuetSongs].AddValue(CBase.Language.Translate("TR_SCREENCONFIG_DUETS_ONLY", PartyModeId)); + _SelectSlides[_SelectSlideDuetSongs].AddValue(CBase.Language.Translate("TR_SCREENCONFIG_DUETS_NONE", PartyModeId)); + _SelectSlides[_SelectSlideDuetSongs].Selection = (int)_PartyMode.GameData.DuetSongs; + + _SelectSlides[_SelectSlideNumJokers].Clear(); + for (var i = 0; i <= CPartyModePartnerSwap.MaxJokers; i++) + { + _SelectSlides[_SelectSlideNumJokers].AddValue(i.ToString()); + } + + _SelectSlides[_SelectSlideNumJokers].SelectedValue = _PartyMode.GameData.NumJokers.ToString(); + } + + public override bool UpdateGame() + { + return true; + } + + private void _UpdateSlides() + { + _PartyMode.GameData.NumPlayer = _SelectSlides[_SelectSlideNumPlayers].Selection + _PartyMode.MinPlayers; + _PartyMode.GameData.NumPasses = _SelectSlides[_SelectSlideNumPasses].Selection + 1; + _PartyMode.GameData.HarmonyBonus = _SelectSlides[_SelectSlideHarmonyBonus].Selection == 1; + _PartyMode.GameData.DuetSongs = (EDuetSongs)_SelectSlides[_SelectSlideDuetSongs].Selection; + _PartyMode.GameData.NumJokers = _SelectSlides[_SelectSlideNumJokers].Selection; + _UpdatePassesSlide(); + } + + private void _UpdatePassesSlide() + { + var maxPasses = CPartyModePartnerSwap.GetMaxPasses(_PartyMode.GameData.NumPlayer); + _PartyMode.GameData.NumPasses = Math.Max(1, Math.Min(maxPasses, _PartyMode.GameData.NumPasses)); + + _SelectSlides[_SelectSlideNumPasses].Clear(); + for (var i = 1; i <= maxPasses; i++) + { + _SelectSlides[_SelectSlideNumPasses].AddValue(i.ToString()); + } + + _SelectSlides[_SelectSlideNumPasses].Selection = _PartyMode.GameData.NumPasses - 1; + } + } +} diff --git a/PartyModes/PartyModePartnerSwap/CPartyScreenPartnerSwapMain.cs b/PartyModes/PartyModePartnerSwap/CPartyScreenPartnerSwapMain.cs new file mode 100644 index 00000000..f5a1bfd9 --- /dev/null +++ b/PartyModes/PartyModePartnerSwap/CPartyScreenPartnerSwapMain.cs @@ -0,0 +1,527 @@ +#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 System.Diagnostics; +using System.Windows.Forms; +using VocaluxeLib.Menu; + +namespace VocaluxeLib.PartyModes.PartnerSwap +{ + class CRankRow + { + public CSwapPlayer Player; + public CStatic Highlight; + public CStatic Avatar; + public CText Pos; + public CText Name; + public CText Songs; + public CText Average; + public int OldRank; + public int NewRank; + } + + public class CPartyScreenPartnerSwapMain : CPartyScreenPartnerSwap + { + protected override int _ScreenVersion + { + get { return 1; } + } + + private const string _TextPopupReallyExit = "TextPopupReallyExit"; + private const string _TextPass = "TextPass"; + private const string _TextRowPos = "TextRowPos"; + private const string _TextRowName = "TextRowName"; + private const string _TextRowSongs = "TextRowSongs"; + private const string _TextRowAverage = "TextRowAverage"; + private const string _TextPairName1 = "TextPairName1"; + private const string _TextPairName2 = "TextPairName2"; + private const string _TextAmp = "TextAmp"; + private const string _TextTogether = "TextTogether"; + private const string _TextPause = "TextPause"; + private const string _TextLastResult = "TextLastResult"; + private const string _TextHarmony = "TextHarmony"; + private const string _TextBestLabel = "TextBestLabel"; + private const string _TextBestNames = "TextBestNames"; + private const string _TextBestScore = "TextBestScore"; + private const string _TextChampionLabel = "TextChampionLabel"; + private const string _TextChampion = "TextChampion"; + + private const string _ButtonNextRound = "ButtonNextRound"; + private const string _ButtonBack = "ButtonBack"; + private const string _ButtonExit = "ButtonExit"; + private const string _ButtonPopupYes = "ButtonPopupYes"; + private const string _ButtonPopupNo = "ButtonPopupNo"; + + private const string _StaticPopupBG = "StaticPopupBG"; + private const string _StaticRowHighlight = "StaticRowHighlight"; + private const string _StaticRowAvatar = "StaticRowAvatar"; + private const string _StaticPairAvatar1 = "StaticPairAvatar1"; + private const string _StaticPairAvatar2 = "StaticPairAvatar2"; + private const string _StaticBestAvatar1 = "StaticBestAvatar1"; + private const string _StaticBestAvatar2 = "StaticBestAvatar2"; + + private const string _ParticleEffectChampion = "ParticleEffectChampion"; + + private const float _FirstRowY = 260f; + private const float _RowStep = 54f; + private const float _RankDelay = 300f; + private const float _RankDuration = 700f; + private const float _PopDuration = 700f; + + private readonly string[] _RankColors = new string[] { "Top1Color", "Top2Color", "Top3Color" }; + + private bool _ExitPopupVisible; + private List _Rows; + private readonly Stopwatch _AnimTimer = new Stopwatch(); + private bool _ShowNewResult; + private int _LastSeenSongs = -1; + private float _LastResultHeight; + private float _HarmonyHeight; + private float _ChampionHeight; + private SRectF _PairAvatar1Rect; + + public override void Init() + { + base.Init(); + + _ThemeTexts = new string[] + { + _TextPopupReallyExit, _TextPass, _TextRowPos, _TextRowName, _TextRowSongs, _TextRowAverage, _TextPairName1, _TextPairName2, _TextAmp, _TextTogether, + _TextPause, _TextLastResult, _TextHarmony, _TextBestLabel, _TextBestNames, _TextBestScore, _TextChampionLabel, _TextChampion + }; + _ThemeButtons = new string[] { _ButtonNextRound, _ButtonBack, _ButtonExit, _ButtonPopupYes, _ButtonPopupNo }; + _ThemeStatics = new string[] + { + _StaticPopupBG, _StaticRowHighlight, _StaticRowAvatar, _StaticPairAvatar1, _StaticPairAvatar2, _StaticBestAvatar1, + _StaticBestAvatar2 + }; + _ThemeParticleEffects = new string[] { _ParticleEffectChampion }; + } + + public override void LoadTheme(string xmlPath) + { + base.LoadTheme(xmlPath); + + _Rows = new List(); + for (var i = 0; i < _PartyMode.MaxPlayers; i++) + { + var row = new CRankRow + { + Highlight = GetNewStatic(_Statics[_StaticRowHighlight]), + Avatar = GetNewStatic(_Statics[_StaticRowAvatar]), + Pos = GetNewText(_Texts[_TextRowPos]), + Name = GetNewText(_Texts[_TextRowName]), + Songs = GetNewText(_Texts[_TextRowSongs]), + Average = GetNewText(_Texts[_TextRowAverage]) + }; + row.Avatar.Aspect = EAspect.Crop; + _AddStatic(row.Highlight); + _AddStatic(row.Avatar); + _AddText(row.Pos); + _AddText(row.Name); + _AddText(row.Songs); + _AddText(row.Average); + _Rows.Add(row); + } + + _Statics[_StaticRowHighlight].Visible = false; + _Statics[_StaticRowAvatar].Visible = false; + _Texts[_TextRowPos].Visible = false; + _Texts[_TextRowName].Visible = false; + _Texts[_TextRowSongs].Visible = false; + _Texts[_TextRowAverage].Visible = false; + + _Statics[_StaticPairAvatar1].Aspect = EAspect.Crop; + _Statics[_StaticPairAvatar2].Aspect = EAspect.Crop; + _Statics[_StaticBestAvatar1].Aspect = EAspect.Crop; + _Statics[_StaticBestAvatar2].Aspect = EAspect.Crop; + _PairAvatar1Rect = _Statics[_StaticPairAvatar1].Rect; + + _LastResultHeight = _Texts[_TextLastResult].Font.Height; + _HarmonyHeight = _Texts[_TextHarmony].Font.Height; + _ChampionHeight = _Texts[_TextChampion].Font.Height; + } + + public override bool HandleInput(SKeyEvent keyEvent) + { + base.HandleInput(keyEvent); + + if (!keyEvent.KeyPressed) + { + switch (keyEvent.Key) + { + case Keys.Back: + case Keys.Escape: + _OnBack(); + break; + + case Keys.Enter: + _OnSelect(); + break; + } + } + + return true; + } + + public override bool HandleMouse(SMouseEvent mouseEvent) + { + base.HandleMouse(mouseEvent); + + if (mouseEvent.LB && _IsMouseOverCurSelection(mouseEvent)) + { + _OnSelect(); + } + + if (mouseEvent.RB) + { + _OnBack(); + } + + return true; + } + + public override void OnShow() + { + base.OnShow(); + + _ShowNewResult = _PartyMode.GameData.LastPair != null && _PartyMode.GameData.NumSongsSung != _LastSeenSongs; + _LastSeenSongs = _PartyMode.GameData.NumSongsSung; + + _UpdateRanking(); + _UpdatePair(); + _UpdateBestPair(); + _UpdateLastResult(); + + _AnimTimer.Reset(); + _AnimTimer.Start(); + _UpdateAnimations(); + + var started = _PartyMode.GameData.NumSongsSung > 0; + _Buttons[_ButtonBack].Visible = !started; + _Buttons[_ButtonExit].Visible = started; + _Buttons[_ButtonNextRound].Visible = !_PartyMode.IsFinished; + + _ShowPopup(false); + + if (_PartyMode.IsFinished) + { + _SelectElement(_Buttons[_ButtonExit]); + } + else + { + _SelectElement(_Buttons[_ButtonNextRound]); + } + } + + public override bool UpdateGame() + { + _UpdateAnimations(); + return true; + } + + private void _OnBack() + { + if (_ExitPopupVisible) + { + _ShowPopup(false); + } + else if (_PartyMode.GameData.NumSongsSung == 0) + { + _PartyMode.Back(); + } + else if (_PartyMode.IsFinished) + { + _EndParty(); + } + else + { + _ShowPopup(true); + } + } + + private void _OnSelect() + { + if (_ExitPopupVisible) + { + if (_Buttons[_ButtonPopupYes].Selected) + { + _EndParty(); + } + + if (_Buttons[_ButtonPopupNo].Selected) + { + _ShowPopup(false); + } + + return; + } + + if (_Buttons[_ButtonNextRound].Selected && _Buttons[_ButtonNextRound].Visible) + { + _PartyMode.Next(); + } + + if (_Buttons[_ButtonBack].Selected && _Buttons[_ButtonBack].Visible) + { + _PartyMode.Back(); + } + + if (_Buttons[_ButtonExit].Selected && _Buttons[_ButtonExit].Visible) + { + if (_PartyMode.IsFinished) + { + _EndParty(); + } + else + { + _ShowPopup(true); + } + } + } + + private void _EndParty() + { + CBase.Graphics.FadeTo(EScreen.Party); + } + + private void _ShowPopup(bool visible) + { + _ExitPopupVisible = visible; + + _Statics[_StaticPopupBG].Visible = _ExitPopupVisible; + _Texts[_TextPopupReallyExit].Visible = _ExitPopupVisible; + _Buttons[_ButtonPopupYes].Visible = _ExitPopupVisible; + _Buttons[_ButtonPopupNo].Visible = _ExitPopupVisible; + + if (_ExitPopupVisible) + { + _SelectElement(_Buttons[_ButtonPopupNo]); + } + } + + private static float _EaseInOut(float t) + { + return t < 0.5f ? 4f * t * t * t : 1f - (float)Math.Pow(-2f * t + 2f, 3) / 2f; + } + + private static float _EaseOutBack(float t) + { + const float c1 = 1.70158f; + const float c3 = c1 + 1f; + return 1f + c3 * (float)Math.Pow(t - 1f, 3) + c1 * (float)Math.Pow(t - 1f, 2); + } + + private string _GetName(CSwapPlayer player) + { + return CBase.Profiles.GetPlayerName(player.ProfileId); + } + + private string _GetPairNames(CSwapPair pair) + { + return _GetName(pair.Players[0]) + " & " + _GetName(pair.Players[1]); + } + + private void _UpdateRanking() + { + var ranking = _PartyMode.GetRanking(); + var previous = _ShowNewResult ? _PartyMode.GameData.PreviousRanking : ranking; + + for (var i = 0; i < _Rows.Count; i++) + { + var row = _Rows[i]; + var visible = i < ranking.Count; + row.Player = visible ? _PartyMode.GameData.Players[i] : null; + row.Avatar.Visible = visible; + row.Pos.Visible = visible; + row.Name.Visible = visible; + row.Songs.Visible = visible; + row.Average.Visible = visible; + row.Highlight.Visible = false; + if (!visible) + { + continue; + } + + row.NewRank = ranking.IndexOf(row.Player); + row.OldRank = previous.IndexOf(row.Player); + if (row.OldRank < 0) + { + row.OldRank = row.NewRank; + } + + row.Avatar.Texture = CBase.Profiles.GetAvatar(row.Player.ProfileId); + row.Name.Text = _GetName(row.Player); + row.Songs.Text = row.Player.NumSongs.ToString(); + row.Average.Text = row.Player.Average.ToString("N0"); + row.Pos.Text = (row.NewRank + 1) + "."; + row.Highlight.Visible = row.NewRank == 0 && row.Player.NumSongs > 0; + + SColorF rankColor; + var color = _Texts[_TextRowName].Color; + if (row.Player.NumSongs > 0 && row.NewRank < _RankColors.Length && CBase.Themes.GetColor(_RankColors[row.NewRank], PartyModeId, out rankColor)) + { + color = rankColor; + } + + row.Pos.Color = color; + row.Name.Color = color; + } + } + + private void _PlaceRow(CRankRow row, float y) + { + row.Highlight.Y = y + (_Texts[_TextRowName].H - row.Highlight.H) / 2; + row.Avatar.Y = y + (_Texts[_TextRowName].H - row.Avatar.H) / 2; + row.Pos.Y = y; + row.Name.Y = y; + row.Songs.Y = y; + row.Average.Y = y; + } + + private void _UpdatePair() + { + var finished = _PartyMode.IsFinished; + var pair = _PartyMode.CurrentPair; + var showPair = !finished && pair != null; + + _Statics[_StaticPairAvatar2].Visible = showPair; + _Texts[_TextPairName1].Visible = showPair; + _Texts[_TextPairName2].Visible = showPair; + _Texts[_TextAmp].Visible = showPair; + _Texts[_TextTogether].Visible = showPair; + _Texts[_TextPass].Visible = showPair; + + var pause = _PartyMode.CurrentBreak; + _Texts[_TextPause].Visible = showPair && pause != null; + if (pause != null) + { + _Texts[_TextPause].Text = CBase.Language.Translate("TR_SCREENMAIN_PAUSE", PartyModeId) + " " + _GetName(pause); + } + + _Statics[_StaticPairAvatar1].MaxRect = _PairAvatar1Rect; + _Statics[_StaticPairAvatar1].Visible = showPair || finished; + + if (showPair) + { + _Statics[_StaticPairAvatar1].Texture = CBase.Profiles.GetAvatar(pair.Players[0].ProfileId); + _Statics[_StaticPairAvatar2].Texture = CBase.Profiles.GetAvatar(pair.Players[1].ProfileId); + _Texts[_TextPairName1].Text = _GetName(pair.Players[0]); + _Texts[_TextPairName2].Text = _GetName(pair.Players[1]); + + var together = _PartyMode.GetTimesTogether(pair.Players[0], pair.Players[1]); + _Texts[_TextTogether].Text = together == 0 + ? CBase.Language.Translate("TR_SCREENMAIN_FIRST_TIME", PartyModeId) + : CBase.Language.Translate("TR_SCREENMAIN_TIMES_TOGETHER", PartyModeId).Replace("%n", (together + 1).ToString()); + + _Texts[_TextPass].Text = CBase.Language.Translate("TR_SCREENMAIN_PASS", PartyModeId) + " " + (_PartyMode.GameData.PassIndex + 1) + " / " + + _PartyMode.GameData.Passes.Count + " · " + CBase.Language.Translate("TR_SCREENMAIN_SONG", PartyModeId) + " " + + (_PartyMode.GameData.PairIndex + 1) + " / " + _PartyMode.GameData.Passes[_PartyMode.GameData.PassIndex].Count; + } + + _Texts[_TextChampionLabel].Visible = finished; + _Texts[_TextChampion].Visible = finished; + _ParticleEffects[_ParticleEffectChampion].Visible = finished; + + if (finished) + { + var champion = _PartyMode.GetRanking()[0]; + _Texts[_TextChampion].Text = _GetName(champion); + _Statics[_StaticPairAvatar1].Texture = CBase.Profiles.GetAvatar(champion.ProfileId); + var centerX = (_PairAvatar1Rect.X + _Statics[_StaticPairAvatar2].Rect.X + _Statics[_StaticPairAvatar2].Rect.W) / 2; + _Statics[_StaticPairAvatar1].X = centerX - _PairAvatar1Rect.W / 2; + _Statics[_StaticPairAvatar1].Y = _PairAvatar1Rect.Y + 60f; + } + } + + private void _UpdateBestPair() + { + var best = _PartyMode.GameData.BestPair; + var visible = best != null; + _Statics[_StaticBestAvatar1].Visible = visible; + _Statics[_StaticBestAvatar2].Visible = visible; + _Texts[_TextBestNames].Visible = visible; + _Texts[_TextBestScore].Visible = visible; + _Texts[_TextBestLabel].Text = _PartyMode.IsFinished ? "TR_SCREENMAIN_BEST_PAIR_FINAL" : "TR_SCREENMAIN_BEST_PAIR"; + + if (!visible) + { + return; + } + + _Statics[_StaticBestAvatar1].Texture = CBase.Profiles.GetAvatar(best.Players[0].ProfileId); + _Statics[_StaticBestAvatar2].Texture = CBase.Profiles.GetAvatar(best.Players[1].ProfileId); + _Texts[_TextBestNames].Text = _GetPairNames(best); + _Texts[_TextBestScore].Text = best.PairScore.ToString("N0"); + } + + private void _UpdateLastResult() + { + var last = _PartyMode.GameData.LastPair; + _Texts[_TextLastResult].Visible = last != null && !_PartyMode.IsFinished; + _Texts[_TextHarmony].Visible = last != null && last.Bonus > 0 && !_PartyMode.IsFinished; + + if (last == null) + { + return; + } + + _Texts[_TextLastResult].Text = CBase.Language.Translate("TR_SCREENMAIN_LAST_SONG", PartyModeId) + " " + _GetPairNames(last) + " · " + + last.PairScore.ToString("N0"); + _Texts[_TextHarmony].Text = CBase.Language.Translate("TR_SCREENMAIN_HARMONY_BONUS", PartyModeId) + " +" + last.Bonus; + } + + private void _UpdateAnimations() + { + var time = _AnimTimer.ElapsedMilliseconds; + + var rankProgress = _ShowNewResult ? _EaseInOut(Math.Max(0f, Math.Min(1f, (time - _RankDelay) / _RankDuration))) : 1f; + foreach (var row in _Rows) + { + if (row.Player == null) + { + continue; + } + + var oldY = _FirstRowY + row.OldRank * _RowStep; + var newY = _FirstRowY + row.NewRank * _RowStep; + _PlaceRow(row, oldY + (newY - oldY) * rankProgress); + } + + var popScale = _ShowNewResult && time < _PopDuration ? 0.3f + 0.7f * _EaseOutBack(time / _PopDuration) : 1f; + _Texts[_TextLastResult].Font.Height = _LastResultHeight * popScale; + _Texts[_TextHarmony].Font.Height = _HarmonyHeight * popScale; + + if (_PartyMode.IsFinished) + { + float scale; + if (time < _PopDuration) + { + scale = 0.3f + 0.7f * _EaseOutBack(time / _PopDuration); + } + else + { + scale = 1f + 0.03f * (float)Math.Sin((time - _PopDuration) / 1000.0 * Math.PI * 1.4); + } + + _Texts[_TextChampion].Font.Height = _ChampionHeight * scale; + } + } + } +} diff --git a/PartyModes/PartyModePartnerSwap/CPartyScreenPartnerSwapNames.cs b/PartyModes/PartyModePartnerSwap/CPartyScreenPartnerSwapNames.cs new file mode 100644 index 00000000..f28695e4 --- /dev/null +++ b/PartyModes/PartyModePartnerSwap/CPartyScreenPartnerSwapNames.cs @@ -0,0 +1,74 @@ +#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.Menu; + +namespace VocaluxeLib.PartyModes.PartnerSwap +{ + public class CPartyScreenPartnerSwapNames : CMenuPartyNameSelection + { + protected override int _ScreenVersion + { + get { return 1; } + } + + private new CPartyModePartnerSwap _PartyMode; + + public override void Init() + { + base.Init(); + _PartyMode = (CPartyModePartnerSwap)base._PartyMode; + _AllowChangePlayerNum = false; + _Teams = false; + } + + public override void OnShow() + { + base.OnShow(); + SetPartyModeData(_PartyMode.GameData.NumPlayer); + while (_PartyMode.GameData.ProfileIds.Count > _NumPlayer) + { + _PartyMode.GameData.ProfileIds.RemoveAt(_PartyMode.GameData.ProfileIds.Count - 1); + } + + var ids = new List[] { _PartyMode.GameData.ProfileIds }; + SetPartyModeProfiles(ids); + } + + public override void Back() + { + if (_TeamList.Length == 1) + { + _PartyMode.GameData.ProfileIds = _TeamList[0]; + } + + _PartyMode.Back(); + } + + public override void Next() + { + if (_TeamList.Length == 1) + { + _PartyMode.GameData.ProfileIds = _TeamList[0]; + } + + _PartyMode.Next(); + } + } +} \ No newline at end of file diff --git a/PartyModes/PartyModePartnerSwap/CPartyScreenPartnerSwapSongs.cs b/PartyModes/PartyModePartnerSwap/CPartyScreenPartnerSwapSongs.cs new file mode 100644 index 00000000..0fa5df20 --- /dev/null +++ b/PartyModes/PartyModePartnerSwap/CPartyScreenPartnerSwapSongs.cs @@ -0,0 +1,66 @@ +using VocaluxeLib.Menu; + +namespace VocaluxeLib.PartyModes.PartnerSwap +{ + class CPartyScreenPartnerSwapSongs : CMenuPartySongSelection + { + protected override int _ScreenVersion + { + get { return 1; } + } + + private new CPartyModePartnerSwap _PartyMode; + + public override void Init() + { + base.Init(); + _PartyMode = (CPartyModePartnerSwap)base._PartyMode; + } + + public override void OnShow() + { + Source = _PartyMode.GameData.SongSource; + Sorting = _PartyMode.GameData.Sorting; + Category = _PartyMode.GameData.CategoryIndex; + Playlist = _PartyMode.GameData.PlaylistId; + SongMode = _PartyMode.GameData.GameMode; + NumMedleySongs = _PartyMode.GameData.NumMedleySongs; + + base.OnShow(); + } + + public override void Back() + { + _SaveConfig(); + _PartyMode.Back(); + } + + public override void Next() + { + _SaveConfig(); + _PartyMode.Next(); + } + + public override bool UpdateGame() + { + return true; + } + + protected override void _SetAllowedOptions() + { + base._SetAllowedOptions(); + + AllowedSongModes = new EGameMode[] { EGameMode.TR_GAMEMODE_NORMAL, EGameMode.TR_GAMEMODE_SHORTSONG, EGameMode.TR_GAMEMODE_MEDLEY }; + } + + private void _SaveConfig() + { + _PartyMode.GameData.SongSource = Source; + _PartyMode.GameData.Sorting = Sorting; + _PartyMode.GameData.CategoryIndex = Category; + _PartyMode.GameData.PlaylistId = Playlist; + _PartyMode.GameData.GameMode = SongMode; + _PartyMode.GameData.NumMedleySongs = NumMedleySongs; + } + } +} \ No newline at end of file diff --git a/PartyModes/PartyModePartnerSwap/GlobalSuppressions.cs b/PartyModes/PartyModePartnerSwap/GlobalSuppressions.cs new file mode 100644 index 00000000..e661ff03 Binary files /dev/null and b/PartyModes/PartyModePartnerSwap/GlobalSuppressions.cs differ diff --git a/PartyModes/PartyModePartnerSwap/PartyModePartnerSwap.csproj b/PartyModes/PartyModePartnerSwap/PartyModePartnerSwap.csproj new file mode 100644 index 00000000..f015ffb3 --- /dev/null +++ b/PartyModes/PartyModePartnerSwap/PartyModePartnerSwap.csproj @@ -0,0 +1,118 @@ + + + + DebugWin + AnyCPU + 8.0.30703 + 2.0 + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53} + Library + Properties + VocaluxeLib.PartyModes.PartnerSwap + PartnerSwap + v4.8.1 + + + 512 + + + AnyCPU + true + full + false + bin + TRACE;DEBUG;WIN + prompt + 4 + Off + ..\..\CheckingRules.ruleset + false + 9.0 + + + AnyCPU + pdbonly + true + bin + prompt + 4 + false + WIN + Off + false + true + 9.0 + + + AnyCPU + true + full + false + bin + TRACE;DEBUG;LINUX + prompt + 4 + Off + false + 9.0 + + + AnyCPU + pdbonly + true + bin + prompt + 4 + false + LINUX + Off + false + true + 9.0 + + + bin + WIN + true + AnyCPU + false + Off + prompt + ManagedMinimumRules.ruleset + false + pdbonly + true + 9.0 + + + + + + + + + + + + {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC} + VocaluxeLib + False + + + + + + + + + + if exist "$(SolutionDir)Output\PartyModes\$(TargetName)\Code" rd "$(SolutionDir)Output\PartyModes\$(TargetName)\Code" /S /Q +cd $(SolutionDir)Partymodes\ +xcopy "$(ProjectDir)*.cs" "$(SolutionDir)Output\PartyModes\$(TargetName)\Code\" /EXCLUDE:Excludes.txt /I /Y + rm -rf "$(SolutionDir)Output\PartyModes\$(TargetName)\Code" +mkdir -p "$(SolutionDir)Output\PartyModes\$(TargetName)\Code\" +cp -R $(ProjectDir)*.cs "$(SolutionDir)Output\PartyModes\$(TargetName)\Code\" +rm -f "$(SolutionDir)Output\PartyModes\$(TargetName)\Code\GlobalSuppressions.cs" + + + \ No newline at end of file diff --git a/PartyModes/PartyModePartnerSwap/Settings.StyleCop b/PartyModes/PartyModePartnerSwap/Settings.StyleCop new file mode 100644 index 00000000..f4a4ea2a --- /dev/null +++ b/PartyModes/PartyModePartnerSwap/Settings.StyleCop @@ -0,0 +1,809 @@ + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + \ No newline at end of file diff --git a/Vocaluxe.sln b/Vocaluxe.sln index 2681e92a..ad929fc1 100644 --- a/Vocaluxe.sln +++ b/Vocaluxe.sln @@ -7,6 +7,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vocaluxe", "Vocaluxe\Vocalu {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41} = {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41} {55F89808-4E79-4FFE-BC13-48258913F5C9} = {55F89808-4E79-4FFE-BC13-48258913F5C9} {6F3E1874-F28A-40E9-AFBD-31934D593679} = {6F3E1874-F28A-40E9-AFBD-31934D593679} + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53} = {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53} {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC} = {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC} {5A4053F1-5AD5-441F-B254-D97A088127B6} = {5A4053F1-5AD5-441F-B254-D97A088127B6} {54A48AF7-515C-4EDD-B395-2BFFA096050A} = {54A48AF7-515C-4EDD-B395-2BFFA096050A} @@ -14,6 +15,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vocaluxe", "Vocaluxe\Vocalu EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VocaluxeLib", "VocaluxeLib\VocaluxeLib.csproj", "{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PartyModePartnerSwap", "PartyModes\PartyModePartnerSwap\PartyModePartnerSwap.csproj", "{9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PartyModeTicTacToe", "PartyModes\PartyModeTicTacToe\PartyModeTicTacToe.csproj", "{6F3E1874-F28A-40E9-AFBD-31934D593679}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PartyModeChallenge", "PartyModes\PartyModeChallenge\PartyModeChallenge.csproj", "{5A4053F1-5AD5-441F-B254-D97A088127B6}" @@ -80,6 +83,26 @@ Global {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.ReleaseWin|x64.Build.0 = ReleaseWin|Any CPU {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.ReleaseWin|x86.ActiveCfg = ReleaseWin|Any CPU {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.ReleaseWin|x86.Build.0 = ReleaseWin|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.DebugLinux|x64.ActiveCfg = DebugLinux|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.DebugLinux|x64.Build.0 = DebugLinux|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.DebugLinux|x86.ActiveCfg = DebugLinux|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.DebugLinux|x86.Build.0 = DebugLinux|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.DebugWin|x64.ActiveCfg = DebugWin|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.DebugWin|x64.Build.0 = DebugWin|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.DebugWin|x86.ActiveCfg = DebugWin|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.DebugWin|x86.Build.0 = DebugWin|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.InstallerWin|x64.ActiveCfg = InstallerWin|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.InstallerWin|x64.Build.0 = InstallerWin|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.InstallerWin|x86.ActiveCfg = InstallerWin|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.InstallerWin|x86.Build.0 = InstallerWin|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.ReleaseLinux|x64.ActiveCfg = ReleaseLinux|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.ReleaseLinux|x64.Build.0 = ReleaseLinux|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.ReleaseLinux|x86.ActiveCfg = ReleaseLinux|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.ReleaseLinux|x86.Build.0 = ReleaseLinux|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.ReleaseWin|x64.ActiveCfg = ReleaseWin|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.ReleaseWin|x64.Build.0 = ReleaseWin|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.ReleaseWin|x86.ActiveCfg = ReleaseWin|Any CPU + {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53}.ReleaseWin|x86.Build.0 = ReleaseWin|Any CPU {6F3E1874-F28A-40E9-AFBD-31934D593679}.DebugLinux|x64.ActiveCfg = DebugLinux|Any CPU {6F3E1874-F28A-40E9-AFBD-31934D593679}.DebugLinux|x64.Build.0 = DebugLinux|Any CPU {6F3E1874-F28A-40E9-AFBD-31934D593679}.DebugLinux|x86.ActiveCfg = DebugLinux|Any CPU