public async Task OracleRollCommand([Remainder] string TableNameAndOptionalGame) { ChannelSettings channelSettings = await ChannelSettings.GetChannelSettingsAsync(Context.Channel.Id); GameName game = Utilities.GetGameContainedInString(TableNameAndOptionalGame); string oracleTable = Utilities.RemoveGameNamesFromString(TableNameAndOptionalGame); if (game == GameName.None && channelSettings != null) { game = channelSettings.DefaultGame; } OracleRoller roller = new OracleRoller(Services, game); try { var msg = await ReplyAsync("", false, roller.BuildRollResults(oracleTable).GetEmbed()); if (roller.RollResultList.Count == 1 && roller.RollResultList[0].ParentTable.Pair?.Length > 0) { await msg.AddReactionAsync(new Emoji("\uD83E\uDDE6")); } } catch (ArgumentException ex) { Console.WriteLine($"{Context.User} triggered an ArgumentException: {ex.Message}"); await ReplyAsync(ex.Message); } }
internal static OracleRoller RebuildRoller(OracleService oracleService, EmbedBuilder embed) { var roller = new OracleRoller(oracleService, Utilities.GetGameContainedInString(embed.Author.Name)); foreach (var field in embed.Fields) { var titleElementsRegex = Regex.Match(field.Name, @" ?(.*)\[(\d+)\]"); var sourceTable = oracleService.OracleList.Find(oracle => oracle.Name == titleElementsRegex.Groups[1].Value.Trim()); var oracleResult = oracleService.OracleList.Find(tbl => tbl.Name == sourceTable.Name)?.Oracles?.Find(oracle => oracle.Description == field.Value.ToString()) ?? null; if (!Int32.TryParse(titleElementsRegex.Groups[2].Value, out int tempRoll)) { continue; } roller.RollResultList.Add(new RollResult { ParentTable = sourceTable, Result = oracleResult, ShouldInline = field.IsInline, Roll = tempRoll }); } return(roller); }
private Embed AddRollToExisting(IUserMessage message) { var embed = message.Embeds.First().ToEmbedBuilder(); if (!embed.Title.Contains(OracleResources.OracleResult)) { throw new ArgumentException("Unknown message type"); } OracleRoller existingRoller = OracleRoller.RebuildRoller(_oracleService, embed); var rollerCopy = new List <RollResult>(existingRoller.RollResultList); //Copy the list so we can safely add to it using foreach foreach (var rollResult in rollerCopy.Where(tbl => tbl.ParentTable.Pair?.Length > 0)) { var pairedTable = _oracleService.OracleList.Find(tbl => tbl.Name == rollResult.ParentTable.Name); if (existingRoller.RollResultList.Any(tbl => tbl.ParentTable.Name == pairedTable.Pair)) { continue; } var roller = new OracleRoller(Services, existingRoller.Game).BuildRollResults(pairedTable.Pair); roller.RollResultList.ForEach(res => res.ShouldInline = true); rollResult.ShouldInline = true; int index = existingRoller.RollResultList.IndexOf(rollResult) + 1; existingRoller.RollResultList.InsertRange(index, roller.RollResultList); } return(existingRoller.GetEmbed()); }
//TODO move this to an extension method of IOracleEntry? /// <summary> /// Gets the result of a oracle roll, and any rolls that would result from it. /// </summary> /// <param name="services"></param> /// <param name="game"></param> /// <returns></returns> public string GetOracleResultPrompt(IServiceProvider services, GameName game, Random rnd = null) { var roller = new OracleRoller(services, game, rnd); var tables = roller.ParseOracleTables(Prompt); if (tables.Count == 0) { return(Prompt); } roller.BuildRollResults(Prompt); var finalResults = roller.RollResultList.Select(ocl => ocl.Result.Prompt); return($"{Prompt}\n" + String.Join(" / ", finalResults)); }
/// <summary> /// Gets the result of a oracle roll, and any rolls that would result from it. /// </summary> /// <param name="services"></param> /// <param name="game"></param> /// <returns></returns> public string GetOracleResult(IServiceProvider services, GameName game, Random rnd = null, string[] additionalSearchTerms = null) { var roller = new OracleRoller(services, game, rnd); var tables = roller.ParseOracleTables(Description); if (tables.Count == 0) { return(Description); } roller.BuildRollResults(Description, additionalSearchTerms); var finalResults = roller.RollResultList.Select(ocl => ocl.Result.Description); return($"{Description}\n" + String.Join(" / ", finalResults)); }
/// <summary> /// Gets the result of a oracle roll, and any rolls that would result from it. /// </summary> /// <param name="services"></param> /// <param name="game"></param> /// <returns></returns> public static string GetOracleResult(this IOracleEntry oracle, IServiceProvider services, GameName game, Random rnd = null) { var roller = new OracleRoller(services, game, rnd); var tables = roller.ParseOracleTables(oracle.Description); if (tables.Count == 0) { return(oracle.Description); } roller.BuildRollResults(oracle.Description); var finalResults = roller.RollResultList.Select(ocl => ocl.Result.Description); return($"{oracle.Description}\n" + String.Join(" / ", finalResults)); }
public List <RollResult> RandomOracleResultList(string TableName, IServiceProvider serviceProvider, GameName game = GameName.None, Random rand = null, string[] additionalSearchTerms = null) { if (rand == null) { rand = BotRandom.Instance; } var row = RandomRow(TableName, game, rand); var tableData = OracleList.Single(ot => ot.Name == TableName && (ot.Game == game || game == GameName.None)); game = tableData.Game ?? GameName.None; string lookup = row.Description; var match = Regex.Match(lookup, @"\[.*(\d+)x"); if (match.Success && int.TryParse(match.Groups[1].Value, out int rolls)) { List <string> ReplaceMultiRollTables = new List <string>(); for (int i = 0; i < rolls; i++) { ReplaceMultiRollTables.Add(tableData.Name); } lookup = lookup.Replace($"{match.Groups[1]}x", string.Join("/", ReplaceMultiRollTables)); } var oracleService = serviceProvider.GetRequiredService <OracleService>(); var roller = new OracleRoller(oracleService, game, rand); var tables = roller.ParseOracleTables(lookup); if (tables.Count == 0) { var rollResult = new RollResult(); rollResult.ParentTable = serviceProvider.GetRequiredService <OracleService>().OracleList.First(tbl => tbl.Name == TableName && (tbl.Game == game || game == GameName.None)); } roller.BuildRollResults(lookup, additionalSearchTerms); var finalResults = roller.RollResultList.Select(ocl => ocl.Result.Description); var spacer = (match.Success) ? " " : "\n"; return(roller.RollResultList); }
private void RollFacade(string table, int depth = 0, string[] additionalSearchTerms = null) { table = table.Trim(); var TablesToRoll = ParseOracleTables(table, additionalSearchTerms); if (TablesToRoll.Count == 0) { if (this.Game == GameName.None) { throw new ArgumentException($"{OracleResources.UnknownTableError}{table}"); } //try again without any game name this.Game = GameName.None; RollFacade(table, depth, additionalSearchTerms); } if (this.Game == GameName.None) { this.Game = TablesToRoll?.FirstOrDefault()?.Game ?? GameName.None; } foreach (var oracleTable in TablesToRoll) { int roll = RollerRandom.Next(1, oracleTable.d + 1); var oracleResult = oracleTable.Oracles.LookupOracle(roll); if (oracleTable.ShowResult) { RollResultList.Add(new RollResult { Roll = roll, Result = oracleResult, Depth = depth, ShouldInline = oracleTable?.DisplayMode?.Equals("Inline", StringComparison.OrdinalIgnoreCase) ?? false, ParentTable = oracleTable }); } //Check if we have any nested oracles if (oracleResult.Oracles != null) { RollNested(oracleResult, depth: 1, oracleTable); } //Check if we need to roll another oracle var match = Regex.Match(oracleResult.Description, @"^\[(.*)\]$"); if (match.Success) { string nextTable = match.Groups[0].Value; if (Regex.IsMatch(nextTable, @"^\[\d+x\]")) { MultiRollFacade(nextTable, oracleTable, depth); return; } RollFacade(nextTable, depth + 1, additionalSearchTerms); } // Match "{Place} of {Namesake}'s {Detail}" style entries var formatedStringMatches = Regex.Matches(oracleResult.Description, @"\{([^\}]*)\}").ToList(); for (int i = formatedStringMatches.Count - 1; i >= 0; i--) { Match formatMatch = formatedStringMatches[i]; var subTable = OracleService.OracleList.SingleOrDefault(o => o.MatchTableAlias(formatMatch.Groups[1].Value) && (Game == GameName.None || Game == o.Game)); if (subTable == null) { continue; } var subRoller = new OracleRoller(OracleService, subTable.Game.GetValueOrDefault(), RollerRandom); subRoller.BuildRollResults(subTable.Name); var replacement = subRoller.RollResultList.Last().Result.Description; string newDescription = oracleResult.Description.Substring(0, formatMatch.Index) + replacement + oracleResult.Description.Substring(formatMatch.Index + formatMatch.Length); oracleResult.Description = newDescription; } } string output = string.Empty; foreach (var rollResult in RollResultList) { output += $"{OracleResources.Roll}: {rollResult.Roll} {OracleResources.Outcome}: {rollResult.Result.Description}\n"; } }