Esempio n. 1
0
        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));
            }
        }
Esempio n. 2
0
        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);
        }