public static void CreateSpoilerLog(RandomizedResult randomized, SettingsObject settings) { var itemList = randomized.ItemList .Where(io => !io.Item.IsFake()) .Select(u => new SpoilerItem(u, ItemUtils.IsRequired(u.Item, randomized), ItemUtils.IsImportant(u.Item, randomized))); var settingsString = settings.ToString(); var directory = Path.GetDirectoryName(settings.OutputROMFilename); var filename = $"{Path.GetFileNameWithoutExtension(settings.OutputROMFilename)}"; var plainTextRegex = new Regex("[^a-zA-Z0-9' .\\-]+"); Spoiler spoiler = new Spoiler() { Version = MainForm.AssemblyVersion.Substring(26), SettingsString = settingsString, Seed = settings.Seed, RandomizeDungeonEntrances = settings.RandomizeDungeonEntrances, ItemList = itemList.Where(u => !u.Item.IsFake()).ToList(), NewDestinationIndices = randomized.NewDestinationIndices, Logic = randomized.Logic, CustomItemListString = settings.UseCustomItemList ? settings.CustomItemListString : null, CustomStartingItemListString = settings.CustomStartingItemList.Any() ? settings.CustomStartingItemListString : null, CustomJunkLocationsString = settings.CustomJunkLocationsString, GossipHints = randomized.GossipQuotes?.ToDictionary(me => (GossipQuote)me.Id, (me) => { var message = me.Message.Substring(1); var soundEffect = message.Substring(0, 2); message = message.Substring(2); if (soundEffect == "\x69\x0C") { // real } else if (soundEffect == "\x69\x0A") { // fake message = "FAKE - " + message; } else { // junk message = "JUNK - " + message; } return(plainTextRegex.Replace(message.Replace("\x11", " "), "")); }), }; if (settings.GenerateHTMLLog) { filename += "_SpoilerLog.html"; using (StreamWriter newlog = new StreamWriter(Path.Combine(directory, filename))) { Templates.HtmlSpoiler htmlspoiler = new Templates.HtmlSpoiler(spoiler); newlog.Write(htmlspoiler.TransformText()); } } else { filename += "_SpoilerLog.txt"; CreateTextSpoilerLog(spoiler, Path.Combine(directory, filename)); } }
public static List <MessageEntry> MakeGossipQuotes(RandomizedResult randomizedResult) { if (randomizedResult.Settings.GossipHintStyle == GossipHintStyle.Default) { return(new List <MessageEntry>()); } var randomizedItems = new List <ItemObject>(); var competitiveHints = new List <string>(); var itemsInRegions = new Dictionary <Region, List <ItemObject> >(); foreach (var item in randomizedResult.ItemList) { if (item.NewLocation == null) { continue; } if (randomizedResult.Settings.ClearHints) { // skip free items if (ItemUtils.IsStartingLocation(item.NewLocation.Value)) { continue; } } if (!item.IsRandomized) { continue; } var itemName = item.Item.Name(); if (randomizedResult.Settings.GossipHintStyle != GossipHintStyle.Competitive && (itemName.Contains("Heart") || itemName.Contains("Rupee")) && (randomizedResult.Settings.ClearHints || randomizedResult.Random.Next(8) != 0)) { continue; } if (randomizedResult.Settings.GossipHintStyle == GossipHintStyle.Competitive) { var preventRegions = new List <Region> { Region.TheMoon, Region.BottleCatch, Region.Misc }; var itemRegion = item.NewLocation.Value.Region(); if (itemRegion.HasValue && !preventRegions.Contains(itemRegion.Value) && !randomizedResult.Settings.CustomJunkLocations.Contains(item.NewLocation.Value)) { if (!itemsInRegions.ContainsKey(itemRegion.Value)) { itemsInRegions[itemRegion.Value] = new List <ItemObject>(); } itemsInRegions[itemRegion.Value].Add(item); } var competitiveHintInfo = item.NewLocation.Value.GetAttribute <GossipCompetitiveHintAttribute>(); if (competitiveHintInfo == null) { continue; } if (randomizedResult.Settings.CustomJunkLocations.Contains(item.NewLocation.Value)) { continue; } if (competitiveHintInfo.Condition != null && competitiveHintInfo.Condition(randomizedResult.Settings)) { continue; } } randomizedItems.Add(item); } var unusedItems = randomizedItems.ToList(); if (randomizedResult.Settings.GossipHintStyle == GossipHintStyle.Competitive) { unusedItems.AddRange(randomizedItems); var requiredHints = new List <string>(); var nonRequiredHints = new List <string>(); foreach (var kvp in itemsInRegions) { var numberOfRequiredItems = kvp.Value.Count(io => ItemUtils.IsRequired(io.Item, randomizedResult)); var numberOfImportantItems = kvp.Value.Count(io => ItemUtils.IsImportant(io.Item, randomizedResult)); if (numberOfRequiredItems == 0 && numberOfImportantItems > 0) { continue; } ushort soundEffectId = 0x690C; // grandma curious string start = Gossip.MessageStartSentences.Random(randomizedResult.Random); string sfx = $"{(char)((soundEffectId >> 8) & 0xFF)}{(char)(soundEffectId & 0xFF)}"; var locationMessage = kvp.Key.Name(); //var mid = "is"; //var itemMessage = numberOfRequiredItems > 0 // ? "on the Way of the Hero" // : "a foolish choice"; List <string> list; char color; if (numberOfRequiredItems > 0) { list = requiredHints; color = TextCommands.ColorYellow; } else { list = nonRequiredHints; color = TextCommands.ColorSilver; } //list.Add($"\x1E{sfx}{start} \x01{locationMessage}\x00 {mid} \x06{itemMessage}\x00...\xBF".Wrap(35, "\x11")); var mid = "has"; list.Add($"\x1E{sfx}{start} {TextCommands.ColorRed}{locationMessage}{TextCommands.ColorWhite} {mid} {color}{NumberToWords(numberOfImportantItems)} important item{(numberOfImportantItems == 1 ? "" : "s")}{TextCommands.ColorWhite}...\xBF".Wrap(35, "\x11")); } var numberOfRequiredHints = 2; var numberOfNonRequiredHints = 3; for (var i = 0; i < numberOfRequiredHints; i++) { var chosen = requiredHints.RandomOrDefault(randomizedResult.Random); if (chosen != null) { requiredHints.Remove(chosen); competitiveHints.Add(chosen); competitiveHints.Add(chosen); } } for (var i = 0; i < numberOfNonRequiredHints; i++) { var chosen = nonRequiredHints.RandomOrDefault(randomizedResult.Random); if (chosen != null) { nonRequiredHints.Remove(chosen); competitiveHints.Add(chosen); competitiveHints.Add(chosen); } } } List <MessageEntry> finalHints = new List <MessageEntry>(); foreach (var gossipQuote in Enum.GetValues(typeof(GossipQuote)).Cast <GossipQuote>().OrderBy(gq => randomizedResult.Random.Next())) { string messageText = null; var isMoonGossipStone = gossipQuote.ToString().StartsWith("Moon"); if (!isMoonGossipStone && competitiveHints.Any()) { messageText = competitiveHints.Random(randomizedResult.Random); competitiveHints.Remove(messageText); } if (messageText == null) { var restrictionAttributes = gossipQuote.GetAttributes <GossipRestrictAttribute>().ToList(); ItemObject item = null; var forceClear = false; while (item == null) { if (restrictionAttributes.Any() && (isMoonGossipStone || randomizedResult.Settings.GossipHintStyle == GossipHintStyle.Relevant)) { var chosen = restrictionAttributes.Random(randomizedResult.Random); var candidateItem = chosen.Type == GossipRestrictAttribute.RestrictionType.Item ? randomizedResult.ItemList.Single(io => io.Item == chosen.Item) : randomizedResult.ItemList.Single(io => io.NewLocation == chosen.Item); if (isMoonGossipStone || unusedItems.Contains(candidateItem)) { item = candidateItem; forceClear = chosen.ForceClear; } else { restrictionAttributes.Remove(chosen); } } else if (unusedItems.Any()) { if (randomizedResult.Settings.GossipHintStyle == GossipHintStyle.Competitive) { item = unusedItems.FirstOrDefault(io => unusedItems.Count(x => x.Item == io.Item) == 1); if (item == null) { item = unusedItems.GroupBy(io => io.NewLocation.Value.GetAttribute <GossipCompetitiveHintAttribute>().Priority) .OrderByDescending(g => g.Key) .First() .ToList() .Random(randomizedResult.Random); } } else { item = unusedItems.Random(randomizedResult.Random); } } else { break; } } if (!isMoonGossipStone) { unusedItems.Remove(item); } if (item != null) { ushort soundEffectId = 0x690C; // grandma curious string itemName = null; string locationName = null; if (forceClear || randomizedResult.Settings.ClearHints) { itemName = item.Item.Name(); locationName = item.NewLocation.Value.Location(); } else { if (isMoonGossipStone || randomizedResult.Settings.GossipHintStyle == GossipHintStyle.Competitive || randomizedResult.Random.Next(100) >= 5) // 5% chance of fake/junk hint if it's not a moon gossip stone or competitive style { itemName = item.Item.ItemHints().Random(randomizedResult.Random); locationName = item.NewLocation.Value.LocationHints().Random(randomizedResult.Random); } else { if (randomizedResult.Random.Next(2) == 0) // 50% chance for fake hint. otherwise default to junk hint. { soundEffectId = 0x690A; // grandma laugh itemName = item.Item.ItemHints().Random(randomizedResult.Random); locationName = randomizedItems.Random(randomizedResult.Random).Item.LocationHints().Random(randomizedResult.Random); } } } if (itemName != null && locationName != null) { messageText = BuildGossipQuote(soundEffectId, locationName, itemName, randomizedResult.Random); } } } if (messageText == null) { messageText = Gossip.JunkMessages.Random(randomizedResult.Random); } finalHints.Add(new MessageEntry() { Id = (ushort)gossipQuote, Message = messageText, Header = MessageHeader.ToArray() }); } return(finalHints); }