From 3810f75e041b0cfbdd70811012f5d9bf23a83f1d Mon Sep 17 00:00:00 2001 From: McSchneidar <262792195+McSchneidar@users.noreply.github.com> Date: Sun, 18 Oct 2026 07:49:44 +0200 Subject: [PATCH] New party mode: Team Survival (#914) * Add team survival party mode A new party mode for two teams that only needs 2 microphones. In every duel one player of each team sings against one of the other team. Whoever loses a duel loses a heart, players without hearts are out, and the team whose players are all out loses. - Every player sings once per round before anyone sings again, the duels are drawn randomly - Teams of different sizes are possible, in the smaller team some players sing a second time per round - Hearts can be the same for everyone or set per player, to balance uneven teams or strong and weak singers - Up to 3 jokers per player to skip a song - On a tie, the duel is sung again - A lost heart is animated, and the winning team is celebrated at the end * Trigger CI rebuild --------- Co-authored-by: Florian Ostertag --- Output/PartyModes/TeamSurvival.xml | 21 + .../PartyModes/TeamSurvival/Languages/de.xml | 36 + .../PartyModes/TeamSurvival/Languages/en.xml | 36 + .../TeamSurvival/Themes/Default.xml | 10 + .../TeamSurvival/Themes/Default/Default.xml | 16 + .../TeamSurvival/Themes/Default/Heart.png | Bin 0 -> 2605 bytes .../Themes/Default/PartyModeIcon.png | Bin 0 -> 6430 bytes .../Screens/PartyScreenTeamSurvivalConfig.xml | 295 +++++++ .../Screens/PartyScreenTeamSurvivalHearts.xml | 262 ++++++ .../Screens/PartyScreenTeamSurvivalMain.xml | 586 +++++++++++++ .../Screens/PartyScreenTeamSurvivalNames.xml | 410 +++++++++ .../Screens/PartyScreenTeamSurvivalSongs.xml | 407 +++++++++ .../CPartyModeTeamSurvival.cs | 769 +++++++++++++++++ .../CPartyScreenTeamSurvivalConfig.cs | 145 ++++ .../CPartyScreenTeamSurvivalHearts.cs | 374 ++++++++ .../CPartyScreenTeamSurvivalMain.cs | 560 ++++++++++++ .../CPartyScreenTeamSurvivalNames.cs | 88 ++ .../CPartyScreenTeamSurvivalSongs.cs | 66 ++ .../GlobalSuppressions.cs | Bin 0 -> 1704 bytes .../PartyModeTeamSurvival.csproj | 119 +++ .../PartyModeTeamSurvival/Settings.StyleCop | 809 ++++++++++++++++++ Vocaluxe.sln | 23 + 22 files changed, 5032 insertions(+) create mode 100644 Output/PartyModes/TeamSurvival.xml create mode 100644 Output/PartyModes/TeamSurvival/Languages/de.xml create mode 100644 Output/PartyModes/TeamSurvival/Languages/en.xml create mode 100644 Output/PartyModes/TeamSurvival/Themes/Default.xml create mode 100644 Output/PartyModes/TeamSurvival/Themes/Default/Default.xml create mode 100644 Output/PartyModes/TeamSurvival/Themes/Default/Heart.png create mode 100644 Output/PartyModes/TeamSurvival/Themes/Default/PartyModeIcon.png create mode 100644 Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalConfig.xml create mode 100644 Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalHearts.xml create mode 100644 Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalMain.xml create mode 100644 Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalNames.xml create mode 100644 Output/PartyModes/TeamSurvival/Themes/Default/Screens/PartyScreenTeamSurvivalSongs.xml create mode 100644 PartyModes/PartyModeTeamSurvival/CPartyModeTeamSurvival.cs create mode 100644 PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalConfig.cs create mode 100644 PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalHearts.cs create mode 100644 PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalMain.cs create mode 100644 PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalNames.cs create mode 100644 PartyModes/PartyModeTeamSurvival/CPartyScreenTeamSurvivalSongs.cs create mode 100644 PartyModes/PartyModeTeamSurvival/GlobalSuppressions.cs create mode 100644 PartyModes/PartyModeTeamSurvival/PartyModeTeamSurvival.csproj create mode 100644 PartyModes/PartyModeTeamSurvival/Settings.StyleCop 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 0000000000000000000000000000000000000000..76af991a23bcf3b86dcc75a477fdd2aa02ee4b06 GIT binary patch literal 2605 zcmb7`X*|@68pr=LW6M?;nJL7WGYn!zXk;6*Gia1O#!~h|ikvuO9Lpq29N}JSWItsK zS&|uykZsBqVI;d#oUu(2SNFxe@9yVwU;Li$v;5vX?|xK!TXPY?Q-S~hh*(;f5RXXy zDFMEt+G*g`cLdNaqPa0pH7LDuG?-j-w!BUt0Ln+b002q~0C;{{j&$ls005zZ0LT$R zKX)|nf39R2QOjkt!Ra+dGM4SE~(5Nb?n6I}J6<)X@vff2QMuYHIX?2_KG z)?UNWvmHaaJtR!1xiKF${rS2n%O%wRm*jH{s~Y|YSA%XwD#?(4JX{7b{ZM3LwLbY= zSlO_TGi5kt7E~j2`Rr*dt|ItNv4lnBC_=RBn&$-ew#k{ao%l+ctyq9H{*$HJg{=y@ z$jGJs+-Vhd-5C2}adsheX@`IJuiNA4*`rNi&NJK*DT^dKMB47q>0wrEf}uPy`C?1| zU1|5{Aw%Xp4Hy_BUqnJC!V7H6Z!D4o4w03S}KD^PC@BX7u4^cuKD5^;-CH+~snPM4Fvk zDN|>VHOt8de>Jx3>6PNQ+A46RnykqydU`1-z9pb~HNhK}dG~ij+noK4KZ< z74VWI+d`6VonmP?x|@+VS3-KzOIRQI7HpcWp*djIz?m!z++v`>8npbKjkMt--dZ98 zehKhbcSRt6rL`HjW4_?>I|PJTG5W-V9{SFiO1aS|KeW=W~shM z2J?yE%GCz%%ij5GQC}Fjh^Yj&HdRqx=Q6mXwe_csil{%vYd)_>uXl$k_?t@$Q5Enb zm(nSO4&T|b;(3)~COFwUR=xkjKoIQTPiTH2%-;C(!N^oIl<{nu>D=i}7`QrzwD;XG zv2PUDI`02AM-l3HKDq5%u~Wyv-hq!hqe1~+OuCv6{U03v(rF(lkXP_h|}Ix73l(BZAP@8X*gcz!Wi5PpSt^Gu`;qXuw!Y z^pYOf!mBtc^;x)XRXE?6uVq_npC-5*QbcZ3q-|OU(4ACXqY~gBQWMco{OXTGN9#N@ z;PwMy)u1chYaW;y)gaEo?L{$s0gPAl+TZdx*N>=%bF^PICD7!4^$lNH5H!$txpcBq zo1YKfgtp_1>NtVQ75KKT3svfG5LF;5Pu=Ik5#wkQOT3JNeNKniN>BOqS;4vDL0L*< z&rR0>eQ*!SmwU>Q|F;`wtIv$7>q6%C|AFYu={4q+ItB*3uXQDeb0zOc)_p@g_Ctg zU#%rpuoFq3unKycL}Q873a{LH=;h-niMe;+F((IBQ+Q!-(@FRsSh7@vR`a zY$Jfimce{8gnXAh)XSvr91;p990EW}JoiZ#Qv4WRliCw~xLWT)zurtGA|!*3%!rN@bYh7E&V$I74O z4T-E!+Hnz+YOuF=11Y(J$Isg8>n^`>>VwuL{&2mSH|`3Ypdq-Yrx>e53@t`Ps;lWT zHhz*_{O2`sSPlu5PwC1))T-D!FnOt+{Xn7AwGOSQw%kX>)MBDMBNMy4 zL8wDE_E#rB@G%0H)}@Sb`6!anNc|L^N$+ZO4txTsS3n{HQ6bT>Ct8#e^9)di0^V?u zlkwAXnh%Fk;^ihH73IT4xxdf^Gpbu!w>?_(A@x2Y#&%wGRFcGG!>{#r)gb{dcB$qD zT`hA9(zJp`vBF`02QjWPC&X2$cQ>19LWdoTZvR3$zF|6_a!>HO2?43|yIId;{(HGn zJxO=vL&tDuzu@6*83L%=3P9$>;f^gD?ac3~Q?X z9g&gdg}ol!xGtR0YD#iSGq!(X+ScuNpo769wlM+bi3nD$kzRk809#ZHf{f7M4i*YT z*f@BY)Xq0*;Jv%!b|voPLq5CieTeRa$+ag@oF<`hJ1gfi2>%!asIt6|1JK~g^uXw; zlb%8lf{{m+>fJguU literal 0 HcmV?d00001 diff --git a/Output/PartyModes/TeamSurvival/Themes/Default/PartyModeIcon.png b/Output/PartyModes/TeamSurvival/Themes/Default/PartyModeIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..3f421a173c2435e74a9565ab201d0c2a10418e33 GIT binary patch literal 6430 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 aL(GM;Mt$}br|W;;CJSz+x1p{8 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..e661ff030ad7d32272d04b4b0dafd6d8f44c9c78 GIT binary patch literal 1704 zcmbW2-)j>=5Xa|P@PAm+mljH@2tHU5Vl-7q+G0{m5g+p7(j1=2k-J#)&#RyB>|HOB z`e0cuyE{8O^PTU^PJaJ7u(c(2YpJblX~8m9QzT0(_>;YX^zfcAf(_k&!$q(jl8AW>&X~PpG!xeG zz9RnN*ox{r*b8L)k?doX1##7|a|miN8JU;O6%o`PkJyXjEpz6Yk->ex|5pJIJvlz5t376vMmJSUaTa}@Gh>DddcyWawgQVde_cU={$-5hTnm`$43|c(ND+Tf~W78 zgd$dM&-dr(4jIb+1-FD%H7A@SG`d94_no9yNH5VFa;uG=swh@dLww~7q0s4|n&l(0Lu(ea{s7Ok8_oa# literal 0 HcmV?d00001 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