Added options for number of songs and song-source to challenge-medley.
This commit is contained in:
1 parent
dddb1206b3
commit
cf6ff3c133
5 files changed
+368
-153
No files matched your search
@@ -8,7 +8,7 @@
|
|||||||
<Folder>ChallengeMedley</Folder>
|
<Folder>ChallengeMedley</Folder>
|
||||||
<PartyModeFile>CPartyModeChallengeMedley</PartyModeFile>
|
<PartyModeFile>CPartyModeChallengeMedley</PartyModeFile>
|
||||||
<PartyModeVersionMajor>0</PartyModeVersionMajor>
|
<PartyModeVersionMajor>0</PartyModeVersionMajor>
|
||||||
<PartyModeVersionMinor>1</PartyModeVersionMinor>
|
<PartyModeVersionMinor>2</PartyModeVersionMinor>
|
||||||
<TargetAudience>TR_PARTYMODE_AUDIENCE</TargetAudience>
|
<TargetAudience>TR_PARTYMODE_AUDIENCE</TargetAudience>
|
||||||
</Info>
|
</Info>
|
||||||
<PartyScreens>
|
<PartyScreens>
|
||||||
@@ -16,4 +16,4 @@
|
|||||||
<ScreenFile>CPartyScreenChallengeMedleyConfig</ScreenFile>
|
<ScreenFile>CPartyScreenChallengeMedleyConfig</ScreenFile>
|
||||||
<ScreenFile>CPartyScreenChallengeMedleyNames</ScreenFile>
|
<ScreenFile>CPartyScreenChallengeMedleyNames</ScreenFile>
|
||||||
</PartyScreens>
|
</PartyScreens>
|
||||||
</root>
|
</root>
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="language">English</string>
|
<string name="language">English</string>
|
||||||
<string name="TR_PARTYMODE_NAME">Challenge Medley Mode</string>
|
<string name="TR_PARTYMODE_NAME">Challenge Medley Mode</string>
|
||||||
<string name="TR_PARTYMODE_DESCRIPTION">Play some challenge rounds by using 5-some Medleys only.</string>
|
<string name="TR_PARTYMODE_DESCRIPTION">Play some challenge rounds by using Medleys only.</string>
|
||||||
<string name="TR_PARTYMODE_AUDIENCE">For all who are interested in duel fights and Medleys.</string>
|
<string name="TR_PARTYMODE_AUDIENCE">For all who are interested in duel fights and Medleys.</string>
|
||||||
<string name="TR_BUTTON_NEXT">Next</string>
|
<string name="TR_BUTTON_NEXT">Next</string>
|
||||||
<string name="TR_BUTTON_BACK">Back</string>
|
<string name="TR_BUTTON_BACK">Back</string>
|
||||||
@@ -11,10 +11,16 @@
|
|||||||
<string name="TR_BUTTON_YES">Yes</string>
|
<string name="TR_BUTTON_YES">Yes</string>
|
||||||
<string name="TR_BUTTON_NO">No</string>
|
<string name="TR_BUTTON_NO">No</string>
|
||||||
<string name="TR_BUTTON_NEXT_ROUND">Next Round</string>
|
<string name="TR_BUTTON_NEXT_ROUND">Next Round</string>
|
||||||
|
<string name="TR_PLAYLIST">Playlist</string>
|
||||||
|
<string name="TR_CATEGORY">Category</string>
|
||||||
|
<string name="TR_ALLSONGS">All songs</string>
|
||||||
|
<string name="TR_SONGS">Songs</string>
|
||||||
<string name="TR_SCREENCONFIG_TITLE">Challenge Medley Mode: Configuration</string>
|
<string name="TR_SCREENCONFIG_TITLE">Challenge Medley Mode: Configuration</string>
|
||||||
<string name="TR_SCREENCONFIG_NUMPLAYERS">Number of players</string>
|
<string name="TR_SCREENCONFIG_NUMPLAYERS">Number of players</string>
|
||||||
<string name="TR_SCREENCONFIG_NUMMICS">Number of mics</string>
|
<string name="TR_SCREENCONFIG_NUMMICS">Number of mics</string>
|
||||||
<string name="TR_SCREENCONFIG_NUMROUNDS">Number of rounds</string>
|
<string name="TR_SCREENCONFIG_NUMROUNDS">Number of rounds</string>
|
||||||
|
<string name="TR_SCREENCONFIG_NUMSONGS">Number of songs per round</string>
|
||||||
|
<string name="TR_SCREENCONFIG_SONGSOURCE">Song source</string>
|
||||||
<string name="TR_SCREENNAMES_TITLE">Challenge Medley Mode: Choose Player</string>
|
<string name="TR_SCREENNAMES_TITLE">Challenge Medley Mode: Choose Player</string>
|
||||||
<string name="TR_SCREENNAMES_BUTTON_RANDOM">Select random</string>
|
<string name="TR_SCREENNAMES_BUTTON_RANDOM">Select random</string>
|
||||||
<string name="TR_SCREENMAIN_TITLE">Challenge Medley Mode: Overview</string>
|
<string name="TR_SCREENMAIN_TITLE">Challenge Medley Mode: Overview</string>
|
||||||
|
|||||||
+198
-2
@@ -2,7 +2,7 @@
|
|||||||
<Screen xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
<Screen xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<Informations>
|
<Informations>
|
||||||
<ScreenName>PartyScreenChallengeMedleyConfig</ScreenName>
|
<ScreenName>PartyScreenChallengeMedleyConfig</ScreenName>
|
||||||
<ScreenVersion>1</ScreenVersion>
|
<ScreenVersion>2</ScreenVersion>
|
||||||
</Informations>
|
</Informations>
|
||||||
<Backgrounds>
|
<Backgrounds>
|
||||||
<Background Name="Background1">
|
<Background Name="Background1">
|
||||||
@@ -83,6 +83,34 @@
|
|||||||
<Font>Outline</Font>
|
<Font>Outline</Font>
|
||||||
<Text>TR_SCREENCONFIG_NUMROUNDS</Text>
|
<Text>TR_SCREENCONFIG_NUMROUNDS</Text>
|
||||||
</Text>
|
</Text>
|
||||||
|
<Text Name="Text5">
|
||||||
|
<X>75</X>
|
||||||
|
<Y>285</Y>
|
||||||
|
<Z>0</Z>
|
||||||
|
<H>27</H>
|
||||||
|
<MaxW>0</MaxW>
|
||||||
|
<Color Name="StaticColor" />
|
||||||
|
<SelColor Name="TextSelColor" />
|
||||||
|
<Align>Left</Align>
|
||||||
|
<ResizeAlign>Center</ResizeAlign>
|
||||||
|
<Style>Bold</Style>
|
||||||
|
<Font>Outline</Font>
|
||||||
|
<Text>TR_SCREENCONFIG_NUMSONGS</Text>
|
||||||
|
</Text>
|
||||||
|
<Text Name="Text6">
|
||||||
|
<X>75</X>
|
||||||
|
<Y>345</Y>
|
||||||
|
<Z>0</Z>
|
||||||
|
<H>27</H>
|
||||||
|
<MaxW>0</MaxW>
|
||||||
|
<Color Name="StaticColor" />
|
||||||
|
<SelColor Name="TextSelColor" />
|
||||||
|
<Align>Left</Align>
|
||||||
|
<ResizeAlign>Center</ResizeAlign>
|
||||||
|
<Style>Bold</Style>
|
||||||
|
<Font>Outline</Font>
|
||||||
|
<Text>TR_SCREENCONFIG_SONGSOURCE</Text>
|
||||||
|
</Text>
|
||||||
</Texts>
|
</Texts>
|
||||||
<Buttons>
|
<Buttons>
|
||||||
<Button Name="ButtonNext">
|
<Button Name="ButtonNext">
|
||||||
@@ -285,6 +313,174 @@
|
|||||||
<TextStyle>Bold</TextStyle>
|
<TextStyle>Bold</TextStyle>
|
||||||
<NumVisible>10</NumVisible>
|
<NumVisible>10</NumVisible>
|
||||||
</SelectSlide>
|
</SelectSlide>
|
||||||
|
<SelectSlide Name="SelectSlideNumSongs">
|
||||||
|
<Skin/>
|
||||||
|
<SkinArrowLeft>SelectSlideArrowLeft</SkinArrowLeft>
|
||||||
|
<SkinArrowRight>SelectSlideArrowRight</SkinArrowRight>
|
||||||
|
<SkinSelected>SelectSlide</SkinSelected>
|
||||||
|
<SkinArrowLeftSelected>SelectSlideArrowLeft</SkinArrowLeftSelected>
|
||||||
|
<SkinArrowRightSelected>SelectSlideArrowRight</SkinArrowRightSelected>
|
||||||
|
<Rect>
|
||||||
|
<X>500</X>
|
||||||
|
<Y>280</Y>
|
||||||
|
<W>700</W>
|
||||||
|
<H>50</H>
|
||||||
|
<Z>0</Z>
|
||||||
|
</Rect>
|
||||||
|
<RectArrowLeft>
|
||||||
|
<X>505</X>
|
||||||
|
<Y>285</Y>
|
||||||
|
<W>40</W>
|
||||||
|
<H>40</H>
|
||||||
|
<Z>0</Z>
|
||||||
|
</RectArrowLeft>
|
||||||
|
<RectArrowRight>
|
||||||
|
<X>1170</X>
|
||||||
|
<Y>285</Y>
|
||||||
|
<W>40</W>
|
||||||
|
<H>40</H>
|
||||||
|
<Z>0</Z>
|
||||||
|
</RectArrowRight>
|
||||||
|
<Color Name="SelectSlideColor" />
|
||||||
|
<SelColor Name="SelectSlideSelColor" />
|
||||||
|
<ArrowColor Name="ArrowColor" />
|
||||||
|
<ArrowSelColor Name="ArrowSelColor" />
|
||||||
|
<TextColor Name="TextColor" />
|
||||||
|
<TextSelColor Name="TextSelColor" />
|
||||||
|
<TextH>27</TextH>
|
||||||
|
<TextRelativeX>50</TextRelativeX>
|
||||||
|
<TextRelativeY>0</TextRelativeY>
|
||||||
|
<TextMaxW>205.33</TextMaxW>
|
||||||
|
<TextFont>Outline</TextFont>
|
||||||
|
<TextStyle>Bold</TextStyle>
|
||||||
|
<NumVisible>10</NumVisible>
|
||||||
|
</SelectSlide>
|
||||||
|
<SelectSlide Name="SelectSlideSongSource">
|
||||||
|
<Skin/>
|
||||||
|
<SkinArrowLeft>SelectSlideArrowLeft</SkinArrowLeft>
|
||||||
|
<SkinArrowRight>SelectSlideArrowRight</SkinArrowRight>
|
||||||
|
<SkinSelected>SelectSlide</SkinSelected>
|
||||||
|
<SkinArrowLeftSelected>SelectSlideArrowLeft</SkinArrowLeftSelected>
|
||||||
|
<SkinArrowRightSelected>SelectSlideArrowRight</SkinArrowRightSelected>
|
||||||
|
<Rect>
|
||||||
|
<X>500</X>
|
||||||
|
<Y>340</Y>
|
||||||
|
<W>700</W>
|
||||||
|
<H>50</H>
|
||||||
|
<Z>0</Z>
|
||||||
|
</Rect>
|
||||||
|
<RectArrowLeft>
|
||||||
|
<X>505</X>
|
||||||
|
<Y>345</Y>
|
||||||
|
<W>40</W>
|
||||||
|
<H>40</H>
|
||||||
|
<Z>0</Z>
|
||||||
|
</RectArrowLeft>
|
||||||
|
<RectArrowRight>
|
||||||
|
<X>1170</X>
|
||||||
|
<Y>345</Y>
|
||||||
|
<W>40</W>
|
||||||
|
<H>40</H>
|
||||||
|
<Z>0</Z>
|
||||||
|
</RectArrowRight>
|
||||||
|
<Color Name="SelectSlideColor" />
|
||||||
|
<SelColor Name="SelectSlideSelColor" />
|
||||||
|
<ArrowColor Name="ArrowColor" />
|
||||||
|
<ArrowSelColor Name="ArrowSelColor" />
|
||||||
|
<TextColor Name="TextColor" />
|
||||||
|
<TextSelColor Name="TextSelColor" />
|
||||||
|
<TextH>27</TextH>
|
||||||
|
<TextRelativeX>50</TextRelativeX>
|
||||||
|
<TextRelativeY>0</TextRelativeY>
|
||||||
|
<TextMaxW>205.33</TextMaxW>
|
||||||
|
<TextFont>Outline</TextFont>
|
||||||
|
<TextStyle>Bold</TextStyle>
|
||||||
|
<NumVisible>3</NumVisible>
|
||||||
|
</SelectSlide>
|
||||||
|
<SelectSlide Name="SelectSlidePlaylist">
|
||||||
|
<Skin/>
|
||||||
|
<SkinArrowLeft>SelectSlideArrowLeft</SkinArrowLeft>
|
||||||
|
<SkinArrowRight>SelectSlideArrowRight</SkinArrowRight>
|
||||||
|
<SkinSelected>SelectSlide</SkinSelected>
|
||||||
|
<SkinArrowLeftSelected>SelectSlideArrowLeft</SkinArrowLeftSelected>
|
||||||
|
<SkinArrowRightSelected>SelectSlideArrowRight</SkinArrowRightSelected>
|
||||||
|
<Rect>
|
||||||
|
<X>500</X>
|
||||||
|
<Y>400</Y>
|
||||||
|
<W>700</W>
|
||||||
|
<H>50</H>
|
||||||
|
<Z>0</Z>
|
||||||
|
</Rect>
|
||||||
|
<RectArrowLeft>
|
||||||
|
<X>505</X>
|
||||||
|
<Y>405</Y>
|
||||||
|
<W>40</W>
|
||||||
|
<H>40</H>
|
||||||
|
<Z>0</Z>
|
||||||
|
</RectArrowLeft>
|
||||||
|
<RectArrowRight>
|
||||||
|
<X>1170</X>
|
||||||
|
<Y>405</Y>
|
||||||
|
<W>40</W>
|
||||||
|
<H>40</H>
|
||||||
|
<Z>0</Z>
|
||||||
|
</RectArrowRight>
|
||||||
|
<Color Name="SelectSlideColor" />
|
||||||
|
<SelColor Name="SelectSlideSelColor" />
|
||||||
|
<ArrowColor Name="ArrowColor" />
|
||||||
|
<ArrowSelColor Name="ArrowSelColor" />
|
||||||
|
<TextColor Name="TextColor" />
|
||||||
|
<TextSelColor Name="TextSelColor" />
|
||||||
|
<TextH>27</TextH>
|
||||||
|
<TextRelativeX>50</TextRelativeX>
|
||||||
|
<TextRelativeY>0</TextRelativeY>
|
||||||
|
<TextMaxW>700</TextMaxW>
|
||||||
|
<TextFont>Outline</TextFont>
|
||||||
|
<TextStyle>Bold</TextStyle>
|
||||||
|
<NumVisible>1</NumVisible>
|
||||||
|
</SelectSlide>
|
||||||
|
<SelectSlide Name="SelectSlideCategory">
|
||||||
|
<Skin/>
|
||||||
|
<SkinArrowLeft>SelectSlideArrowLeft</SkinArrowLeft>
|
||||||
|
<SkinArrowRight>SelectSlideArrowRight</SkinArrowRight>
|
||||||
|
<SkinSelected>SelectSlide</SkinSelected>
|
||||||
|
<SkinArrowLeftSelected>SelectSlideArrowLeft</SkinArrowLeftSelected>
|
||||||
|
<SkinArrowRightSelected>SelectSlideArrowRight</SkinArrowRightSelected>
|
||||||
|
<Rect>
|
||||||
|
<X>500</X>
|
||||||
|
<Y>400</Y>
|
||||||
|
<W>700</W>
|
||||||
|
<H>50</H>
|
||||||
|
<Z>0</Z>
|
||||||
|
</Rect>
|
||||||
|
<RectArrowLeft>
|
||||||
|
<X>505</X>
|
||||||
|
<Y>405</Y>
|
||||||
|
<W>40</W>
|
||||||
|
<H>40</H>
|
||||||
|
<Z>0</Z>
|
||||||
|
</RectArrowLeft>
|
||||||
|
<RectArrowRight>
|
||||||
|
<X>1170</X>
|
||||||
|
<Y>405</Y>
|
||||||
|
<W>40</W>
|
||||||
|
<H>40</H>
|
||||||
|
<Z>0</Z>
|
||||||
|
</RectArrowRight>
|
||||||
|
<Color Name="SelectSlideColor" />
|
||||||
|
<SelColor Name="SelectSlideSelColor" />
|
||||||
|
<ArrowColor Name="ArrowColor" />
|
||||||
|
<ArrowSelColor Name="ArrowSelColor" />
|
||||||
|
<TextColor Name="TextColor" />
|
||||||
|
<TextSelColor Name="TextSelColor" />
|
||||||
|
<TextH>27</TextH>
|
||||||
|
<TextRelativeX>50</TextRelativeX>
|
||||||
|
<TextRelativeY>0</TextRelativeY>
|
||||||
|
<TextMaxW>700</TextMaxW>
|
||||||
|
<TextFont>Outline</TextFont>
|
||||||
|
<TextStyle>Bold</TextStyle>
|
||||||
|
<NumVisible>1</NumVisible>
|
||||||
|
</SelectSlide>
|
||||||
</SelectSlides>
|
</SelectSlides>
|
||||||
<SingNotes />
|
<SingNotes />
|
||||||
<NameSelections />
|
<NameSelections />
|
||||||
@@ -292,4 +488,4 @@
|
|||||||
<Playlists />
|
<Playlists />
|
||||||
<ParticleEffects />
|
<ParticleEffects />
|
||||||
<ScreenSettings />
|
<ScreenSettings />
|
||||||
</Screen>
|
</Screen>
|
||||||
@@ -29,6 +29,13 @@ using VocaluxeLib.Songs;
|
|||||||
|
|
||||||
namespace VocaluxeLib.PartyModes.ChallengeMedley
|
namespace VocaluxeLib.PartyModes.ChallengeMedley
|
||||||
{
|
{
|
||||||
|
public enum ESongSource
|
||||||
|
{
|
||||||
|
TR_ALLSONGS,
|
||||||
|
TR_CATEGORY,
|
||||||
|
TR_PLAYLIST
|
||||||
|
}
|
||||||
|
|
||||||
public class CResultTableRow : IComparable
|
public class CResultTableRow : IComparable
|
||||||
{
|
{
|
||||||
public int Position;
|
public int Position;
|
||||||
@@ -72,8 +79,6 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
public sealed class CPartyModeChallengeMedley : CPartyMode
|
public sealed class CPartyModeChallengeMedley : CPartyMode
|
||||||
// ReSharper restore ClassNeverInstantiated.Global
|
// ReSharper restore ClassNeverInstantiated.Global
|
||||||
{
|
{
|
||||||
private const int _NumSongs = 5;
|
|
||||||
|
|
||||||
public override int MinMics
|
public override int MinMics
|
||||||
{
|
{
|
||||||
get { return 1; }
|
get { return 1; }
|
||||||
@@ -107,6 +112,16 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
get { return MaxPlayers; }
|
get { return MaxPlayers; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int MinSongs
|
||||||
|
{
|
||||||
|
get { return 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int MaxSongs
|
||||||
|
{
|
||||||
|
get { return 10; }
|
||||||
|
}
|
||||||
|
|
||||||
private enum EStage
|
private enum EStage
|
||||||
{
|
{
|
||||||
Config,
|
Config,
|
||||||
@@ -121,6 +136,8 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
public int NumPlayerAtOnce;
|
public int NumPlayerAtOnce;
|
||||||
public int NumRounds;
|
public int NumRounds;
|
||||||
public List<int> ProfileIDs;
|
public List<int> ProfileIDs;
|
||||||
|
public int NumSongs;
|
||||||
|
public List<int> Songs;
|
||||||
|
|
||||||
public CChallengeRounds Rounds;
|
public CChallengeRounds Rounds;
|
||||||
public List<CResultTableRow> ResultTable;
|
public List<CResultTableRow> ResultTable;
|
||||||
@@ -129,6 +146,10 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
public int CurrentRoundNr;
|
public int CurrentRoundNr;
|
||||||
|
|
||||||
public int[] CatSongIndices;
|
public int[] CatSongIndices;
|
||||||
|
|
||||||
|
public ESongSource SongSource;
|
||||||
|
public int CategoryIndex;
|
||||||
|
public int PlaylistID;
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct SStats
|
private struct SStats
|
||||||
@@ -144,17 +165,7 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
|
|
||||||
public CPartyModeChallengeMedley(int id) : base(id)
|
public CPartyModeChallengeMedley(int id) : base(id)
|
||||||
{
|
{
|
||||||
_ScreenSongOptions.Selection.RandomOnly = false;
|
GameData = new SData {NumPlayer = 4, NumPlayerAtOnce = 2, NumRounds = 12, CurrentRoundNr = 1, ProfileIDs = new List<int>(), NumSongs = 5, Songs = new List<int>(), SongSource = ESongSource.TR_ALLSONGS, CatSongIndices = null, Results = null};
|
||||||
_ScreenSongOptions.Selection.PartyMode = true;
|
|
||||||
_ScreenSongOptions.Selection.CategoryChangeAllowed = true;
|
|
||||||
_ScreenSongOptions.Selection.NumJokers = new int[] {5, 5};
|
|
||||||
_ScreenSongOptions.Selection.TeamNames = new string[] {"foo", "bar"};
|
|
||||||
|
|
||||||
_ScreenSongOptions.Sorting.SearchString = String.Empty;
|
|
||||||
_ScreenSongOptions.Sorting.SearchActive = false;
|
|
||||||
_ScreenSongOptions.Sorting.DuetOptions = EDuetOptions.NoDuets;
|
|
||||||
|
|
||||||
GameData = new SData {NumPlayer = 4, NumPlayerAtOnce = 2, NumRounds = 12, CurrentRoundNr = 1, ProfileIDs = new List<int>(), CatSongIndices = null, Results = null};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Init()
|
public override bool Init()
|
||||||
@@ -163,14 +174,6 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
return false;
|
return false;
|
||||||
_Stage = EStage.Config;
|
_Stage = EStage.Config;
|
||||||
|
|
||||||
_ScreenSongOptions.Sorting.IgnoreArticles = EOffOn.TR_CONFIG_OFF;
|
|
||||||
_ScreenSongOptions.Sorting.SongSorting = ESongSorting.TR_CONFIG_NONE;
|
|
||||||
_ScreenSongOptions.Sorting.Tabs = EOffOn.TR_CONFIG_OFF;
|
|
||||||
_ScreenSongOptions.Selection.SongIndex = -1;
|
|
||||||
|
|
||||||
CBase.Songs.SortSongs(ESongSorting.TR_CONFIG_NONE, EOffOn.TR_CONFIG_OFF, EOffOn.TR_CONFIG_OFF, String.Empty, EDuetOptions.NoDuets);
|
|
||||||
CBase.Songs.SetCategory(0);
|
|
||||||
|
|
||||||
GameData.ResultTable = new List<CResultTableRow>();
|
GameData.ResultTable = new List<CResultTableRow>();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -259,79 +262,27 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
{
|
{
|
||||||
return _Screens["CPartyScreenChallengeMedleyConfig"];
|
return _Screens["CPartyScreenChallengeMedleyConfig"];
|
||||||
}
|
}
|
||||||
|
|
||||||
public override SScreenSongOptions GetScreenSongOptions()
|
public override SScreenSongOptions GetScreenSongOptions()
|
||||||
{
|
{
|
||||||
_ScreenSongOptions.Sorting.SongSorting = CBase.Config.GetSongSorting();
|
throw new ArgumentException("Not required!");
|
||||||
_ScreenSongOptions.Sorting.Tabs = CBase.Config.GetTabs();
|
|
||||||
_ScreenSongOptions.Sorting.IgnoreArticles = CBase.Config.GetIgnoreArticles();
|
|
||||||
|
|
||||||
return _ScreenSongOptions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReSharper disable RedundantAssignment
|
|
||||||
public override void OnSongChange(int songIndex, ref SScreenSongOptions screenSongOptions)
|
public override void OnSongChange(int songIndex, ref SScreenSongOptions screenSongOptions)
|
||||||
// ReSharper restore RedundantAssignment
|
|
||||||
{
|
{
|
||||||
_ScreenSongOptions.Selection.SongIndex = -1;
|
throw new ArgumentException("Not required!");
|
||||||
|
|
||||||
if (_ScreenSongOptions.Selection.SelectNextRandomSong && songIndex != -1)
|
|
||||||
{
|
|
||||||
_ScreenSongOptions.Selection.SelectNextRandomSong = false;
|
|
||||||
_CreateCatSongIndices();
|
|
||||||
|
|
||||||
if (GameData.CatSongIndices != null)
|
|
||||||
{
|
|
||||||
if (GameData.CatSongIndices[CBase.Songs.GetCurrentCategoryIndex()] == -1)
|
|
||||||
GameData.CatSongIndices[CBase.Songs.GetCurrentCategoryIndex()] = songIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
screenSongOptions = _ScreenSongOptions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReSharper disable RedundantAssignment
|
|
||||||
public override void OnCategoryChange(int categoryIndex, ref SScreenSongOptions screenSongOptions)
|
public override void OnCategoryChange(int categoryIndex, ref SScreenSongOptions screenSongOptions)
|
||||||
// ReSharper restore RedundantAssignment
|
|
||||||
{
|
{
|
||||||
if (GameData.CatSongIndices != null && categoryIndex != -1)
|
throw new ArgumentException("Not required!");
|
||||||
{
|
|
||||||
if (GameData.CatSongIndices[categoryIndex] == -1)
|
|
||||||
_ScreenSongOptions.Selection.SelectNextRandomSong = true;
|
|
||||||
else
|
|
||||||
_ScreenSongOptions.Selection.SongIndex = GameData.CatSongIndices[categoryIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GameData.CatSongIndices == null && categoryIndex != -1)
|
|
||||||
_ScreenSongOptions.Selection.SelectNextRandomSong = true;
|
|
||||||
|
|
||||||
if (categoryIndex == -1)
|
|
||||||
_ScreenSongOptions.Selection.RandomOnly = false;
|
|
||||||
|
|
||||||
if (_ScreenSongOptions.Sorting.Tabs == EOffOn.TR_CONFIG_OFF || categoryIndex != -1)
|
|
||||||
_ScreenSongOptions.Selection.RandomOnly = true;
|
|
||||||
|
|
||||||
screenSongOptions = _ScreenSongOptions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetSearchString(string searchString, bool visible)
|
public override void SetSearchString(string searchString, bool visible)
|
||||||
{
|
{
|
||||||
_ScreenSongOptions.Sorting.SearchString = searchString;
|
throw new ArgumentException("Not required!");
|
||||||
_ScreenSongOptions.Sorting.SearchActive = visible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void JokerUsed(int teamNr)
|
public override void JokerUsed(int teamNr) { }
|
||||||
{
|
|
||||||
if (_ScreenSongOptions.Selection.NumJokers == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (teamNr >= _ScreenSongOptions.Selection.NumJokers.Length)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_ScreenSongOptions.Selection.NumJokers[teamNr]--;
|
|
||||||
_ScreenSongOptions.Selection.RandomOnly = true;
|
|
||||||
_ScreenSongOptions.Selection.CategoryChangeAllowed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SongSelected(int songID) {}
|
public override void SongSelected(int songID) {}
|
||||||
|
|
||||||
@@ -343,16 +294,13 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
|
|
||||||
private bool _StartNextRound()
|
private bool _StartNextRound()
|
||||||
{
|
{
|
||||||
_ScreenSongOptions.Selection.RandomOnly = _ScreenSongOptions.Sorting.Tabs != EOffOn.TR_CONFIG_ON;
|
|
||||||
_ScreenSongOptions.Selection.CategoryChangeAllowed = _ScreenSongOptions.Sorting.Tabs == EOffOn.TR_CONFIG_ON;
|
|
||||||
_SetNumJokers();
|
|
||||||
_SetTeamNames();
|
_SetTeamNames();
|
||||||
GameData.CatSongIndices = null;
|
GameData.CatSongIndices = null;
|
||||||
|
|
||||||
return _RandomizeSongs();
|
return _PrepareGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _RandomizeSongs()
|
private bool _PrepareGame()
|
||||||
{
|
{
|
||||||
CBase.Game.Reset();
|
CBase.Game.Reset();
|
||||||
CBase.Game.ClearSongs();
|
CBase.Game.ClearSongs();
|
||||||
@@ -379,85 +327,50 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
#endregion PlayerNames
|
#endregion PlayerNames
|
||||||
|
|
||||||
#region SongQueue
|
#region SongQueue
|
||||||
if (CBase.Songs.GetNumSongsVisible() < _NumSongs)
|
for (int i = 0; i < GameData.NumSongs; i++)
|
||||||
CBase.Songs.ResetSongSung();
|
|
||||||
|
|
||||||
List<int> ids = new List<int>();
|
|
||||||
|
|
||||||
ReadOnlyCollection<CSong> visibleSongs = CBase.Songs.GetVisibleSongs();
|
|
||||||
if (visibleSongs.Count == 0)
|
|
||||||
{
|
{
|
||||||
CBase.Log.LogError("CPartyChallengeMedleyMode Error: There are no songs!");
|
if (GameData.Songs.Count == 0)
|
||||||
return false;
|
_UpdateSongList();
|
||||||
}
|
CBase.Game.AddSong(GameData.Songs[0], EGameMode.TR_GAMEMODE_MEDLEY);
|
||||||
|
GameData.Songs.RemoveAt(0);
|
||||||
//Calc avarage sing-count
|
|
||||||
int totalCounts = visibleSongs.Sum(song => song.NumPlayedSession);
|
|
||||||
int averageCount = totalCounts / visibleSongs.Count;
|
|
||||||
|
|
||||||
// ReSharper disable LoopCanBeConvertedToQuery
|
|
||||||
foreach (CSong song in visibleSongs)
|
|
||||||
{
|
|
||||||
foreach (EGameMode mode in song.AvailableGameModes)
|
|
||||||
{
|
|
||||||
if (mode == EGameMode.TR_GAMEMODE_MEDLEY && song.NumPlayedSession <= averageCount)
|
|
||||||
ids.Add(song.ID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ReSharper restore LoopCanBeConvertedToQuery
|
|
||||||
|
|
||||||
if (ids.Count == 0)
|
|
||||||
{
|
|
||||||
CBase.Log.LogError("CPartyChallengeMedleyMode Error: There are no medley songs!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int s = 0;
|
|
||||||
while (s < _NumSongs && ids.Count > 0)
|
|
||||||
{
|
|
||||||
int songID = ids[CBase.Game.GetRandom(ids.Count)];
|
|
||||||
CBase.Game.AddSong(songID, EGameMode.TR_GAMEMODE_MEDLEY);
|
|
||||||
CBase.Songs.AddPartySongSung(songID);
|
|
||||||
ids.Remove(songID);
|
|
||||||
s++;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
#endregion SongQueue
|
#endregion SongQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _SetNumJokers()
|
private void _UpdateSongList()
|
||||||
{
|
{
|
||||||
switch (GameData.NumPlayerAtOnce)
|
if (GameData.Songs.Count > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (GameData.SongSource)
|
||||||
{
|
{
|
||||||
case 1:
|
case ESongSource.TR_PLAYLIST:
|
||||||
_ScreenSongOptions.Selection.NumJokers = new int[] {10};
|
for (int i = 0; i < CBase.Playlist.GetSongCount(GameData.PlaylistID); i++)
|
||||||
|
{
|
||||||
|
int id = CBase.Playlist.GetSong(GameData.PlaylistID, i).SongID;
|
||||||
|
if (CBase.Songs.GetSongByID(id).AvailableGameModes.Contains(EGameMode.TR_GAMEMODE_MEDLEY))
|
||||||
|
GameData.Songs.Add(id);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case ESongSource.TR_ALLSONGS:
|
||||||
_ScreenSongOptions.Selection.NumJokers = new int[] {5, 5};
|
ReadOnlyCollection<CSong> avSongs = CBase.Songs.GetSongs();
|
||||||
|
GameData.Songs.AddRange(avSongs.Where(song => song.AvailableGameModes.Contains(EGameMode.TR_GAMEMODE_MEDLEY)).Select(song => song.ID));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case ESongSource.TR_CATEGORY:
|
||||||
_ScreenSongOptions.Selection.NumJokers = new int[] {4, 4, 4};
|
CBase.Songs.SetCategory(GameData.CategoryIndex);
|
||||||
break;
|
avSongs = CBase.Songs.GetVisibleSongs();
|
||||||
|
GameData.Songs.AddRange(avSongs.Where(song => song.AvailableGameModes.Contains(EGameMode.TR_GAMEMODE_MEDLEY)).Select(song => song.ID));
|
||||||
|
|
||||||
case 4:
|
CBase.Songs.SetCategory(-1);
|
||||||
_ScreenSongOptions.Selection.NumJokers = new int[] {3, 3, 3, 3};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5:
|
|
||||||
_ScreenSongOptions.Selection.NumJokers = new int[] {2, 2, 2, 2, 2};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 6:
|
|
||||||
_ScreenSongOptions.Selection.NumJokers = new int[] {2, 2, 2, 2, 2, 2};
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
_ScreenSongOptions.Selection.NumJokers = new int[] {5, 5};
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
GameData.Songs.Shuffle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void _SetTeamNames()
|
private void _SetTeamNames()
|
||||||
{
|
{
|
||||||
CProfile[] profiles = CBase.Profiles.GetProfiles();
|
CProfile[] profiles = CBase.Profiles.GetProfiles();
|
||||||
|
|||||||
@@ -16,7 +16,10 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using VocaluxeLib.Songs;
|
||||||
|
|
||||||
namespace VocaluxeLib.PartyModes.ChallengeMedley
|
namespace VocaluxeLib.PartyModes.ChallengeMedley
|
||||||
{
|
{
|
||||||
@@ -27,23 +30,28 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
// Version number for theme files. Increment it, if you've changed something on the theme files!
|
// Version number for theme files. Increment it, if you've changed something on the theme files!
|
||||||
protected override int _ScreenVersion
|
protected override int _ScreenVersion
|
||||||
{
|
{
|
||||||
get { return 1; }
|
get { return 2; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private const string _SelectSlideNumPlayers = "SelectSlideNumPlayers";
|
private const string _SelectSlideNumPlayers = "SelectSlideNumPlayers";
|
||||||
private const string _SelectSlideNumMics = "SelectSlideNumMics";
|
private const string _SelectSlideNumMics = "SelectSlideNumMics";
|
||||||
private const string _SelectSlideNumRounds = "SelectSlideNumRounds";
|
private const string _SelectSlideNumRounds = "SelectSlideNumRounds";
|
||||||
|
private const string _SelectSlideNumSongs = "SelectSlideNumSongs";
|
||||||
|
private const string _SelectSlideSongSource = "SelectSlideSongSource";
|
||||||
|
private const string _SelectSlidePlaylist = "SelectSlidePlaylist";
|
||||||
|
private const string _SelectSlideCategory = "SelectSlideCategory";
|
||||||
private const string _ButtonNext = "ButtonNext";
|
private const string _ButtonNext = "ButtonNext";
|
||||||
private const string _ButtonBack = "ButtonBack";
|
private const string _ButtonBack = "ButtonBack";
|
||||||
|
|
||||||
private const int _MaxNumRounds = 100;
|
private const int _MaxNumRounds = 100;
|
||||||
private int _RoundSteps = 1;
|
private int _RoundSteps = 1;
|
||||||
|
private bool _ConfigOk;
|
||||||
|
|
||||||
public override void Init()
|
public override void Init()
|
||||||
{
|
{
|
||||||
base.Init();
|
base.Init();
|
||||||
|
|
||||||
_ThemeSelectSlides = new string[] {_SelectSlideNumPlayers, _SelectSlideNumMics, _SelectSlideNumRounds};
|
_ThemeSelectSlides = new string[] {_SelectSlideNumPlayers, _SelectSlideNumMics, _SelectSlideNumRounds, _SelectSlideNumSongs, _SelectSlideSongSource, _SelectSlidePlaylist, _SelectSlideCategory};
|
||||||
_ThemeButtons = new string[] {_ButtonNext, _ButtonBack};
|
_ThemeButtons = new string[] {_ButtonNext, _ButtonBack};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,10 +116,12 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
base.OnShow();
|
base.OnShow();
|
||||||
|
|
||||||
_RebuildSlides();
|
_RebuildSlides();
|
||||||
|
_UpdateSlides();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool UpdateGame()
|
public override bool UpdateGame()
|
||||||
{
|
{
|
||||||
|
_Buttons[_ButtonNext].Visible = _ConfigOk;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +133,35 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
_SelectSlides[_SelectSlideNumPlayers].AddValue(i.ToString());
|
_SelectSlides[_SelectSlideNumPlayers].AddValue(i.ToString());
|
||||||
_SelectSlides[_SelectSlideNumPlayers].Selection = _PartyMode.GameData.NumPlayer - _PartyMode.MinPlayers;
|
_SelectSlides[_SelectSlideNumPlayers].Selection = _PartyMode.GameData.NumPlayer - _PartyMode.MinPlayers;
|
||||||
|
|
||||||
_UpdateMicsAtOnce();
|
_SelectSlides[_SelectSlideNumSongs].Clear();
|
||||||
|
for (int i = _PartyMode.MinSongs; i <= _PartyMode.MaxSongs; i++)
|
||||||
|
_SelectSlides[_SelectSlideNumSongs].AddValue(i.ToString());
|
||||||
|
_SelectSlides[_SelectSlideNumSongs].Selection = _PartyMode.GameData.NumSongs - _PartyMode.MinSongs;
|
||||||
|
|
||||||
|
_SelectSlides[_SelectSlideSongSource].Clear();
|
||||||
|
_SelectSlides[_SelectSlideSongSource].SetValues<ESongSource>((int)_PartyMode.GameData.SongSource);
|
||||||
|
|
||||||
|
List<string> playlists = CBase.Playlist.GetNames();
|
||||||
|
_SelectSlides[_SelectSlidePlaylist].Clear();
|
||||||
|
for (int i = 0; i < playlists.Count; i++)
|
||||||
|
{
|
||||||
|
string value = playlists[i] + " (" + CBase.Playlist.GetSongCount(i) + " " + CBase.Language.Translate("TR_SONGS", PartyModeID) + ")";
|
||||||
|
_SelectSlides[_SelectSlidePlaylist].AddValue(value);
|
||||||
|
}
|
||||||
|
_SelectSlides[_SelectSlidePlaylist].Selection = _PartyMode.GameData.PlaylistID;
|
||||||
|
_SelectSlides[_SelectSlidePlaylist].Visible = _PartyMode.GameData.SongSource == ESongSource.TR_PLAYLIST;
|
||||||
|
|
||||||
|
_SelectSlides[_SelectSlideCategory].Clear();
|
||||||
|
for (int i = 0; i < CBase.Songs.GetNumCategories(); i++)
|
||||||
|
{
|
||||||
|
CCategory cat = CBase.Songs.GetCategory(i);
|
||||||
|
string value = cat.Name + " (" + cat.GetNumSongsNotSung() + " " + CBase.Language.Translate("TR_SONGS", PartyModeID) + ")";
|
||||||
|
_SelectSlides[_SelectSlideCategory].AddValue(value);
|
||||||
|
}
|
||||||
|
_SelectSlides[_SelectSlideCategory].Selection = _PartyMode.GameData.CategoryIndex;
|
||||||
|
_SelectSlides[_SelectSlideCategory].Visible = _PartyMode.GameData.SongSource == ESongSource.TR_CATEGORY;
|
||||||
|
|
||||||
|
_UpdateMicsAtOnce();
|
||||||
_SetRoundSteps();
|
_SetRoundSteps();
|
||||||
_UpdateSlideRounds();
|
_UpdateSlideRounds();
|
||||||
}
|
}
|
||||||
@@ -135,6 +173,10 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
_PartyMode.GameData.NumPlayer = _SelectSlides[_SelectSlideNumPlayers].Selection + _PartyMode.MinPlayers;
|
_PartyMode.GameData.NumPlayer = _SelectSlides[_SelectSlideNumPlayers].Selection + _PartyMode.MinPlayers;
|
||||||
_PartyMode.GameData.NumPlayerAtOnce = _SelectSlides[_SelectSlideNumMics].Selection + _PartyMode.MinPlayers;
|
_PartyMode.GameData.NumPlayerAtOnce = _SelectSlides[_SelectSlideNumMics].Selection + _PartyMode.MinPlayers;
|
||||||
_PartyMode.GameData.NumRounds = (_SelectSlides[_SelectSlideNumRounds].Selection + 1) * _RoundSteps;
|
_PartyMode.GameData.NumRounds = (_SelectSlides[_SelectSlideNumRounds].Selection + 1) * _RoundSteps;
|
||||||
|
_PartyMode.GameData.NumSongs = _SelectSlides[_SelectSlideNumSongs].Selection + _PartyMode.MinSongs;
|
||||||
|
_PartyMode.GameData.SongSource = (ESongSource)_SelectSlides[_SelectSlideSongSource].Selection;
|
||||||
|
_PartyMode.GameData.PlaylistID = _SelectSlides[_SelectSlidePlaylist].Selection;
|
||||||
|
_PartyMode.GameData.CategoryIndex = _SelectSlides[_SelectSlideCategory].Selection;
|
||||||
|
|
||||||
_UpdateMicsAtOnce();
|
_UpdateMicsAtOnce();
|
||||||
_SetRoundSteps();
|
_SetRoundSteps();
|
||||||
@@ -147,6 +189,64 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
_PartyMode.GameData.NumRounds = num;
|
_PartyMode.GameData.NumRounds = num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_PartyMode.GameData.SongSource == ESongSource.TR_PLAYLIST)
|
||||||
|
{
|
||||||
|
if (CBase.Playlist.GetNumPlaylists() > 0)
|
||||||
|
{
|
||||||
|
if (CBase.Playlist.GetSongCount(_PartyMode.GameData.PlaylistID) > 0)
|
||||||
|
{
|
||||||
|
_ConfigOk = false;
|
||||||
|
for (int i = 0; i < CBase.Playlist.GetSongCount(_PartyMode.GameData.PlaylistID); i++)
|
||||||
|
{
|
||||||
|
int id = CBase.Playlist.GetSong(_PartyMode.GameData.PlaylistID, i).SongID;
|
||||||
|
_ConfigOk = CBase.Songs.GetSongByID(id).AvailableGameModes.Any(mode => mode == EGameMode.TR_GAMEMODE_MEDLEY);
|
||||||
|
if (_ConfigOk)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_ConfigOk = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_ConfigOk = false;
|
||||||
|
}
|
||||||
|
if (_PartyMode.GameData.SongSource == ESongSource.TR_CATEGORY)
|
||||||
|
{
|
||||||
|
if (CBase.Songs.GetNumCategories() == 0)
|
||||||
|
_ConfigOk = false;
|
||||||
|
else if (CBase.Songs.GetNumSongsNotSungInCategory(_PartyMode.GameData.CategoryIndex) <= 0)
|
||||||
|
_ConfigOk = false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CBase.Songs.SetCategory(_PartyMode.GameData.CategoryIndex);
|
||||||
|
_ConfigOk = false;
|
||||||
|
foreach (CSong song in CBase.Songs.GetVisibleSongs())
|
||||||
|
{
|
||||||
|
_ConfigOk = song.AvailableGameModes.Any(mode => mode == EGameMode.TR_GAMEMODE_MEDLEY);
|
||||||
|
if (_ConfigOk)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
CBase.Songs.SetCategory(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_PartyMode.GameData.SongSource == ESongSource.TR_ALLSONGS)
|
||||||
|
{
|
||||||
|
if (CBase.Songs.GetNumSongs() > 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < CBase.Songs.GetNumSongs(); i++)
|
||||||
|
{
|
||||||
|
_ConfigOk = CBase.Songs.GetSongByID(i).AvailableGameModes.Any(mode => mode == EGameMode.TR_GAMEMODE_MEDLEY);
|
||||||
|
if (_ConfigOk)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_ConfigOk = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_SelectSlides[_SelectSlideCategory].Visible = _PartyMode.GameData.SongSource == ESongSource.TR_CATEGORY;
|
||||||
|
_SelectSlides[_SelectSlidePlaylist].Visible = _PartyMode.GameData.SongSource == ESongSource.TR_PLAYLIST;
|
||||||
|
|
||||||
_UpdateSlideRounds();
|
_UpdateSlideRounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user