private async Task HandleTextAsync(SocketMessage messageParam)
        {
            var message = messageParam as SocketUserMessage;

            if (message == null)
            {
                return;
            }
            if (message.Author.IsBot)
            {
                return;                       //Else will respond to self responses
            }
            const string textRollSyntax = @"(?:(?<label>(?:\w+?)|(?:\""[\w\s]+\""))\s*?\:\s*?)?\[\[(?<expression>[dDkhl\s\d\.\,\(\)\,\!\+\-\*\/\^]+)\]\]";

            var matches = Regex.Matches(message.Content, textRollSyntax);

            if (matches.Count == 0)
            {
                return;                    //None found
            }
            List <(string, string)> diceRollRequestsLongShort = new List <(string, string)>();

            foreach (Match match in matches)
            {
                var request     = match.Groups["expression"].Value;
                var label       = match.Groups["label"].Value.Replace("\"", "");
                var results     = RollCommand.EvaluateDiceRequest(request).ToArray();
                var text        = string.Join(", ", results.Select(t => t.Item2));
                var totals      = string.Join(", ", results.Select(t => $"`{t.Item1}`"));
                var output      = $"({request} => {text} = {totals})";
                var shortOutput = $"({request} => { totals })";
                if (!String.IsNullOrWhiteSpace(label))
                {
                    output      = $"**{label}**: ({request} => {text} = **{totals}**)";
                    shortOutput = $"**{label}**: ({request} => **{totals}**)";
                }
                diceRollRequestsLongShort.Add((output, shortOutput));
            }

            var allLongRequests = string.Join(",\n", diceRollRequestsLongShort.Select(t => t.Item1));
            var finalOutput     = diceRollRequestsLongShort.Count > 1 ? $"{message.Author.Mention} ->\n{allLongRequests}" : $"{message.Author.Mention} -> {allLongRequests}";

            if (finalOutput.Length > DiscordConfig.MaxMessageSize)
            {
                var allShortRequests = string.Join(",\n", diceRollRequestsLongShort.Select(t => t.Item2));
                finalOutput = $"{message.Author.Mention} (shortened) -> {allShortRequests}";
            }
            var context = new SocketCommandContext(_client, message);

            await context.Channel.SendMessageAsync(finalOutput);
        }
Beispiel #2
0
        private static (double finalVal, string textual) RollQuickInit(string standardInitiativeDiceRoll)
        {
            Func <(double, string), bool> predicate = (x => x.Item1 >= 2 && x.Item1 <= 17);

            (double, string)roll;
            double finalVal = 0;
            var    rolls    = new List <(double, string)>();

            do
            {
                roll = RollCommand.EvaluateExpression(standardInitiativeDiceRoll).First();
                if (predicate(roll))
                {
                    roll.Item2 = $"~~{roll.Item2}~~";
                }
                rolls.Add(roll);
                finalVal = roll.Item1;
            } while (predicate(roll)); //2 -> 5 of each suit

            var textual = string.Join(',', rolls.Select(x => x.Item2));

            textual = $"[{textual}]";
            return(finalVal, textual);
        }
Beispiel #3
0
        public Task RollInitiative()
        {
            var combatUsers = this.Context.Guild.Users
                              .Where(u => u.Roles
                                     .Any(r => InCombatRoles
                                          .Any(icr => icr == r.Name)))
                              .Select(user => (user, user.Roles.Where(modRole => InitiativeModifierRoles.Any(s => s == modRole.Name)).Select(x => x.Name)))
                              .Select(userAndRoles => string.IsNullOrWhiteSpace(userAndRoles.user.Nickname) ? (userAndRoles.user.Username, userAndRoles.Item2) : (userAndRoles.user.Nickname, userAndRoles.Item2));

            var standardInitiativeDiceRoll  = "d54";
            var levelHeadedDiceRoll         = "2d54kh1";
            var improvedLevelHeadedDiceRoll = "3d54kh1";


            var initiative = combatUsers
                             .Select(nickAndEdges =>
            {
                var quick               = nickAndEdges.Item2 !.Contains(QuickEdge);
                var levelHeaded         = nickAndEdges.Item2.Contains(LevelHeadedEdge);
                var improvedLevelHeaded = nickAndEdges.Item2.Contains(ImprovedLevelHeadedEdge);
                if (quick)
                {
                    var cards = new List <(double, string)> {
                        RollQuickInit(standardInitiativeDiceRoll)
                    };

                    if (!levelHeaded && !improvedLevelHeaded)
                    {
                        return(nickAndEdges.Item1, cards.First());
                    }

                    cards.Add(RollQuickInit(standardInitiativeDiceRoll));
                    if (improvedLevelHeaded)
                    {
                        cards.Add(RollQuickInit(standardInitiativeDiceRoll));
                    }

                    var ordered   = cards.OrderByDescending(x => x.Item1).ToArray();
                    var first     = ordered.First();
                    var discarded = cards.Where(x => x != first).ToArray();
                    return(nickAndEdges.Item1, (first.Item1, $"{string.Join(',',discarded.Select(x => x.Item2))}{first.Item2}"));
                }
                if (levelHeaded)
                {
                    return(nickAndEdges.Item1, RollCommand.EvaluateExpression(levelHeadedDiceRoll).First());
                }

                if (improvedLevelHeaded)
                {
                    return(nickAndEdges.Item1,
                           RollCommand.EvaluateExpression(improvedLevelHeadedDiceRoll).First());
                }

                return(nickAndEdges.Item1, RollCommand.EvaluateExpression(standardInitiativeDiceRoll).First());
            })
                             .Select(t =>
            {
                if (t.Item2.Item1 != 1 && t.Item2.Item1 != 54)
                {
                    return(t);
                }

                t.Item2.Item1  = 55;        //Sentry value above deck size to put at top
                t.Item2.Item2 += " JOKER";
                return(t);
            })
                             .OrderByDescending(tuple => tuple.Item2.Item1)
                             .Select(tuple => $"{tuple.Item1} ({tuple.Item2.Item2}) -> {tuple.Item2.Item1}");


            var output = $"Initiative order:\n{string.Join('\n',initiative)}";

            return(ReplyAsync(output));
        }