Ejemplo n.º 1
0
        public static void WriteNewBottle(int location, int item)
        {
            System.Diagnostics.Debug.WriteLine($"Writing {Items.ITEM_NAMES[item]} --> {Items.ITEM_NAMES[location]}");

            location = ItemUtils.SubtractItemOffset(location);
            item     = ItemUtils.SubtractItemOffset(item);

            int f        = RomUtils.GetFileIndexForWriting(BOTTLE_CATCH_TABLE);
            int baseaddr = BOTTLE_CATCH_TABLE - RomData.MMFileList[f].Addr;
            var fileData = RomData.MMFileList[f].Data;

            for (int i = 0; i < RomData.BottleIndices[location].Length; i++)
            {
                int offset    = RomData.BottleIndices[location][i] * 6 + baseaddr;
                var newBottle = RomData.BottleList[item][0];
                var data      = new byte[]
                {
                    newBottle.ItemGained,
                    newBottle.Index,
                    newBottle.Message,
                };
                ReadWriteUtils.Arr_Insert(data, 0, data.Length, fileData, offset + 3);
            }
        }
Ejemplo n.º 2
0
        public static void WriteNewItem(int location, int item)
        {
            System.Diagnostics.Debug.WriteLine($"Writing {Items.ITEM_NAMES[item]} --> {Items.ITEM_NAMES[location]}");

            bool isRepeatable      = Items.REPEATABLE.Contains(item);
            bool isCycleRepeatable = Items.CYCLE_REPEATABLE.Contains(item);

            location = ItemUtils.SubtractItemOffset(location);
            item     = ItemUtils.SubtractItemOffset(item);

            int f            = RomUtils.GetFileIndexForWriting(GET_ITEM_TABLE);
            int baseaddr     = GET_ITEM_TABLE - RomData.MMFileList[f].Addr;
            var getItemIndex = RomData.GetItemIndices[location];

            if (location == Items.ItemGoldDust)
            {
                getItemIndex = 0x6A; // Place items intended for Gold Dust at the Goron Race Bottle location.
            }
            int offset   = (getItemIndex - 1) * 8 + baseaddr;
            var newItem  = RomData.GetItemList[item];
            var fileData = RomData.MMFileList[f].Data;

            var data = new byte[]
            {
                newItem.ItemGained,
                newItem.Flag,
                newItem.Index,
                newItem.Type,
                (byte)(newItem.Message >> 8),
                (byte)(newItem.Message & 0xFF),
                (byte)(newItem.Object >> 8),
                (byte)(newItem.Object & 0xFF),
            };

            ReadWriteUtils.Arr_Insert(data, 0, data.Length, fileData, offset);

            if (isCycleRepeatable)
            {
                ReadWriteUtils.WriteToROM(cycle_repeat, (ushort)getItemIndex);
                cycle_repeat += 2;
            }

            if (!isRepeatable)
            {
                SceneUtils.UpdateSceneFlagMask(getItemIndex);
            }

            if (item == Items.ItemBottleWitch)
            {
                ReadWriteUtils.WriteToROM(0xB49982, (ushort)getItemIndex);
                ReadWriteUtils.WriteToROM(0xC72B42, (ushort)getItemIndex);
            }

            if (item == Items.ItemBottleMadameAroma)
            {
                ReadWriteUtils.WriteToROM(0xB4999A, (ushort)getItemIndex);
                ReadWriteUtils.WriteToROM(0xC72B4E, (ushort)getItemIndex);
            }

            if (item == Items.ItemBottleAliens)
            {
                ReadWriteUtils.WriteToROM(0xB499A6, (ushort)getItemIndex);
                ReadWriteUtils.WriteToROM(0xC72B5A, (ushort)getItemIndex);
            }
            // Goron Race Bottle now rewards a plain Gold Dust, so this is unnecessary until a proper fix for Goron Dust is found.
            //if (NewItem == Items.ItemBottleGoronRace)
            //{
            //    WriteToROM(0xB499B2, (ushort)getItemIndex);
            //    WriteToROM(0xC72B66, (ushort)getItemIndex);
            //}
        }
