diff --git a/Output/PartyModes/TeamSurvival.xml b/Output/PartyModes/TeamSurvival.xml new file mode 100644 index 00000000..28b3dce4 --- /dev/null +++ b/Output/PartyModes/TeamSurvival.xml @@ -0,0 +1,21 @@ + + + 2 + + TR_PARTYMODE_NAME + McSchneidar + TR_PARTYMODE_DESCRIPTION + TeamSurvival + CPartyModeTeamSurvival + 1 + 0 + TR_PARTYMODE_AUDIENCE + + + CPartyScreenTeamSurvivalMain + CPartyScreenTeamSurvivalConfig + CPartyScreenTeamSurvivalNames + CPartyScreenTeamSurvivalSongs + CPartyScreenTeamSurvivalHearts + + diff --git a/Output/PartyModes/TeamSurvival/Languages/de.xml b/Output/PartyModes/TeamSurvival/Languages/de.xml new file mode 100644 index 00000000..04ffdf6a --- /dev/null +++ b/Output/PartyModes/TeamSurvival/Languages/de.xml @@ -0,0 +1,36 @@ + + + Deutsch + Team Survival + Zwei Teams singen Duelle, der Verlierer verliert ein Herz, das letzte Team gewinnt. + Für zwei Teams mit bis zu 8 Spielern, 2 Mikrofone nötig. + Weiter + Zurück + Beenden + Ja + Nein + Duell starten + Songs + Team + Team Survival: Konfiguration + Herzen + Für alle gleich + Pro Spieler festlegen + Herzen pro Spieler + Joker pro Spieler + Team Survival: Teams zusammenstellen + Ausgewählte Spieler für dieses Team: + Team 1 + Team 2 + Zufällig wählen + Füge beiden Teams mindestens einen Spieler hinzu! / Ziehe Avatare in die Liste der ausgewählten Spieler! / Rechtsklick auf einen ausgewählten Avatar entfernt ihn! + Team Survival: Herzen pro Spieler + Hoch/Runter = Spieler wählen · Links/Rechts oder Herz anklicken = Herzen ändern · Enter = Weiter · ESC = Zurück + Team Survival + Willst du das Spiel wirklich beenden? + Durchgang + Duell + gegen + Gleichstand! Das Duell wird nachgesungen. + Siegerteam + diff --git a/Output/PartyModes/TeamSurvival/Languages/en.xml b/Output/PartyModes/TeamSurvival/Languages/en.xml new file mode 100644 index 00000000..d5592adc --- /dev/null +++ b/Output/PartyModes/TeamSurvival/Languages/en.xml @@ -0,0 +1,36 @@ + + + English + Team Survival + Two teams sing duels, the loser loses a heart, the last team standing wins. + For two teams with up to 8 players each, 2 microphones needed. + Next + Back + Exit + Yes + No + Start duel + Songs + Team + Team Survival: Configuration + Hearts + Same for everyone + Set per player + Hearts per player + Jokers per player + Team Survival: Choose Teams + Selected players for this team: + Team 1 + Team 2 + Select random + Add at least one player to both teams! / Drag player avatars to add them to the selected players list! / Right click avatar of selected players to remove them! + Team Survival: Hearts per Player + Up/Down = Select player · Left/Right or click a heart = Change hearts · Enter = Next · ESC = Back + Team Survival + Do you really want to exit the game? + Round + Duel + vs. + Tie! The duel is sung again. + Winning team + diff --git a/Output/PartyModes/TeamSurvival/Themes/Default.xml b/Output/PartyModes/TeamSurvival/Themes/Default.xml new file mode 100644 index 00000000..97392ded --- /dev/null +++ b/Output/PartyModes/TeamSurvival/Themes/Default.xml @@ -0,0 +1,10 @@ + + + 9 + + Default + McSchneidar + 0 + 1 + + diff --git a/Output/PartyModes/TeamSurvival/Themes/Default/Default.xml b/Output/PartyModes/TeamSurvival/Themes/Default/Default.xml new file mode 100644 index 00000000..5d5694e3 --- /dev/null +++ b/Output/PartyModes/TeamSurvival/Themes/Default/Default.xml @@ -0,0 +1,16 @@ + + + 4 + + Default + McSchneidar + 0 + 1 + + + + Heart.png + PartyModeIcon.png + + + diff --git a/Output/PartyModes/TeamSurvival/Themes/Default/Heart.png b/Output/PartyModes/TeamSurvival/Themes/Default/Heart.png new file mode 100644 index 00000000..76af991a Binary files /dev/null and b/Output/PartyModes/TeamSurvival/Themes/Default/Heart.png differ diff --git a/Output/PartyModes/TeamSurvival/Themes/Default/PartyModeIcon.png b/Output/PartyModes/TeamSurvival/Themes/Default/PartyModeIcon.png new file mode 100644 index 00000000..3f421a17 Binary files /dev/null and b/Output/PartyModes/TeamSurvival/Themes/Default/PartyModeIcon.png differ diff --git a/Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalConfig.xml b/Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalConfig.xml new file mode 100644 index 00000000..987a31b1 --- /dev/null +++ b/Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalConfig.xml @@ -0,0 +1,295 @@ + + + + PartyScreenTeamSurvivalConfig + 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_HEARTSMODE + + + 112.5 + 247.5 + 0 + 40.5 + 0 + + + Left + Center + + Outline + TR_SCREENCONFIG_NUMHEARTS + + + 112.5 + 337.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 + + + + + + + + + diff --git a/Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalHearts.xml b/Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalHearts.xml new file mode 100644 index 00000000..d55d58e5 --- /dev/null +++ b/Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalHearts.xml @@ -0,0 +1,262 @@ + + + + PartyScreenTeamSurvivalHearts + 1 + + + + Video + + + BG_Default + + + + + + + + + 0 + 60 + 1920 + 67.5 + 1 + + + + + + 0.1 + 0.09 + 0.25 + 0.75 + + + 140 + 200 + 800 + 640 + 0.8 + + + + + + 0.1 + 0.09 + 0.25 + 0.75 + + + 1000 + 200 + 800 + 640 + 0.8 + + + + + + 1 + 0.8 + 0 + 0.18 + + + 0 + 0 + 760 + 62 + 0.6 + + + + + + + 0 + 0 + 54 + 54 + 0.4 + + + + Heart + + 1 + 0.3 + 0.4 + 1 + + + 0 + 0 + 46 + 46 + 0.3 + + + + + + 960 + 75 + 0 + 40.5 + 0 + + + Center + Center + + Outline + TR_SCREENHEARTS_TITLE + + + 540 + 210 + 0 + 40 + 0 + + + Center + Center + + Outline + TR_SCREENNAMES_TEAM1 + + + 1400 + 210 + 0 + 40 + 0 + + + Center + Center + + Outline + TR_SCREENNAMES_TEAM2 + + + 0 + 0 + 0 + 34 + 330 + + + Left + Center + + Outline + + + + 960 + 860 + 0 + 30 + 1600 + + 0.75 + 0.78 + 0.85 + 1 + + + Center + Center + + Outline + TR_SCREENHEARTS_HINT + + + + + + + + + + + + + + + + diff --git a/Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalMain.xml b/Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalMain.xml new file mode 100644 index 00000000..95668a5c --- /dev/null +++ b/Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalMain.xml @@ -0,0 +1,586 @@ + + + + PartyScreenTeamSurvivalMain + 1 + + + + Video + + + BG_Default + + + + + + + + + 0 + 60 + 1920 + 67.5 + 1 + + + + PopupBG + + + 0 + 0 + 1920 + 1080 + -1 + + + + + + 0.1 + 0.09 + 0.25 + 0.75 + + + 40 + 190 + 560 + 720 + 0.8 + + + + + + 0.1 + 0.09 + 0.25 + 0.75 + + + 1320 + 190 + 560 + 720 + 0.8 + + + + + + 0.1 + 0.09 + 0.25 + 0.9 + + + 0 + 0 + 520 + 68 + 0.5 + + + + + + 1 + 0.8 + 0 + 1 + + + 0 + 0 + 528 + 76 + 0.6 + + + + + + + 0 + 0 + 56 + 56 + 0.4 + + + + Heart + + 1 + 0.3 + 0.4 + 1 + + + 0 + 0 + 32 + 32 + 0.3 + + + + + + 1 + 1 + 1 + 1 + + + 652 + 292 + 216 + 216 + 0.5 + + + + + + + 660 + 300 + 200 + 200 + 0.4 + + + + + + 1 + 1 + 1 + 1 + + + 1052 + 292 + 216 + 216 + 0.5 + + + + + + + 1060 + 300 + 200 + 200 + 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 + + + 320 + 205 + 0 + 44 + 0 + + + Center + Center + + Outline + + + + 1600 + 205 + 0 + 44 + 0 + + + Center + Center + + Outline + + + + 960 + 150 + 0 + 34 + 0 + + 0.75 + 0.78 + 0.85 + 1 + + + Center + Center + + Outline + + + + 0 + 0 + 0 + 32 + 0 + + + Left + Center + + Outline + + + + 760 + 520 + 0 + 40 + 260 + + + Center + Center + + Outline + + + + 1160 + 520 + 0 + 40 + 260 + + + Center + Center + + Outline + + + + 960 + 375 + 0 + 44 + 0 + + 1 + 0.8 + 0 + 1 + + + Center + Center + + Outline + TR_SCREENMAIN_VERSUS + + + 960 + 600 + 0 + 34 + 600 + + 1 + 0.8 + 0 + 1 + + + Center + Center + + Outline + TR_SCREENMAIN_REMATCH + + + 960 + 300 + 0 + 36 + 0 + + 1 + 0.8 + 0 + 1 + + + Center + Center + + Outline + TR_SCREENMAIN_CHAMPION + + + 960 + 350 + 0 + 70 + 600 + + 1 + 0.8 + 0 + 1 + + + Center + Center + + Outline + + + + + + + + + + + + + + + + + + + + Star + + 660 + 280 + 600 + 340 + -1 + + + 1 + 0.8 + 0 + 1 + + Star + 18 + 40 + + + + diff --git a/Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalNames.xml b/Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalNames.xml new file mode 100644 index 00000000..79390c4e --- /dev/null +++ b/Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalNames.xml @@ -0,0 +1,410 @@ + + + + PartyScreenTeamSurvivalNames + 1 + + + + Video + + + BG_Default + + + + + + + + + 0 + 60 + 1920 + 67.5 + 1 + + + + + + 960 + 75 + 0 + 40.5 + 0 + + + Center + Center + + Outline + TR_SCREENNAMES_TITLE + + + 960 + 232.5 + 0 + 30 + 0 + + + Center + Center + + Outline + TR_SCREENNAMES_SELPLAYERSTITLE + + + 960 + 1054.5 + 0 + 24 + 1800 + + + Center + Center + + Outline + TR_SCREENNAMES_HELPMESSAGE + + + + + + + + + + + + + + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlide + SelectSlideArrowLeft + SelectSlideArrowRight + + 60 + 150 + 1582.5 + 75 + 0 + + + 67.5 + 157.5 + 60 + 60 + 0 + + + 1575 + 157.5 + 60 + 60 + 0 + + + + + + + + 40.5 + 75 + 0 + 300 + Outline + Bold + 2 + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlidePlayer + SelectSlideArrowLeft + SelectSlideArrowRight + + 60 + 270 + 1582.5 + 225 + 0 + + + 67.5 + 345 + 60 + 60 + 0 + + + 1575 + 345 + 60 + 60 + 0 + + + + + + + + 40.5 + 75 + 7.5 + 300 + Outline + Bold + 8 + + + + + + + 142.5 + 525 + 1800 + 589.5 + 0 + + CoverTile + + PlayerSelector + + 150 + 150 + 10 + 2 + 15 + 15 + + -30 + 25.5 + Outline + + + + + + + + + + + diff --git a/Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalSongs.xml b/Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalSongs.xml new file mode 100644 index 00000000..27b45756 --- /dev/null +++ b/Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalSongs.xml @@ -0,0 +1,407 @@ + + + + PartyScreenTeamSurvivalSongs + 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/PartyModeTeamSurvival/CPartyModeTeamSurvival.cs b/PartyModes/PartyModeTeamSurvival/CPartyModeTeamSurvival.cs new file mode 100644 index 00000000..177b3aa8 --- /dev/null +++ b/PartyModes/PartyModeTeamSurvival/CPartyModeTeamSurvival.cs @@ -0,0 +1,769 @@ +#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.TeamSurvival +{ + public class CSurvivalPlayer + { + public Guid ProfileId; + public int Team; + public int StartHearts; + public int Hearts; + public int Jokers; + public int DuelsInPass; + + public bool IsOut + { + get { return Hearts <= 0; } + } + } + + public class CSurvivalDuel + { + public CSurvivalPlayer[] Players = new CSurvivalPlayer[2]; + public int[] Scores = new int[2]; + public int Loser = -1; + } + + public abstract class CPartyScreenTeamSurvival : CMenuParty + { + protected new CPartyModeTeamSurvival _PartyMode; + + public override void Init() + { + base.Init(); + _PartyMode = (CPartyModeTeamSurvival)base._PartyMode; + } + } + + public sealed class CPartyModeTeamSurvival : CPartyMode + { + public const int TeamCount = 2; + public const int MaxHearts = 5; + public const int MaxJokers = 3; + public const int MaxPlayersInTeam = 8; + + public override int MinMics + { + get { return TeamCount; } + } + public override int MaxMics + { + get { return CBase.Config.GetMaxNumMics(); } + } + public override int MinPlayers + { + get { return TeamCount; } + } + public override int MaxPlayers + { + get { return TeamCount * MaxPlayersInTeam; } + } + public override int MinTeams + { + get { return TeamCount; } + } + public override int MaxTeams + { + get { return TeamCount; } + } + public override int MinPlayersPerTeam + { + get { return 1; } + } + public override int MaxPlayersPerTeam + { + get { return MaxPlayersInTeam; } + } + + private enum EStage + { + Config, + Songs, + Names, + Hearts, + Main, + SongSelection, + Singing, + MedleySinging + } + + public struct SData + { + public bool HeartsPerPlayer; + public int NumHearts; + public int NumJokers; + public Dictionary PlayerHearts; + + public int NumPlayerTeam1; + public int NumPlayerTeam2; + public List ProfileIdsTeam1; + public List ProfileIdsTeam2; + + public ESongSource SongSource; + public ESongSorting Sorting; + public int CategoryIndex; + public int PlaylistId; + + public EGameMode GameMode; + public int NumMedleySongs; + + public List Players; + public List PassDuels; + public int PassNr; + public int DuelIndex; + public int NumDuelsPlayed; + public bool IsRematch; + public CSurvivalDuel LastDecidedDuel; + public int WinnerTeam; + + public List Songs; + } + + public SData GameData; + private EStage _Stage; + + public CPartyModeTeamSurvival(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.NoDuets; + _ScreenSongOptions.Sorting.FilterPlaylistId = -1; + + GameData = new SData + { + HeartsPerPlayer = false, + NumHearts = 2, + NumJokers = 1, + PlayerHearts = new Dictionary(), + NumPlayerTeam1 = 2, + NumPlayerTeam2 = 2, + ProfileIdsTeam1 = new List(), + ProfileIdsTeam2 = 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(), + PassDuels = new List(), + WinnerTeam = -1, + 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 bool IsFinished + { + get { return GameData.WinnerTeam >= 0; } + } + + public CSurvivalDuel CurrentDuel + { + get + { + if (IsFinished || GameData.DuelIndex >= GameData.PassDuels.Count) + { + return null; + } + + return GameData.PassDuels[GameData.DuelIndex]; + } + } + + public List GetTeam(int team) + { + return GameData.Players.Where(player => player.Team == team).ToList(); + } + + public int GetStartHearts(Guid profileId) + { + int hearts; + if (GameData.HeartsPerPlayer && GameData.PlayerHearts.TryGetValue(profileId, out hearts)) + { + return hearts; + } + + return GameData.NumHearts; + } + + private IMenu _GetNextScreen() + { + switch (_Stage) + { + case EStage.Config: + return _Screens["CPartyScreenTeamSurvivalConfig"]; + case EStage.Songs: + return _Screens["CPartyScreenTeamSurvivalSongs"]; + case EStage.Names: + return _Screens["CPartyScreenTeamSurvivalNames"]; + case EStage.Hearts: + return _Screens["CPartyScreenTeamSurvivalHearts"]; + case EStage.Main: + return _Screens["CPartyScreenTeamSurvivalMain"]; + 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: + if (GameData.HeartsPerPlayer) + { + _Stage = EStage.Hearts; + } + else + { + _StartGame(); + } + + break; + case EStage.Hearts: + _StartGame(); + break; + case EStage.Main: + if (CurrentDuel == 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.Hearts: + _Stage = EStage.Names; + break; + case EStage.Main: + _Stage = GameData.HeartsPerPlayer ? EStage.Hearts : EStage.Names; + break; + default: + throw new ArgumentException("Invalid stage: " + _Stage); + } + + _FadeToScreen(); + } + + public override IMenu GetStartScreen() + { + return _Screens["CPartyScreenTeamSurvivalConfig"]; + } + + 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 duel = CurrentDuel; + if (duel != null && duel.Players[teamNr].Jokers > 0) + { + duel.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() + { + _Stage = EStage.Main; + CBase.Songs.ResetSongSung(); + + GameData.Players = new List(); + var teams = new List[] { GameData.ProfileIdsTeam1, GameData.ProfileIdsTeam2 }; + for (var team = 0; team < TeamCount; team++) + { + foreach (var profileId in teams[team]) + { + var hearts = GetStartHearts(profileId); + GameData.Players.Add(new CSurvivalPlayer { ProfileId = profileId, Team = team, StartHearts = hearts, Hearts = hearts, Jokers = GameData.NumJokers }); + } + } + + GameData.PassNr = 0; + GameData.NumDuelsPlayed = 0; + GameData.IsRematch = false; + GameData.LastDecidedDuel = null; + GameData.WinnerTeam = -1; + GameData.Songs = new List(); + _StartPass(); + } + + private void _StartPass() + { + GameData.PassNr++; + GameData.DuelIndex = 0; + GameData.PassDuels = new List(); + + var teams = new List[TeamCount]; + var numDuels = 0; + for (var team = 0; team < TeamCount; team++) + { + teams[team] = GetTeam(team).Where(player => !player.IsOut).ToList(); + teams[team].Shuffle(); + foreach (var player in teams[team]) + { + player.DuelsInPass = 0; + } + + numDuels = Math.Max(numDuels, teams[team].Count); + } + + for (var i = 0; i < numDuels; i++) + { + GameData.PassDuels.Add(new CSurvivalDuel()); + } + + for (var team = 0; team < TeamCount; team++) + { + var order = new List(teams[team]); + while (order.Count < numDuels) + { + var extra = new List(teams[team]); + extra.Shuffle(); + order.AddRange(extra); + } + + for (var i = 1; i < numDuels; i++) + { + if (order[i] != order[i - 1] || teams[team].Count < 2) + { + continue; + } + + for (var j = i + 1; j < order.Count; j++) + { + if (order[j] != order[i - 1] && (i + 1 >= numDuels || order[j] != order[i + 1])) + { + var swap = order[i]; + order[i] = order[j]; + order[j] = swap; + break; + } + } + } + + for (var i = 0; i < numDuels; i++) + { + GameData.PassDuels[i].Players[team] = order[i]; + } + } + } + + private CSurvivalPlayer _GetReplacement(int team) + { + var candidates = GetTeam(team).Where(player => !player.IsOut).ToList(); + if (candidates.Count == 0) + { + return null; + } + + var minDuels = candidates.Min(player => player.DuelsInPass); + candidates = candidates.Where(player => player.DuelsInPass == minDuels).ToList(); + return candidates[CBase.Game.GetRandom(candidates.Count)]; + } + + private void _ValidateCurrentDuel() + { + var duel = CurrentDuel; + if (duel == null) + { + return; + } + + for (var team = 0; team < TeamCount; team++) + { + if (duel.Players[team] == null || duel.Players[team].IsOut) + { + duel.Players[team] = _GetReplacement(team); + } + } + } + + 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(); + + 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 duel = CurrentDuel; + _ScreenSongOptions.Selection.NumJokers = new int[] { duel.Players[0].Jokers, duel.Players[1].Jokers }; + _ScreenSongOptions.Selection.TeamNames = new string[] + { + CBase.Profiles.GetPlayerName(duel.Players[0].ProfileId), + CBase.Profiles.GetPlayerName(duel.Players[1].ProfileId) + }; + } + + private bool _PrepareRound(int[] songIds) + { + CBase.Game.Reset(); + CBase.Game.ClearSongs(); + + CBase.Game.SetNumPlayer(TeamCount); + var players = CBase.Game.GetPlayers(); + var duel = CurrentDuel; + if (players == null || players.Length < TeamCount || duel == null) + { + return false; + } + + for (var team = 0; team < TeamCount; team++) + { + players[team].ProfileId = duel.Players[team].ProfileId; + } + + foreach (var songId in songIds) + { + var gameMode = GameData.GameMode; + if (GameData.IsRematch && gameMode != EGameMode.TR_GAMEMODE_MEDLEY && CBase.Songs.GetSongById(songId).IsGameModeAvailable(EGameMode.TR_GAMEMODE_SHORTSONG)) + { + gameMode = EGameMode.TR_GAMEMODE_SHORTSONG; + } + + 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; + if (CBase.Songs.GetSongById(id).IsGameModeAvailable(EGameMode.TR_GAMEMODE_MEDLEY)) + { + 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)).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)).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 duel = CurrentDuel; + if (duel == null) + { + return; + } + + var points = CBase.Game.GetPoints(); + if (points == null || points.NumRounds == 0) + { + return; + } + + var scores = new double[TeamCount]; + for (var round = 0; round < points.NumRounds; round++) + { + var res = points.GetPlayer(round, TeamCount); + if (res == null || res.Length < TeamCount) + { + return; + } + + for (var p = 0; p < TeamCount; p++) + { + scores[p] += res[p].Points; + } + } + + for (var p = 0; p < TeamCount; p++) + { + duel.Scores[p] = (int)Math.Round(scores[p] / points.NumRounds); + } + + GameData.NumDuelsPlayed++; + + if (duel.Scores[0] == duel.Scores[1]) + { + GameData.IsRematch = true; + return; + } + + GameData.IsRematch = false; + duel.Loser = duel.Scores[0] < duel.Scores[1] ? 0 : 1; + duel.Players[duel.Loser].Hearts--; + foreach (var player in duel.Players) + { + player.DuelsInPass++; + } + + GameData.LastDecidedDuel = duel; + + for (var team = 0; team < TeamCount; team++) + { + if (GetTeam(team).All(player => player.IsOut)) + { + GameData.WinnerTeam = 1 - team; + return; + } + } + + GameData.DuelIndex++; + if (GameData.DuelIndex >= GameData.PassDuels.Count) + { + _StartPass(); + } + + _ValidateCurrentDuel(); + } + } +} diff --git a/PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalConfig.cs b/PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalConfig.cs new file mode 100644 index 00000000..01a9ffc7 --- /dev/null +++ b/PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalConfig.cs @@ -0,0 +1,145 @@ +#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.Windows.Forms; + +namespace VocaluxeLib.PartyModes.TeamSurvival +{ + public class CPartyScreenTeamSurvivalConfig : CPartyScreenTeamSurvival + { + protected override int _ScreenVersion + { + get { return 1; } + } + + private const string _SelectSlideHeartsMode = "SelectSlideHeartsMode"; + private const string _SelectSlideNumHearts = "SelectSlideNumHearts"; + private const string _SelectSlideNumJokers = "SelectSlideNumJokers"; + private const string _ButtonNext = "ButtonNext"; + private const string _ButtonBack = "ButtonBack"; + + public override void Init() + { + base.Init(); + + _ThemeSelectSlides = new string[] { _SelectSlideHeartsMode, _SelectSlideNumHearts, _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[_SelectSlideHeartsMode].Clear(); + _SelectSlides[_SelectSlideHeartsMode].AddValue(CBase.Language.Translate("TR_SCREENCONFIG_HEARTS_EQUAL", PartyModeId)); + _SelectSlides[_SelectSlideHeartsMode].AddValue(CBase.Language.Translate("TR_SCREENCONFIG_HEARTS_PERPLAYER", PartyModeId)); + _SelectSlides[_SelectSlideHeartsMode].Selection = _PartyMode.GameData.HeartsPerPlayer ? 1 : 0; + + _SelectSlides[_SelectSlideNumHearts].Clear(); + for (var i = 1; i <= CPartyModeTeamSurvival.MaxHearts; i++) + { + _SelectSlides[_SelectSlideNumHearts].AddValue(i.ToString()); + } + + _SelectSlides[_SelectSlideNumHearts].SelectedValue = _PartyMode.GameData.NumHearts.ToString(); + + _SelectSlides[_SelectSlideNumJokers].Clear(); + for (var i = 0; i <= CPartyModeTeamSurvival.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.HeartsPerPlayer = _SelectSlides[_SelectSlideHeartsMode].Selection == 1; + _PartyMode.GameData.NumHearts = _SelectSlides[_SelectSlideNumHearts].Selection + 1; + _PartyMode.GameData.NumJokers = _SelectSlides[_SelectSlideNumJokers].Selection; + } + } +} diff --git a/PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalHearts.cs b/PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalHearts.cs new file mode 100644 index 00000000..a00a0bfa --- /dev/null +++ b/PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalHearts.cs @@ -0,0 +1,374 @@ +#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.Windows.Forms; +using VocaluxeLib.Menu; + +namespace VocaluxeLib.PartyModes.TeamSurvival +{ + class CHeartsRow + { + public Guid ProfileId; + public CStatic Highlight; + public CStatic Avatar; + public CText Name; + public CStatic[] Hearts; + } + + public class CPartyScreenTeamSurvivalHearts : CPartyScreenTeamSurvival + { + protected override int _ScreenVersion + { + get { return 1; } + } + + private const string _ButtonNext = "ButtonNext"; + private const string _ButtonBack = "ButtonBack"; + + private const string _StaticRowHighlight = "StaticRowHighlight"; + private const string _StaticRowAvatar = "StaticRowAvatar"; + private const string _StaticHeart = "StaticHeart"; + private const string _TextRowName = "TextRowName"; + + private const float _FirstRowY = 260f; + private const float _RowH = 70f; + private const float _HeartSize = 46f; + private const float _HeartSpace = 10f; + private const float _LostHeartAlpha = 0.2f; + + private readonly float[] _ColumnX = new float[] { 160f, 1020f }; + + private List _Rows; + private int _NumRowsUsed; + private int _SelectedRow; + private bool _OnButtons; + + public override void Init() + { + base.Init(); + + _ThemeButtons = new string[] { _ButtonNext, _ButtonBack }; + _ThemeStatics = new string[] { _StaticRowHighlight, _StaticRowAvatar, _StaticHeart }; + _ThemeTexts = new string[] { _TextRowName }; + } + + public override void LoadTheme(string xmlPath) + { + base.LoadTheme(xmlPath); + + _Rows = new List(); + for (var i = 0; i < CPartyModeTeamSurvival.TeamCount * CPartyModeTeamSurvival.MaxPlayersInTeam; i++) + { + var row = new CHeartsRow + { + Highlight = GetNewStatic(_Statics[_StaticRowHighlight]), + Avatar = GetNewStatic(_Statics[_StaticRowAvatar]), + Name = GetNewText(_Texts[_TextRowName]), + Hearts = new CStatic[CPartyModeTeamSurvival.MaxHearts] + }; + row.Avatar.Aspect = EAspect.Crop; + _AddStatic(row.Highlight); + _AddStatic(row.Avatar); + _AddText(row.Name); + for (var h = 0; h < CPartyModeTeamSurvival.MaxHearts; h++) + { + row.Hearts[h] = GetNewStatic(_Statics[_StaticHeart]); + _AddStatic(row.Hearts[h]); + } + + _Rows.Add(row); + } + + _Statics[_StaticRowHighlight].Visible = false; + _Statics[_StaticRowAvatar].Visible = false; + _Statics[_StaticHeart].Visible = false; + _Texts[_TextRowName].Visible = false; + } + + public override void OnShow() + { + base.OnShow(); + + _NumRowsUsed = 0; + var teams = new List[] { _PartyMode.GameData.ProfileIdsTeam1, _PartyMode.GameData.ProfileIdsTeam2 }; + for (var team = 0; team < teams.Length; team++) + { + for (var i = 0; i < teams[team].Count && i < CPartyModeTeamSurvival.MaxPlayersInTeam; i++) + { + var row = _Rows[_NumRowsUsed++]; + row.ProfileId = teams[team][i]; + _PlaceRow(row, _ColumnX[team], _FirstRowY + i * _RowH); + row.Avatar.Texture = CBase.Profiles.GetAvatar(row.ProfileId); + row.Name.Text = CBase.Profiles.GetPlayerName(row.ProfileId); + } + } + + for (var i = 0; i < _Rows.Count; i++) + { + var visible = i < _NumRowsUsed; + _Rows[i].Avatar.Visible = visible; + _Rows[i].Name.Visible = visible; + foreach (var heart in _Rows[i].Hearts) + { + heart.Visible = visible; + } + } + + _SelectedRow = 0; + _UpdateRows(); + _FocusRows(); + } + + public override bool UpdateGame() + { + return true; + } + + public override bool HandleInput(SKeyEvent keyEvent) + { + if (keyEvent.KeyPressed) + { + return true; + } + + switch (keyEvent.Key) + { + case Keys.Back: + case Keys.Escape: + _PartyMode.Back(); + break; + + case Keys.Enter: + if (_OnButtons && _Buttons[_ButtonBack].Selected) + { + _PartyMode.Back(); + } + else + { + _PartyMode.Next(); + } + + break; + + case Keys.Up: + if (_OnButtons) + { + _FocusRows(); + } + else + { + _SelectRow(_SelectedRow - 1); + } + + break; + + case Keys.Down: + if (_OnButtons) + { + break; + } + + if (_SelectedRow + 1 < _NumRowsUsed) + { + _SelectRow(_SelectedRow + 1); + } + else + { + _FocusButtons(); + } + + break; + + case Keys.Left: + case Keys.Right: + if (_OnButtons) + { + _SwitchButton(); + } + else + { + _ChangeHearts(_SelectedRow, _GetHearts(_SelectedRow) + (keyEvent.Key == Keys.Left ? -1 : 1)); + } + + break; + + case Keys.Tab: + if (_OnButtons) + { + _SwitchButton(); + } + else + { + _FocusButtons(); + } + + break; + } + + return true; + } + + public override bool HandleMouse(SMouseEvent mouseEvent) + { + base.HandleMouse(mouseEvent); + if (_Buttons[_ButtonBack].Selected || _Buttons[_ButtonNext].Selected) + { + _OnButtons = true; + } + + if (mouseEvent.LB) + { + for (var r = 0; r < _NumRowsUsed; r++) + { + for (var h = 0; h < CPartyModeTeamSurvival.MaxHearts; h++) + { + if (CHelper.IsInBounds(_Rows[r].Hearts[h].Rect, mouseEvent)) + { + _SelectRow(r); + _ChangeHearts(r, h + 1); + return true; + } + } + + if (CHelper.IsInBounds(_Rows[r].Highlight.Rect, mouseEvent)) + { + _SelectRow(r); + return true; + } + } + + if (_IsMouseOverCurSelection(mouseEvent)) + { + if (_Buttons[_ButtonBack].Selected) + { + _PartyMode.Back(); + } + + if (_Buttons[_ButtonNext].Selected) + { + _PartyMode.Next(); + } + } + } + + if (mouseEvent.RB) + { + _PartyMode.Back(); + } + + return true; + } + + private void _PlaceRow(CHeartsRow row, float x, float y) + { + var highlight = _Statics[_StaticRowHighlight].Rect; + row.Highlight.MaxRect = new SRectF(x, y, highlight.W, highlight.H, highlight.Z); + + var avatar = _Statics[_StaticRowAvatar].Rect; + row.Avatar.MaxRect = new SRectF(x + 8f, y + (highlight.H - avatar.H) / 2, avatar.W, avatar.H, avatar.Z); + + row.Name.X = x + avatar.W + 24f; + row.Name.Y = y + (highlight.H - row.Name.H) / 2; + + var heartsX = x + highlight.W - CPartyModeTeamSurvival.MaxHearts * (_HeartSize + _HeartSpace); + for (var h = 0; h < row.Hearts.Length; h++) + { + row.Hearts[h].MaxRect = new SRectF(heartsX + h * (_HeartSize + _HeartSpace), y + (highlight.H - _HeartSize) / 2, _HeartSize, _HeartSize, + _Statics[_StaticHeart].Rect.Z); + } + } + + private int _GetHearts(int row) + { + if (row < 0 || row >= _NumRowsUsed) + { + return 0; + } + + return _PartyMode.GetStartHearts(_Rows[row].ProfileId); + } + + private void _ChangeHearts(int row, int hearts) + { + if (row < 0 || row >= _NumRowsUsed) + { + return; + } + + hearts = Math.Max(1, Math.Min(CPartyModeTeamSurvival.MaxHearts, hearts)); + _PartyMode.GameData.PlayerHearts[_Rows[row].ProfileId] = hearts; + _UpdateRows(); + } + + private void _FocusRows() + { + _OnButtons = false; + _Buttons[_ButtonBack].Selected = false; + _Buttons[_ButtonNext].Selected = false; + _UpdateRows(); + } + + private void _FocusButtons() + { + _OnButtons = true; + _SelectElement(_Buttons[_ButtonNext]); + _UpdateRows(); + } + + private void _SwitchButton() + { + _SelectElement(_Buttons[_ButtonNext].Selected ? _Buttons[_ButtonBack] : _Buttons[_ButtonNext]); + } + + private void _SelectRow(int row) + { + _OnButtons = false; + _Buttons[_ButtonBack].Selected = false; + _Buttons[_ButtonNext].Selected = false; + if (_NumRowsUsed == 0) + { + return; + } + + _SelectedRow = Math.Max(0, Math.Min(_NumRowsUsed - 1, row)); + _UpdateRows(); + } + + private void _UpdateRows() + { + for (var r = 0; r < _NumRowsUsed; r++) + { + var row = _Rows[r]; + row.Highlight.Visible = r == _SelectedRow && !_OnButtons; + + var hearts = _GetHearts(r); + var color = _Statics[_StaticHeart].Color; + for (var h = 0; h < row.Hearts.Length; h++) + { + row.Hearts[h].Color = new SColorF(color.R, color.G, color.B, h < hearts ? color.A : color.A * _LostHeartAlpha); + } + } + + for (var r = _NumRowsUsed; r < _Rows.Count; r++) + { + _Rows[r].Highlight.Visible = false; + } + } + } +} diff --git a/PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalMain.cs b/PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalMain.cs new file mode 100644 index 00000000..8b8c7410 --- /dev/null +++ b/PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalMain.cs @@ -0,0 +1,560 @@ +#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.TeamSurvival +{ + class CPlayerCard + { + public CSurvivalPlayer Player; + public CStatic Active; + public CStatic Box; + public CStatic Avatar; + public CText Name; + public CStatic[] Hearts; + public SRectF[] HeartRects; + } + + public class CPartyScreenTeamSurvivalMain : CPartyScreenTeamSurvival + { + protected override int _ScreenVersion + { + get { return 1; } + } + + private const string _TextPopupReallyExit = "TextPopupReallyExit"; + private const string _TextTeam1 = "TextTeam1"; + private const string _TextTeam2 = "TextTeam2"; + private const string _TextPass = "TextPass"; + private const string _TextCardName = "TextCardName"; + private const string _TextDuelName1 = "TextDuelName1"; + private const string _TextDuelName2 = "TextDuelName2"; + private const string _TextVersus = "TextVersus"; + private const string _TextRematch = "TextRematch"; + 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 _StaticCardBox = "StaticCardBox"; + private const string _StaticCardActive = "StaticCardActive"; + private const string _StaticCardAvatar = "StaticCardAvatar"; + private const string _StaticHeart = "StaticHeart"; + private const string _StaticDuelFrame1 = "StaticDuelFrame1"; + private const string _StaticDuelFrame2 = "StaticDuelFrame2"; + private const string _StaticDuelAvatar1 = "StaticDuelAvatar1"; + private const string _StaticDuelAvatar2 = "StaticDuelAvatar2"; + + private const string _ParticleEffectChampion = "ParticleEffectChampion"; + + private const float _CardFirstY = 265f; + private const float _CardStep = 76f; + private const float _ActiveBorder = 4f; + private const float _HeartSize = 32f; + private const float _HeartSpace = 6f; + private const float _LostHeartAlpha = 0.18f; + private const float _OutAlpha = 0.35f; + private const float _SurvivorSize = 110f; + private const float _SurvivorY = 470f; + private const float _SurvivorSpace = 16f; + + private const float _HeartLossDelay = 400f; + private const float _HeartLossDuration = 800f; + private const float _ChampionPopDuration = 700f; + + private readonly float[] _CardX = new float[] { 60f, 1340f }; + + private bool _ExitPopupVisible; + private List _Cards; + private List _Survivors; + private readonly Stopwatch _AnimTimer = new Stopwatch(); + private CPlayerCard _LosingCard; + private int _LostHeart; + private bool _LosingCardOut; + private float _ChampionHeight; + + public override void Init() + { + base.Init(); + + _ThemeTexts = new string[] + { + _TextPopupReallyExit, _TextTeam1, _TextTeam2, _TextPass, _TextCardName, _TextDuelName1, _TextDuelName2, _TextVersus, _TextRematch, _TextChampionLabel, + _TextChampion + }; + _ThemeButtons = new string[] { _ButtonNextRound, _ButtonBack, _ButtonExit, _ButtonPopupYes, _ButtonPopupNo }; + _ThemeStatics = new string[] + { + _StaticPopupBG, _StaticCardBox, _StaticCardActive, _StaticCardAvatar, _StaticHeart, _StaticDuelFrame1, _StaticDuelFrame2, _StaticDuelAvatar1, + _StaticDuelAvatar2 + }; + _ThemeParticleEffects = new string[] { _ParticleEffectChampion }; + } + + public override void LoadTheme(string xmlPath) + { + base.LoadTheme(xmlPath); + + _Cards = new List(); + for (var i = 0; i < CPartyModeTeamSurvival.TeamCount * CPartyModeTeamSurvival.MaxPlayersInTeam; i++) + { + var card = new CPlayerCard + { + Active = GetNewStatic(_Statics[_StaticCardActive]), + Box = GetNewStatic(_Statics[_StaticCardBox]), + Avatar = GetNewStatic(_Statics[_StaticCardAvatar]), + Name = GetNewText(_Texts[_TextCardName]), + Hearts = new CStatic[CPartyModeTeamSurvival.MaxHearts], + HeartRects = new SRectF[CPartyModeTeamSurvival.MaxHearts] + }; + card.Avatar.Aspect = EAspect.Crop; + _AddStatic(card.Active); + _AddStatic(card.Box); + _AddStatic(card.Avatar); + _AddText(card.Name); + for (var h = 0; h < CPartyModeTeamSurvival.MaxHearts; h++) + { + card.Hearts[h] = GetNewStatic(_Statics[_StaticHeart]); + _AddStatic(card.Hearts[h]); + } + + _Cards.Add(card); + } + + _Survivors = new List(); + for (var i = 0; i < CPartyModeTeamSurvival.MaxPlayersInTeam; i++) + { + var survivor = GetNewStatic(_Statics[_StaticCardAvatar]); + survivor.Aspect = EAspect.Crop; + _AddStatic(survivor); + _Survivors.Add(survivor); + } + + _Statics[_StaticCardBox].Visible = false; + _Statics[_StaticCardActive].Visible = false; + _Statics[_StaticCardAvatar].Visible = false; + _Statics[_StaticHeart].Visible = false; + _Texts[_TextCardName].Visible = false; + _Statics[_StaticDuelAvatar1].Aspect = EAspect.Crop; + _Statics[_StaticDuelAvatar2].Aspect = EAspect.Crop; + + _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(); + + _BuildCards(); + _UpdateCards(); + _UpdateDuel(); + + _LosingCard = null; + var decided = _PartyMode.GameData.LastDecidedDuel; + _PartyMode.GameData.LastDecidedDuel = null; + if (decided != null) + { + _LosingCard = _FindCard(decided.Players[decided.Loser]); + _LostHeart = decided.Players[decided.Loser].Hearts; + _LosingCardOut = decided.Players[decided.Loser].IsOut; + } + + _AnimTimer.Reset(); + _AnimTimer.Start(); + _UpdateHeartLoss(); + + var started = _PartyMode.GameData.NumDuelsPlayed > 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() + { + _UpdateHeartLoss(); + + if (_PartyMode.IsFinished) + { + _UpdateChampion(); + } + + return true; + } + + private void _OnBack() + { + if (_ExitPopupVisible) + { + _ShowPopup(false); + } + else if (_PartyMode.GameData.NumDuelsPlayed == 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 _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 static SColorF _WithAlpha(SColorF color, float alpha) + { + return new SColorF(color.R, color.G, color.B, color.A * alpha); + } + + private string _GetTeamName(int team) + { + return CBase.Language.Translate("TR_TEAM", PartyModeId) + " " + (team + 1); + } + + private CPlayerCard _FindCard(CSurvivalPlayer player) + { + foreach (var card in _Cards) + { + if (card.Player == player) + { + return card; + } + } + + return null; + } + + private void _BuildCards() + { + var cardNr = 0; + for (var team = 0; team < CPartyModeTeamSurvival.TeamCount; team++) + { + var players = _PartyMode.GetTeam(team); + for (var i = 0; i < players.Count && cardNr < _Cards.Count; i++) + { + var card = _Cards[cardNr++]; + card.Player = players[i]; + + var boxTemplate = _Statics[_StaticCardBox].Rect; + var box = new SRectF(_CardX[team], _CardFirstY + i * _CardStep, boxTemplate.W, boxTemplate.H, boxTemplate.Z); + card.Box.MaxRect = box; + card.Active.MaxRect = new SRectF(box.X - _ActiveBorder, box.Y - _ActiveBorder, box.W + 2 * _ActiveBorder, box.H + 2 * _ActiveBorder, + _Statics[_StaticCardActive].Rect.Z); + + var avatarTemplate = _Statics[_StaticCardAvatar].Rect; + card.Avatar.MaxRect = new SRectF(box.X + 6f, box.Y + (box.H - avatarTemplate.H) / 2, avatarTemplate.W, avatarTemplate.H, avatarTemplate.Z); + card.Avatar.Texture = CBase.Profiles.GetAvatar(card.Player.ProfileId); + + card.Name.Text = CBase.Profiles.GetPlayerName(card.Player.ProfileId); + card.Name.X = box.X + avatarTemplate.W + 18f; + card.Name.Y = box.Y + (box.H - card.Name.H) / 2; + card.Name.W = box.W - avatarTemplate.W - 30f - CPartyModeTeamSurvival.MaxHearts * (_HeartSize + _HeartSpace); + + var heartsX = box.X + box.W - 10f - card.Player.StartHearts * (_HeartSize + _HeartSpace); + for (var h = 0; h < card.Hearts.Length; h++) + { + card.HeartRects[h] = new SRectF(heartsX + h * (_HeartSize + _HeartSpace), box.Y + (box.H - _HeartSize) / 2, _HeartSize, _HeartSize, + _Statics[_StaticHeart].Rect.Z); + card.Hearts[h].MaxRect = card.HeartRects[h]; + } + } + } + + for (var i = cardNr; i < _Cards.Count; i++) + { + _Cards[i].Player = null; + } + } + + private void _UpdateCards() + { + var duel = _PartyMode.CurrentDuel; + foreach (var card in _Cards) + { + var visible = card.Player != null; + card.Box.Visible = visible; + card.Avatar.Visible = visible; + card.Name.Visible = visible; + card.Active.Visible = visible && duel != null && (duel.Players[0] == card.Player || duel.Players[1] == card.Player); + for (var h = 0; h < card.Hearts.Length; h++) + { + card.Hearts[h].Visible = visible && h < card.Player.StartHearts; + } + + if (visible) + { + _SetCardAlpha(card, card.Player.IsOut ? _OutAlpha : 1f); + _SetHeartAlphas(card, card.Player.Hearts); + } + } + + for (var team = 0; team < CPartyModeTeamSurvival.TeamCount; team++) + { + var text = _Texts[team == 0 ? _TextTeam1 : _TextTeam2]; + text.Text = _GetTeamName(team); + text.Color = CBase.Themes.GetPlayerColor(team + 1); + } + } + + private void _SetCardAlpha(CPlayerCard card, float alpha) + { + card.Box.Color = _WithAlpha(_Statics[_StaticCardBox].Color, alpha); + card.Avatar.Color = _WithAlpha(_Statics[_StaticCardAvatar].Color, alpha); + card.Name.Color = _WithAlpha(_Texts[_TextCardName].Color, alpha); + } + + private void _SetHeartAlphas(CPlayerCard card, int hearts) + { + for (var h = 0; h < card.Hearts.Length; h++) + { + card.Hearts[h].MaxRect = card.HeartRects[h]; + card.Hearts[h].Color = _WithAlpha(_Statics[_StaticHeart].Color, h < hearts ? 1f : _LostHeartAlpha); + } + } + + private void _UpdateHeartLoss() + { + if (_LosingCard == null || _LostHeart < 0 || _LostHeart >= _LosingCard.Hearts.Length) + { + return; + } + + var progress = Math.Max(0f, Math.Min(1f, (_AnimTimer.ElapsedMilliseconds - _HeartLossDelay) / _HeartLossDuration)); + var heart = _LosingCard.Hearts[_LostHeart]; + var rect = _LosingCard.HeartRects[_LostHeart]; + var scale = 1f + progress; + var size = rect.W * scale; + heart.MaxRect = new SRectF(rect.X + (rect.W - size) / 2, rect.Y + (rect.H - size) / 2, size, size, rect.Z); + heart.Color = _WithAlpha(_Statics[_StaticHeart].Color, 1f - (1f - _LostHeartAlpha) * progress); + + if (_LosingCardOut) + { + _SetCardAlpha(_LosingCard, 1f - (1f - _OutAlpha) * progress); + } + + if (progress >= 1f) + { + heart.MaxRect = rect; + _LosingCard = null; + } + } + + private void _UpdateDuel() + { + var finished = _PartyMode.IsFinished; + var duel = _PartyMode.CurrentDuel; + var showDuel = !finished && duel != null; + + _Statics[_StaticDuelFrame1].Visible = showDuel; + _Statics[_StaticDuelFrame2].Visible = showDuel; + _Statics[_StaticDuelAvatar1].Visible = showDuel; + _Statics[_StaticDuelAvatar2].Visible = showDuel; + _Texts[_TextDuelName1].Visible = showDuel; + _Texts[_TextDuelName2].Visible = showDuel; + _Texts[_TextVersus].Visible = showDuel; + _Texts[_TextPass].Visible = showDuel; + _Texts[_TextRematch].Visible = showDuel && _PartyMode.GameData.IsRematch; + + if (showDuel) + { + _Statics[_StaticDuelFrame1].Color = CBase.Themes.GetPlayerColor(1); + _Statics[_StaticDuelFrame2].Color = CBase.Themes.GetPlayerColor(2); + _Statics[_StaticDuelAvatar1].Texture = CBase.Profiles.GetAvatar(duel.Players[0].ProfileId); + _Statics[_StaticDuelAvatar2].Texture = CBase.Profiles.GetAvatar(duel.Players[1].ProfileId); + _Texts[_TextDuelName1].Text = CBase.Profiles.GetPlayerName(duel.Players[0].ProfileId); + _Texts[_TextDuelName2].Text = CBase.Profiles.GetPlayerName(duel.Players[1].ProfileId); + _Texts[_TextPass].Text = CBase.Language.Translate("TR_SCREENMAIN_PASS", PartyModeId) + " " + _PartyMode.GameData.PassNr + " · " + + CBase.Language.Translate("TR_SCREENMAIN_DUEL", PartyModeId) + " " + (_PartyMode.GameData.DuelIndex + 1) + " / " + + _PartyMode.GameData.PassDuels.Count; + } + + _Texts[_TextChampionLabel].Visible = finished; + _Texts[_TextChampion].Visible = finished; + _ParticleEffects[_ParticleEffectChampion].Visible = finished; + + var survivors = new List(); + if (finished) + { + _Texts[_TextChampion].Text = _GetTeamName(_PartyMode.GameData.WinnerTeam); + foreach (var player in _PartyMode.GetTeam(_PartyMode.GameData.WinnerTeam)) + { + if (!player.IsOut) + { + survivors.Add(player); + } + } + } + + var x = (CBase.Settings.GetRenderW() - survivors.Count * _SurvivorSize - (survivors.Count - 1) * _SurvivorSpace) / 2; + for (var i = 0; i < _Survivors.Count; i++) + { + _Survivors[i].Visible = i < survivors.Count; + if (i >= survivors.Count) + { + continue; + } + + _Survivors[i].Texture = CBase.Profiles.GetAvatar(survivors[i].ProfileId); + _Survivors[i].MaxRect = new SRectF(x, _SurvivorY, _SurvivorSize, _SurvivorSize, _Statics[_StaticCardAvatar].Rect.Z); + x += _SurvivorSize + _SurvivorSpace; + } + } + + private void _UpdateChampion() + { + var time = _AnimTimer.ElapsedMilliseconds; + float scale; + if (time < _ChampionPopDuration) + { + scale = 0.3f + 0.7f * _EaseOutBack(time / _ChampionPopDuration); + } + else + { + scale = 1f + 0.03f * (float)Math.Sin((time - _ChampionPopDuration) / 1000.0 * Math.PI * 1.4); + } + + _Texts[_TextChampion].Font.Height = _ChampionHeight * scale; + } + } +} diff --git a/PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalNames.cs b/PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalNames.cs new file mode 100644 index 00000000..7e512150 --- /dev/null +++ b/PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalNames.cs @@ -0,0 +1,88 @@ +#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.TeamSurvival +{ + public class CPartyScreenTeamSurvivalNames : CMenuPartyNameSelection + { + protected override int _ScreenVersion + { + get { return 1; } + } + + private new CPartyModeTeamSurvival _PartyMode; + + public override void Init() + { + base.Init(); + _PartyMode = (CPartyModeTeamSurvival)base._PartyMode; + } + + public override void OnShow() + { + base.OnShow(); + + while (_PartyMode.GameData.ProfileIdsTeam1.Count > _PartyMode.GameData.NumPlayerTeam1) + { + _PartyMode.GameData.ProfileIdsTeam1.RemoveAt(_PartyMode.GameData.ProfileIdsTeam1.Count - 1); + } + + while (_PartyMode.GameData.ProfileIdsTeam2.Count > _PartyMode.GameData.NumPlayerTeam2) + { + _PartyMode.GameData.ProfileIdsTeam2.RemoveAt(_PartyMode.GameData.ProfileIdsTeam2.Count - 1); + } + + SetPartyModeData(CPartyModeTeamSurvival.TeamCount, _PartyMode.GameData.NumPlayerTeam1 + _PartyMode.GameData.NumPlayerTeam2, + new int[] { _PartyMode.GameData.NumPlayerTeam1, _PartyMode.GameData.NumPlayerTeam2 }); + var ids = new List[] { _PartyMode.GameData.ProfileIdsTeam1, _PartyMode.GameData.ProfileIdsTeam2 }; + SetPartyModeProfiles(ids); + } + + public override void Back() + { + _SaveTeams(); + _PartyMode.Back(); + } + + public override void Next() + { + _SaveTeams(); + _PartyMode.GameData.NumPlayerTeam1 = _PartyMode.GameData.ProfileIdsTeam1.Count; + _PartyMode.GameData.NumPlayerTeam2 = _PartyMode.GameData.ProfileIdsTeam2.Count; + _PartyMode.Next(); + } + + private void _SaveTeams() + { + if (_TeamList.Length == CPartyModeTeamSurvival.TeamCount) + { + _PartyMode.GameData.ProfileIdsTeam1 = _TeamList[0]; + _PartyMode.GameData.ProfileIdsTeam2 = _TeamList[1]; + } + + if (_NumPlayerTeams.Length == CPartyModeTeamSurvival.TeamCount) + { + _PartyMode.GameData.NumPlayerTeam1 = _NumPlayerTeams[0]; + _PartyMode.GameData.NumPlayerTeam2 = _NumPlayerTeams[1]; + } + } + } +} diff --git a/PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalSongs.cs b/PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalSongs.cs new file mode 100644 index 00000000..543def64 --- /dev/null +++ b/PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalSongs.cs @@ -0,0 +1,66 @@ +using VocaluxeLib.Menu; + +namespace VocaluxeLib.PartyModes.TeamSurvival +{ + class CPartyScreenTeamSurvivalSongs : CMenuPartySongSelection + { + protected override int _ScreenVersion + { + get { return 1; } + } + + private new CPartyModeTeamSurvival _PartyMode; + + public override void Init() + { + base.Init(); + _PartyMode = (CPartyModeTeamSurvival)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/PartyModeTeamSurvival/GlobalSuppressions.cs b/PartyModes/PartyModeTeamSurvival/GlobalSuppressions.cs new file mode 100644 index 00000000..e661ff03 Binary files /dev/null and b/PartyModes/PartyModeTeamSurvival/GlobalSuppressions.cs differ diff --git a/PartyModes/PartyModeTeamSurvival/PartyModeTeamSurvival.csproj b/PartyModes/PartyModeTeamSurvival/PartyModeTeamSurvival.csproj new file mode 100644 index 00000000..be08e00b --- /dev/null +++ b/PartyModes/PartyModeTeamSurvival/PartyModeTeamSurvival.csproj @@ -0,0 +1,119 @@ + + + + DebugWin + AnyCPU + 8.0.30703 + 2.0 + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41} + Library + Properties + VocaluxeLib.PartyModes.TeamSurvival + TeamSurvival + 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/PartyModeTeamSurvival/Settings.StyleCop b/PartyModes/PartyModeTeamSurvival/Settings.StyleCop new file mode 100644 index 00000000..f4a4ea2a --- /dev/null +++ b/PartyModes/PartyModeTeamSurvival/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 423e9884..2681e92a 100644 --- a/Vocaluxe.sln +++ b/Vocaluxe.sln @@ -4,6 +4,7 @@ VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vocaluxe", "Vocaluxe\Vocaluxe.csproj", "{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}" ProjectSection(ProjectDependencies) = postProject + {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} {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC} = {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC} @@ -23,6 +24,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PitchTracker", "PitchTracke EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{8EDF4429-251A-416D-BB68-93F227191BCF}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PartyModeTeamSurvival", "PartyModes\PartyModeTeamSurvival\PartyModeTeamSurvival.csproj", "{7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution DebugLinux|x64 = DebugLinux|x64 @@ -173,6 +176,26 @@ Global {8EDF4429-251A-416D-BB68-93F227191BCF}.ReleaseWin|x64.Build.0 = Release|x64 {8EDF4429-251A-416D-BB68-93F227191BCF}.ReleaseWin|x86.ActiveCfg = Release|x86 {8EDF4429-251A-416D-BB68-93F227191BCF}.ReleaseWin|x86.Build.0 = Release|x86 + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.DebugLinux|x64.ActiveCfg = DebugLinux|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.DebugLinux|x64.Build.0 = DebugLinux|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.DebugLinux|x86.ActiveCfg = DebugLinux|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.DebugLinux|x86.Build.0 = DebugLinux|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.DebugWin|x64.ActiveCfg = DebugWin|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.DebugWin|x64.Build.0 = DebugWin|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.DebugWin|x86.ActiveCfg = DebugWin|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.DebugWin|x86.Build.0 = DebugWin|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.InstallerWin|x64.ActiveCfg = InstallerWin|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.InstallerWin|x64.Build.0 = InstallerWin|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.InstallerWin|x86.ActiveCfg = InstallerWin|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.InstallerWin|x86.Build.0 = InstallerWin|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.ReleaseLinux|x64.ActiveCfg = ReleaseLinux|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.ReleaseLinux|x64.Build.0 = ReleaseLinux|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.ReleaseLinux|x86.ActiveCfg = ReleaseLinux|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.ReleaseLinux|x86.Build.0 = ReleaseLinux|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.ReleaseWin|x64.ActiveCfg = ReleaseWin|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.ReleaseWin|x64.Build.0 = ReleaseWin|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.ReleaseWin|x86.ActiveCfg = ReleaseWin|Any CPU + {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.ReleaseWin|x86.Build.0 = ReleaseWin|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE