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); }
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); }
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)); }