Ejemplo n.º 3
0
        public static List <MessageEntry> MakeGossipQuotes(SettingsObject settings, List <ItemObject> items, Random random)
        {
            if (!settings.EnableGossipHints)
            {
                return(new List <MessageEntry>());
            }

            var hints      = new List <string>();
            var GossipList = settings.ClearHints
                ? items
                             .Where(io => !ItemUtils.IsFakeItem(io.ID))
                             .Select(io => new Gossip
            {
                SourceMessage      = new string[] { Items.LOCATION_NAMES[io.ID] },
                DestinationMessage = new string[] { Items.ITEM_NAMES[io.ID] },
            }).ToList()
                : GetGossipList();

            foreach (var item in items)
            {
                if (!item.ReplacesAnotherItem)
                {
                    continue;
                }

                // Skip hints for vanilla bottle content
                if ((!settings.RandomizeBottleCatchContents) &&
                    ItemUtils.IsBottleCatchContent(item.ID))
                {
                    continue;
                }

                // Skip hints for vanilla shop items
                if ((!settings.AddShopItems) &&
                    ItemUtils.IsShopItem(item.ID))
                {
                    continue;
                }

                // Skip hints for vanilla dungeon items
                if (!settings.AddDungeonItems &&
                    ItemUtils.IsDungeonItem(item.ID))
                {
                    continue;
                }

                int sourceItemId = ItemUtils.SubtractItemOffset(item.ReplacesItemId);
                int toItemId     = ItemUtils.SubtractItemOffset(item.ID);

                ushort soundEffectId = 0x690C;
                if (!settings.ClearHints)
                {
                    // 5% chance of being fake
                    bool isFake = random.Next(100) < 5;
                    if (isFake)
                    {
                        sourceItemId  = random.Next(GossipList.Count);
                        soundEffectId = 0x690A;
                    }
                }

                if (IsBadMessage(GossipList[toItemId].DestinationMessage[0]) && (settings.ClearHints || random.Next(8) != 0))
                {
                    continue;
                }

                int sourceMessageLength = GossipList[sourceItemId]
                                          .SourceMessage
                                          .Length;

                int destinationMessageLength = GossipList[toItemId]
                                               .DestinationMessage
                                               .Length;

                // Randomize messages
                string sourceMessage = GossipList[sourceItemId]
                                       .SourceMessage[random.Next(sourceMessageLength)];

                string destinationMessage = GossipList[toItemId]
                                            .DestinationMessage[random.Next(destinationMessageLength)];

                var quote = BuildGossipQuote(soundEffectId, sourceMessage, destinationMessage, random);

                hints.Add(quote);
            }

            if (!settings.ClearHints)
            {
                for (int i = 0; i < Gossip.JunkMessages.Count; i++)
                {
                    hints.Add(Gossip.JunkMessages[i]);
                }
            }

            //trim the pool of messages
            List <MessageEntry> finalHints = new List <MessageEntry>();

            for (ushort textId = GOSSIP_START_ID; textId < GOSSIP_END_ID; textId++)
            {
                if (GossipExclude.Contains(textId))
                {
                    continue;
                }

                int    selectedIndex = random.Next(hints.Count);
                string selectedHint  = hints[selectedIndex];

                MessageEntry message = new MessageEntry()
                {
                    Id      = textId,
                    Message = selectedHint,
                    Header  = MessageHeader.ToArray()
                };


                finalHints.Add(message);
                hints.RemoveAt(selectedIndex);
            }
            return(finalHints);
        }
