Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/TeamModePlayerSelect #158

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions PugSharp.Config/TeamMode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ public enum TeamMode

// Scramble Teams after all players are joined
Scramble,

// Player Selects which Team to join
PlayerSelect
}
95 changes: 94 additions & 1 deletion PugSharp.Match/Match.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ private void InitializeStateMachine()
_MatchStateMachine.Configure(MatchState.DefineTeams)
.Permit(MatchCommand.TeamsDefined, MatchState.MapVote)
.OnEntry(ContinueIfDefault)
.OnEntry(ContinueIfPlayerSelect)
.OnEntry(ScrambleTeams);

_MatchStateMachine.Configure(MatchState.MapVote)
Expand Down Expand Up @@ -215,6 +216,14 @@ private void ContinueIfDefault()
}
}

private void ContinueIfPlayerSelect()
{
if (MatchInfo.Config.TeamMode == Config.TeamMode.PlayerSelect)
{
TryFireState(MatchCommand.TeamsDefined);
}
}

private void StartWarmup()
{
_CsServer.LoadAndExecuteConfig("warmup.cfg");
Expand Down Expand Up @@ -649,7 +658,7 @@ private void VoteTimer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)

private void ReadyReminderTimer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
{
if (!_ReadyReminderTimer.Enabled)
if (MatchInfo.Config.TeamMode != Config.TeamMode.PlayerSelect && !_ReadyReminderTimer.Enabled)
{
return;
}
Expand All @@ -658,6 +667,25 @@ private void ReadyReminderTimer_Elapsed(object? sender, System.Timers.ElapsedEve
{
try
{
if (MatchInfo.Config.TeamMode == Config.TeamMode.PlayerSelect)
{
_Logger.LogInformation("TeamReminder Elapsed");
foreach (var player in AllMatchPlayers)
{
var matchTeam = GetMatchTeam(player.Player.Team);
if (player.Player.Team == Team.Terrorist || player.Player.Team == Team.CounterTerrorist)
{
var teamMessage = _TextHelper.GetText(nameof(Resources.PugSharp_Match_TeamReminder), matchTeam?.TeamConfig.Name);
player.Player.PrintToChat(teamMessage);
}
}
}

if (!_ReadyReminderTimer.Enabled)
{
return;
}

_Logger.LogInformation("ReadyReminder Elapsed");
var readyPlayerIds = AllMatchPlayers.Where(p => p.IsReady).Select(x => x.Player.SteamID).ToList();
var notReadyPlayers = _CsServer.LoadAllPlayers().Where(p => !readyPlayerIds.Contains(p.SteamID));
Expand Down Expand Up @@ -937,8 +965,61 @@ private MatchPlayer GetMatchPlayer(ulong steamID)
return AllMatchPlayers.First(x => x.Player.SteamID == steamID);
}

public bool PlayerIsReady(ulong steamID)
{
var matchPlayer = AllMatchPlayers.FirstOrDefault(x => x.Player.SteamID == steamID);
return matchPlayer != null && matchPlayer.IsReady;
}

#region Match Functions

private bool TryAddPlayerToCurrentTeam(IPlayer player)
{
var matchPlayer = MatchInfo.MatchTeam1.Players.Any(x => x.Player.SteamID == player.SteamID) || MatchInfo.MatchTeam2.Players.Any(x => x.Player.SteamID == player.SteamID) ? GetMatchPlayer(player.SteamID) : null;
if (matchPlayer == null) {
matchPlayer = new MatchPlayer(player);
}
else {
// Remove the player from the match
MatchInfo.MatchTeam1.Players.Remove(matchPlayer);
MatchInfo.MatchTeam2.Players.Remove(matchPlayer);
}

// Add them back to the match
bool? isTeam1 = null;
if (MatchInfo.MatchTeam1.CurrentTeamSite == Team.None && MatchInfo.MatchTeam2.CurrentTeamSite == Team.None)
{
isTeam1 = player.Team == Team.Terrorist;
}
else if (MatchInfo.MatchTeam1.CurrentTeamSite != Team.None)
{
isTeam1 = MatchInfo.MatchTeam1.CurrentTeamSite == player.Team;
}
else if (MatchInfo.MatchTeam2.CurrentTeamSite != Team.None)
{
isTeam1 = MatchInfo.MatchTeam2.CurrentTeamSite != player.Team;
}

if (isTeam1 == null)
{
_Logger.LogInformation("Could not add player to match", player.SteamID);
return false;
}
else if (isTeam1.HasValue && isTeam1.Value)
TheR00st3r marked this conversation as resolved.
Show resolved Hide resolved
{
MatchInfo.MatchTeam1.Players.Add(matchPlayer);
}
else
{
MatchInfo.MatchTeam2.Players.Add(matchPlayer);
}

// Console.WriteLine("Team 1: " + string.Join(',', MatchInfo.MatchTeam1.Players.Select(p => $"{p.Player.PlayerName}").ToList()));
// Console.WriteLine("Team 2: " + string.Join(',', MatchInfo.MatchTeam2.Players.Select(p => $"{p.Player.PlayerName}").ToList()));

return true;
}

public bool TryAddPlayer(IPlayer player)
{
if (!PlayerBelongsToMatch(player.SteamID))
Expand All @@ -947,6 +1028,12 @@ public bool TryAddPlayer(IPlayer player)
return false;
}

if (MatchInfo.Config.TeamMode == Config.TeamMode.PlayerSelect)
{
// Quicker to just remove them and add them back, rather than check whether they are already in the match
return TryAddPlayerToCurrentTeam(player);
}

if (MatchInfo.MatchTeam1.Players.Any(x => x.Player.SteamID == player.SteamID)
|| MatchInfo.MatchTeam2.Players.Any(x => x.Player.SteamID == player.SteamID))
{
Expand Down Expand Up @@ -1036,6 +1123,12 @@ public void TogglePlayerIsReady(IPlayer player)
}

var matchPlayer = GetMatchPlayer(player.SteamID);
if (matchPlayer.Player.Team != Team.Terrorist && matchPlayer.Player.Team != Team.CounterTerrorist)
{
player.PrintToChat(_TextHelper.GetText(nameof(Resources.PugSharp_Match_Error_NoReadyExpected)));
return;
}

matchPlayer.IsReady = !matchPlayer.IsReady;

var readyPlayers = MatchInfo.MatchTeam1.Players.Count(x => x.IsReady) + MatchInfo.MatchTeam2.Players.Count(x => x.IsReady);
Expand Down
20 changes: 19 additions & 1 deletion PugSharp.Translation/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions PugSharp.Translation/Properties/Resources.br.resx
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@
<data name="PugSharp.Match.Info.WaitingForAllPlayers" xml:space="preserve">
<value>Aguardando todos os jogadores estarem prontos.</value>
</data>
<data name="PugSharp.Match.TeamReminder" xml:space="preserve">
<value>Você está atualmente na equipe: **{0:teamName}**.</value>
</data>
<data name="PugSharp.Match.RemindReady" xml:space="preserve">
<value>Você !!não!! está pronto!! Digite `!ready` se você está pronto.</value>
</data>
Expand All @@ -256,6 +259,9 @@
<data name="PugSharp.Match.VoteTeamMenuHeader" xml:space="preserve">
<value>Escolha o lado inicial com (`!stay` ou `!switch`)</value>
</data>
<data name="PugSharp_Match_VoteConfirmTeamHeader" xml:space="preserve">
<value>Escolha a equipe correta:</value>
</data>
<data name="PugSharp.Match.WaitForOtherTeam" xml:space="preserve">
<value>Aguardando o voto da outra equipe!</value>
</data>
Expand Down
3 changes: 3 additions & 0 deletions PugSharp.Translation/Properties/Resources.da.resx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@
<data name="PugSharp.Command.ConfigLoaded" xml:space="preserve">
<value>Kampconfig loadet!</value>
</data>
<data name="PugSharp.Match.TeamReminder" xml:space="preserve">
<value>Je zit momenteel in Team: **{0:teamName}**.</value>
</data>
<data name="PugSharp.Command.CreatingMatchPlayersPerTeam" xml:space="preserve">
<value>`!spillereperteam &lt;players&gt;` for at sætte antal spillere per hold!</value>
</data>
Expand Down
6 changes: 6 additions & 0 deletions PugSharp.Translation/Properties/Resources.de.resx
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@
<data name="PugSharp.Match.Error.UnknownMapNumber" xml:space="preserve">
<value>Die Karte mit der Kartennummer **{0:mapNumber}** ist nicht verfügbar!</value>
</data>
<data name="PugSharp.Match.TeamReminder" xml:space="preserve">
<value>Sie sind derzeit im Team: **{0:teamName}**.</value>
</data>
<data name="PugSharp.Match.RemindReady" xml:space="preserve">
<value>Du bist !!nicht!! bereit! Schreibe `!ready` in den chat wenn du bereit bist.</value>
</data>
Expand All @@ -177,6 +180,9 @@
<data name="PugSharp.Match.VoteTeamMenuHeader" xml:space="preserve">
<value>Wähle die Startseite (`!stay` oder`!switch`)</value>
</data>
<data name="PugSharp_Match_VoteConfirmTeamHeader" xml:space="preserve">
<value>Wählen Sie das richtige Team:</value>
</data>
<data name="PugSharp.Match.VoteMapMenuHeader" xml:space="preserve">
<value>Stimme ab um eine Karte zu bannen: schreibe `!&lt;Kartennummer&gt;` in den Chat</value>
</data>
Expand Down
6 changes: 6 additions & 0 deletions PugSharp.Translation/Properties/Resources.es.resx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
<data name="PugSharp.Match.VoteTeamMenuHeader" xml:space="preserve">
<value>Elige bando inicial:</value>
</data>
<data name="PugSharp_Match_VoteConfirmTeamHeader" xml:space="preserve">
<value>Elige el equipo correcto:</value>
</data>
<data name="PugSharp.Match.VoteMapMenuHeader" xml:space="preserve">
<value>Votación para banear mapa: escribe `!&lt;mapnumber&gt;`</value>
</data>
Expand All @@ -88,6 +91,9 @@
<data name="PugSharp.Match.Info.WaitingForAllPlayers" xml:space="preserve">
<value>Esperando a que todos los jugadores estén preparados.</value>
</data>
<data name="PugSharp.Match.TeamReminder" xml:space="preserve">
<value>Actualmente estás en el equipo: **{0:teamName}**.</value>
</data>
<data name="PugSharp.Match.Info.IsLive" xml:space="preserve">
<value>La partida está **EN VIVO**</value>
</data>
Expand Down
3 changes: 3 additions & 0 deletions PugSharp.Translation/Properties/Resources.ja.resx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@
<data name="PugSharp.Command.ChangedMaxRounds" xml:space="preserve">
<value>最大ラウンド数を{0:oldMaxRounds}から{1:maxRounds}に変更</value>
</data>
<data name="PugSharp.Match.TeamReminder" xml:space="preserve">
<value>あなたは現在次のチームに所属しています: **{0:teamName}**.</value>
</data>
<data name="PugSharp.Command.CreatingMatchStartMatch" xml:space="preserve">
<value>`!startmatch`で試合を開始できます!</value>
</data>
Expand Down
3 changes: 3 additions & 0 deletions PugSharp.Translation/Properties/Resources.ko.resx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="PugSharp.Match.TeamReminder" xml:space="preserve">
<value>귀하는 현재 다음 팀에 속해 있습니다: **{0:teamName}**.</value>
</data>
<data name="PugSharp.Hello" xml:space="preserve">
<value>**{0:playerName}** 안녕하세요,
매치에 오신걸 환영합니다 {1:matchId}</value>
Expand Down
6 changes: 6 additions & 0 deletions PugSharp.Translation/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@
<data name="PugSharp.Match.Info.WaitingForAllPlayers" xml:space="preserve">
<value>Waiting for all players to be ready.</value>
</data>
<data name="PugSharp.Match.TeamReminder" xml:space="preserve">
<value>You are currently on Team: **{0:teamName}**.</value>
</data>
<data name="PugSharp.Match.RemindReady" xml:space="preserve">
<value>You are !!not!! ready! Type `!ready` if you are ready.</value>
</data>
Expand All @@ -315,6 +318,9 @@
<data name="PugSharp.Match.VoteTeamMenuHeader" xml:space="preserve">
<value>Choose starting side (`!stay` or `!switch`)</value>
</data>
<data name="PugSharp.Match.VoteConfirmTeamHeader" xml:space="preserve">
<value>Escolha a equipe correta:</value>
</data>
<data name="PugSharp.Match.WaitForOtherTeam" xml:space="preserve">
<value>Waiting for other Team to vote!</value>
</data>
Expand Down
35 changes: 32 additions & 3 deletions PugSharp/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,18 @@ private async void CheckMatchPlayerTeam(CCSPlayerController playerController, in

if (_Match.CurrentState == MatchState.WaitingForPlayersConnectedReady || _Match.CurrentState == MatchState.WaitingForPlayersReady)
{
// Do not enforce locked teams during warmup for TeamMode: PlayerSelect
if (_Match.MatchInfo.Config.TeamMode == TeamMode.PlayerSelect)
{
// If player is already on team, make sure the match teams are updated
if (_Match.PlayerIsReady(playerController.SteamID) && (team == (int)Match.Contract.Team.Terrorist || team == (int)Match.Contract.Team.CounterTerrorist))
{
_Match.TryAddPlayer(new Player(playerController.SteamID));
}

return;
}

var configTeam = _Match.GetPlayerTeam(playerController.SteamID);
var steamId = playerController.SteamID;
var userName = playerController.PlayerName;
Expand Down Expand Up @@ -323,10 +335,15 @@ private void OnMapStartHandler(string mapName)
{
if (_Match != null)
{
_Dispatcher.NextFrame(() =>
if (_Match.CurrentState is MatchState.WaitingForPlayersConnectedReady or MatchState.WaitingForPlayersReady)
{
SetMatchVariable();
});
_CsServer.LoadAndExecuteConfig("warmup.cfg");

_Dispatcher.NextFrame(() =>
{
SetMatchVariable();
});
}
}
}

Expand Down Expand Up @@ -1956,6 +1973,18 @@ private void SetMatchVariable()
_CsServer.ExecuteCommand($"mp_teamname_2 {tTeam.TeamConfig.Name}");
_CsServer.ExecuteCommand($"mp_teamflag_2 {tTeam.TeamConfig.Flag}");

// Allow players to select their team
if (_Match.MatchInfo.Config.TeamMode == TeamMode.PlayerSelect)
{
_CsServer.UpdateConvar("sv_disable_teamselect_menu", false);
_CsServer.UpdateConvar("sv_human_autojoin_team", (int)Match.Contract.Team.None);
}
else
{
_CsServer.UpdateConvar("sv_disable_teamselect_menu", true);
_CsServer.UpdateConvar("sv_human_autojoin_team", (int)Match.Contract.Team.Terrorist);
}

_Logger.LogInformation("Set match variables done");
}

Expand Down