예제 #1
0
        public virtual async Task PickPlayersAsync(params SocketGuildUser[] users)
        {
            using (var db = new Database())
            {
                var lobby = db.Lobbies.FirstOrDefault(x => x.ChannelId == Context.Channel.Id);
                if (lobby == null)
                {
                    await SimpleEmbedAsync("Channel is not a lobby.", Color.Red);

                    return;
                }

                var latestGame = db.GameResults.Where(x => x.LobbyId == Context.Channel.Id).OrderByDescending(x => x.GameId).FirstOrDefault();
                if (latestGame == null)
                {
                    await SimpleEmbedAsync("There is no game to pick for.", Color.DarkBlue);

                    return;
                }

                if (latestGame.GameState != GameState.Picking)
                {
                    await SimpleEmbedAsync("Lobby is currently not picking teams.", Color.DarkBlue);

                    return;
                }

                var queue = db.GetQueuedPlayers(Context.Guild.Id, Context.Channel.Id).ToList();
                var team1 = db.GetTeamPlayers(Context.Guild.Id, Context.Channel.Id, latestGame.GameId, 1).ToArray();
                var team2 = db.GetTeamPlayers(Context.Guild.Id, Context.Channel.Id, latestGame.GameId, 2).ToArray();
                var cap1  = db.GetTeamCaptain(Context.Guild.Id, Context.Channel.Id, latestGame.GameId, 1);
                var cap2  = db.GetTeamCaptain(Context.Guild.Id, Context.Channel.Id, latestGame.GameId, 2);

                if (cap1 != null)
                {
                    var match = queue.FirstOrDefault(x => x.UserId == cap1.UserId);
                    if (match != null)
                    {
                        db.QueuedPlayers.Remove(match);
                        queue.Remove(match);
                    }
                }
                if (cap2 != null)
                {
                    var match = queue.FirstOrDefault(x => x.UserId == cap2.UserId);
                    if (match != null)
                    {
                        db.QueuedPlayers.Remove(match);
                        queue.Remove(match);
                    }
                }

                //Ensure the player is eligible to join a team
                if (users.Any(user => !queue.Any(x => x.UserId == user.Id)))
                {
                    if (users.Length == 2)
                    {
                        await SimpleEmbedAndDeleteAsync("A selected player is not queued for this game.", Color.Red);
                    }
                    else
                    {
                        await SimpleEmbedAndDeleteAsync("Player is not queued for this game.", Color.Red);
                    }
                    return;
                }
                else if (users.Any(u => team1.Any(x => x.UserId == u.Id) || team2.Any(x => x.UserId == u.Id)))
                {
                    if (users.Length == 2)
                    {
                        await SimpleEmbedAndDeleteAsync("A selected player is already picked for a team.", Color.Red);
                    }
                    else
                    {
                        await SimpleEmbedAndDeleteAsync("Player is already picked for a team.", Color.Red);
                    }
                    return;
                }
                else if (users.Any(u => u.Id == cap1.UserId || u.Id == cap2.UserId))
                {
                    await SimpleEmbedAndDeleteAsync("You cannot select a captain for picking.", Color.Red);

                    return;
                }

                string pickResponse = null;
                if (latestGame.PickOrder == CaptainPickOrder.PickTwo)
                {
                    var res = await LobbyService.PickTwoAsync(db, Context, lobby, latestGame, users, cap1, cap2);

                    latestGame   = res.Item1;
                    pickResponse = res.Item2;
                }
                else if (latestGame.PickOrder == CaptainPickOrder.PickOne)
                {
                    var res = await LobbyService.PickOneAsync(db, Context, latestGame, users, cap1, cap2);

                    latestGame   = res.Item1;
                    pickResponse = res.Item2;
                }
                else
                {
                    await SimpleEmbedAsync("There was an error picking your game.", Color.DarkRed);

                    return;
                }

                if (latestGame == null)
                {
                    return;
                }

                db.SaveChanges();
                var allQueued = db.GetTeamFull(latestGame, 1).Union(db.GetTeamFull(latestGame, 2)).ToHashSet();
                latestGame.Picks++;
                db.Update(latestGame);
                var remaining = queue.Where(x => !allQueued.Contains(x.UserId)).ToArray();
                if (remaining.Length == 1)
                {
                    var lastUser   = remaining.First();
                    var allMembers = db.TeamPlayers.Where(x => x.GuildId == Context.Guild.Id && x.ChannelId == Context.Channel.Id && x.GameNumber == latestGame.GameId);

                    //More players in team 1 so add user to team 2
                    if (allMembers.Count(x => x.TeamNumber == 1) > allMembers.Count(x => x.TeamNumber == 2))
                    {
                        db.TeamPlayers.Add(new TeamPlayer
                        {
                            GuildId    = Context.Guild.Id,
                            ChannelId  = Context.Channel.Id,
                            UserId     = lastUser.UserId,
                            GameNumber = latestGame.GameId,
                            TeamNumber = 2
                        });
                    }
                    else
                    {
                        db.TeamPlayers.Add(new TeamPlayer
                        {
                            GuildId    = Context.Guild.Id,
                            ChannelId  = Context.Channel.Id,
                            UserId     = lastUser.UserId,
                            GameNumber = latestGame.GameId,
                            TeamNumber = 1
                        });
                    }
                    allQueued.Add(lastUser.UserId);
                }

                if (allQueued.Count >= lobby.PlayersPerTeam * 2)
                {
                    //Teams have been filled.
                    latestGame.GameState = GameState.Undecided;
                    db.QueuedPlayers.RemoveRange(queue);
                    db.SaveChanges();

                    var res = GameService.GetGameMessage(latestGame, $"Game #{latestGame.GameId} Started",
                                                         GameFlag.gamestate,
                                                         GameFlag.lobby,
                                                         GameFlag.map,
                                                         GameFlag.usermentions,
                                                         GameFlag.time);

                    await ReplyAsync(res.Item1, false, res.Item2.Build());

                    if (lobby.GameReadyAnnouncementChannel != null)
                    {
                        var channel = Context.Guild.GetTextChannel(lobby.GameReadyAnnouncementChannel.Value);
                        if (channel != null)
                        {
                            await channel.SendMessageAsync(res.Item1, false, res.Item2.Build());
                        }
                    }

                    if (lobby.DmUsersOnGameReady)
                    {
                        await MessageUsersAsync(queue.Select(x => x.UserId).ToArray(), x => MentionUtils.MentionUser(x), res.Item2.Build());
                    }
                }
                else
                {
                    db.SaveChanges();
                    var res = GameService.GetGameMessage(latestGame, "Player(s) picked.",
                                                         GameFlag.gamestate);
                    res.Item2.AddField("Remaining", string.Join("\n", remaining.Select(x => MentionUtils.MentionUser(x.UserId))));
                    await ReplyAsync(pickResponse ?? "", false, res.Item2.Build());
                }
            }
        }