Ejemplo n.º 4
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 <string, 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;
                    }
                }

                // skip non-randomized items.
                if (randomizedResult.Settings.UseCustomItemList)
                {
                    if (!randomizedResult.Settings.CustomItemList.Contains(ItemUtils.SubtractItemOffset(item.ID)))
                    {
                        continue;
                    }
                }
                else
                {
                    if (randomizedResult.Settings.ExcludeSongOfSoaring && item.Item == Item.SongSoaring)
                    {
                        continue;
                    }

                    if (!randomizedResult.Settings.AddDungeonItems && ItemUtils.IsDungeonItem(item.Item))
                    {
                        continue;
                    }

                    if (!randomizedResult.Settings.AddShopItems && ItemUtils.IsShopItem(item.Item))
                    {
                        continue;
                    }

                    if (!randomizedResult.Settings.AddOther && ItemUtils.IsOtherItem(item.Item))
                    {
                        continue;
                    }

                    if (!randomizedResult.Settings.RandomizeBottleCatchContents && ItemUtils.IsBottleCatchContent(item.Item))
                    {
                        continue;
                    }

                    if (!randomizedResult.Settings.AddMoonItems && ItemUtils.IsMoonLocation(item.Item))
                    {
                        continue;
                    }

                    if (!randomizedResult.Settings.AddNutChest && item.Item == Item.ChestPreClocktownDekuNut)
                    {
                        continue;
                    }

                    if (!randomizedResult.Settings.CrazyStartingItems && ItemUtils.IsStartingLocation(item.Item))
                    {
                        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 <string> {
                        "The Moon", "Bottle Catch", "Misc"
                    };
                    var itemRegion = item.NewLocation.Value.Region();
                    if (!string.IsNullOrWhiteSpace(itemRegion) && !preventRegions.Contains(itemRegion) && (randomizedResult.Settings.AddSongs || !ItemUtils.IsSong(item.Item)))
                    {
                        if (!itemsInRegions.ContainsKey(itemRegion))
                        {
                            itemsInRegions[itemRegion] = new List <ItemObject>();
                        }
                        itemsInRegions[itemRegion].Add(item);
                    }

                    if (!Gossip.GuaranteedLocationHints.Contains(item.NewLocation.Value))
                    {
                        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)
                {
                    bool regionHasRequiredItem;
                    if (kvp.Value.Any(io => randomizedResult.ItemsRequiredForMoonAccess.Contains(io.Item)))
                    {
                        regionHasRequiredItem = true;
                    }
                    else if (!kvp.Value.Any(io => randomizedResult.AllItemsOnPathToMoon.Contains(io.Item)))
                    {
                        regionHasRequiredItem = false;
                    }
                    else
                    {
                        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;
                    var    mid             = "is";
                    var    itemMessage     = regionHasRequiredItem
                        ? "on the Way of the Hero"
                        : "a foolish choice";
                    var list = regionHasRequiredItem
                        ? requiredHints
                        : nonRequiredHints;

                    list.Add($"\x1E{sfx}{start} \x01{locationMessage}\x00 {mid} \x06{itemMessage}\x00...\xBF".Wrap(35, "\x11"));
                }

                var numberOfRequiredHints    = 3;
                var numberOfNonRequiredHints = 2;

                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()))
            {
                var        isMoonGossipStone     = gossipQuote.ToString().StartsWith("Moon");
                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())
                    {
                        item = unusedItems.Random(randomizedResult.Random);
                    }
                    else
                    {
                        break;
                    }
                }

                if (!isMoonGossipStone)
                {
                    unusedItems.Remove(item);
                }

                string messageText = null;
                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)
                {
                    if (competitiveHints.Any())
                    {
                        messageText = competitiveHints.Random(randomizedResult.Random);
                        competitiveHints.Remove(messageText);
                    }
                    else
                    {
                        messageText = Gossip.JunkMessages.Random(randomizedResult.Random);
                    }
                }

                finalHints.Add(new MessageEntry()
                {
                    Id      = (ushort)gossipQuote,
                    Message = messageText,
                    Header  = MessageHeader.ToArray()
                });
            }

            return(finalHints);
        }