Exemple #1
0
        private static void UpdateShop(Item location, Item item, List <MessageEntry> newMessages)
        {
            var newItem = RomData.GetItemList[item.GetItemIndex().Value];

            var shopRooms = location.GetAttributes <ShopRoomAttribute>();

            foreach (var shopRoom in shopRooms)
            {
                ReadWriteUtils.WriteToROM(shopRoom.RoomObjectAddress, (ushort)newItem.Object);
            }

            var shopInventories = location.GetAttributes <ShopInventoryAttribute>();

            foreach (var shopInventory in shopInventories)
            {
                ReadWriteUtils.WriteToROM(shopInventory.ShopItemAddress, (ushort)newItem.Object);
                var index = newItem.Index > 0x7F ? (byte)(0xFF - newItem.Index) : (byte)(newItem.Index - 1);
                ReadWriteUtils.WriteToROM(shopInventory.ShopItemAddress + 0x03, index);

                var    shopTexts = item.ShopTexts();
                string description;
                switch (shopInventory.Keeper)
                {
                case ShopInventoryAttribute.ShopKeeper.WitchShop:
                    description = shopTexts.WitchShop;
                    break;

                case ShopInventoryAttribute.ShopKeeper.TradingPostMain:
                    description = shopTexts.TradingPostMain;
                    break;

                case ShopInventoryAttribute.ShopKeeper.TradingPostPartTimer:
                    description = shopTexts.TradingPostPartTimer;
                    break;

                case ShopInventoryAttribute.ShopKeeper.CuriosityShop:
                    description = shopTexts.CuriosityShop;
                    break;

                case ShopInventoryAttribute.ShopKeeper.BombShop:
                    description = shopTexts.BombShop;
                    break;

                case ShopInventoryAttribute.ShopKeeper.ZoraShop:
                    description = shopTexts.ZoraShop;
                    break;

                case ShopInventoryAttribute.ShopKeeper.GoronShop:
                    description = shopTexts.GoronShop;
                    break;

                case ShopInventoryAttribute.ShopKeeper.GoronShopSpring:
                    description = shopTexts.GoronShopSpring;
                    break;

                default:
                    description = null;
                    break;
                }
                if (description == null)
                {
                    description = shopTexts.Default;
                }

                var messageId = ReadWriteUtils.ReadU16(shopInventory.ShopItemAddress + 0x0A);
                newMessages.Add(new MessageEntry
                {
                    Id      = messageId,
                    Header  = null,
                    Message = MessageUtils.BuildShopDescriptionMessage(item.Name(), 20, description)
                });

                newMessages.Add(new MessageEntry
                {
                    Id      = (ushort)(messageId + 1),
                    Header  = null,
                    Message = MessageUtils.BuildShopPurchaseMessage(item.Name(), 20, item.ShopTexts()?.IsMultiple ?? false)
                });
            }
        }
Exemple #2
0
 public static void ResetSceneFlagMask()
 {
     ReadWriteUtils.WriteToROM(SCENE_FLAG_MASKS, (uint)0);
     ReadWriteUtils.WriteToROM(SCENE_FLAG_MASKS + 0xC, (uint)0);
 }
Exemple #3
0
        public static void WriteNewItem(Item location, Item item, List <MessageEntry> newMessages, bool updateShop, bool preventDowngrades, bool updateChest, ChestTypeAttribute.ChestType?overrideChestType)
        {
            System.Diagnostics.Debug.WriteLine($"Writing {item.Name()} --> {location.Location()}");

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

            if (location == Item.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.GetItemIndex().Value];
            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 (item.IsCycleRepeatable())
            {
                ReadWriteUtils.WriteToROM(cycle_repeat, (ushort)getItemIndex);
                cycle_repeat += 2;
            }

            var isRepeatable = item.IsRepeatable() || (!preventDowngrades && item.IsDowngradable());

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

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

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

            if (item == Item.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 (item == Item.ItemBottleGoronRace)
            //{
            //    WriteToROM(0xB499B2, (ushort)getItemIndex);
            //    WriteToROM(0xC72B66, (ushort)getItemIndex);
            //}

            if (updateChest)
            {
                UpdateChest(location, item, overrideChestType);
            }

            if (location != item)
            {
                if (updateShop)
                {
                    UpdateShop(location, item, newMessages);
                }

                if (location == Item.StartingSword)
                {
                    ResourceUtils.ApplyHack(Values.ModsDirectory + "fix-sword-song-of-time");
                }
            }
        }
Exemple #4
0
        public static void WriteNewItem(int ItemSlot, int NewItem, bool IsRepeatable, bool RepeatCycle)
        {
            int f         = RomUtils.GetFileIndexForWriting(Addresses.GetItemTable);
            int baseaddr  = Addresses.GetItemTable - RomData.MMFileList[f].Addr;
            var itemIndex = RomData.GetItemIndices[ItemSlot];

            if (ItemSlot == Items.ItemGoldDust)
            {
                itemIndex = 0x6A; // Place items intended for Gold Dust at the Goron Race Bottle location.
            }
            int offset   = (itemIndex - 1) * 8 + baseaddr;
            var newItem  = RomData.GetItemList[NewItem];
            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 (RepeatCycle)
            {
                ReadWriteUtils.WriteToROM(cycle_repeat, (ushort)itemIndex);
                cycle_repeat += 2;
            }

            if (!IsRepeatable)
            {
                SceneUtils.UpdateSceneFlagMask(itemIndex);
            }

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

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

            if (NewItem == Items.ItemBottleAliens)
            {
                ReadWriteUtils.WriteToROM(0xB499A6, (ushort)itemIndex);
                ReadWriteUtils.WriteToROM(0xC72B5A, (ushort)itemIndex);
            }
            ;
            // 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)GetItemIndices[ItemSlot]);
            //    WriteToROM(0xC72B66, (ushort)GetItemIndices[ItemSlot]);
            //};
        }
Exemple #5
0
        public static void WriteNewItem(Item location, Item item, List <MessageEntry> newMessages, bool updateShop, bool preventDowngrades, bool updateChest, ChestTypeAttribute.ChestType?overrideChestType, bool isExtraStartingItem)
        {
            System.Diagnostics.Debug.WriteLine($"Writing {item.Name()} --> {location.Location()}");

            int f            = RomUtils.GetFileIndexForWriting(GET_ITEM_TABLE);
            int baseaddr     = GET_ITEM_TABLE - RomData.MMFileList[f].Addr;
            var getItemIndex = location.GetItemIndex().Value;
            int offset       = (getItemIndex - 1) * 8 + baseaddr;
            var newItem      = isExtraStartingItem
                ? Items.RecoveryHeart // Warning: this will not work well for starting with Bottle contents (currently impossible), because you'll first have to acquire the Recovery Heart before getting the bottle-less version. Also may interfere with future implementation of progressive upgrades.
                : RomData.GetItemList[item.GetItemIndex().Value];
            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);

            // todo use Logic Editor to handle which locations should be repeatable and which shouldn't.
            if ((item.IsCycleRepeatable() && location != Item.HeartPieceNotebookMayor) || (item.Name().Contains("Rupee") && location.IsRupeeRepeatable()))
            {
                ReadWriteUtils.WriteToROM(cycle_repeat, (ushort)getItemIndex);
                cycle_repeat       += 2;
                cycle_repeat_count += 2;

                ReadWriteUtils.WriteToROM(cycle_repeat_count_address, cycle_repeat_count);
            }

            var isRepeatable = item.IsRepeatable() || (!preventDowngrades && item.IsDowngradable());

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

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

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

            if (item == Item.ItemBottleAliens)
            {
                ReadWriteUtils.WriteToROM(0xB49996, (ushort)getItemIndex);
                ReadWriteUtils.WriteToROM(0xC72B5A, (ushort)getItemIndex);
            }

            if (item == Item.ItemBottleGoronRace)
            {
                ReadWriteUtils.WriteToROM(0xB499A2, (ushort)getItemIndex);
                ReadWriteUtils.WriteToROM(0xC72B66, (ushort)getItemIndex);
            }

            if (updateChest)
            {
                UpdateChest(location, item, overrideChestType);
            }

            if (location != item)
            {
                if (updateShop)
                {
                    UpdateShop(location, item, newMessages);
                }

                if (location == Item.StartingSword)
                {
                    ResourceUtils.ApplyHack(Values.ModsDirectory + "fix-sword-song-of-time");
                }

                if (location == Item.MundaneItemSeahorse)
                {
                    ResourceUtils.ApplyHack(Values.ModsDirectory + "fix-fisherman");
                }

                if (location == Item.MaskFierceDeity)
                {
                    ResourceUtils.ApplyHack(Values.ModsDirectory + "fix-fd-mask-reset");
                }
            }
        }
Exemple #6
0
        //todo - allow rebuilding text file

        private static void WriteMessage(int addr, byte[] msg)
        {
            int fileIndex = RomUtils.GetFileIndexForWriting(MESSAGE_DATA_ADDRESS);

            ReadWriteUtils.Arr_Insert(msg, 0, msg.Length, MMFileList[fileIndex].Data, addr);
        }
Exemple #7
0
        public static void RebuildAudioSeq(List <MMRando.Models.Rom.SequenceInfo> SequenceList)
        {
            List <MMSequence> OldSeq = new List <MMSequence>();
            int f     = RomUtils.GetFileIndexForWriting(Addresses.SeqTable);
            int basea = RomData.MMFileList[f].Addr;

            for (int i = 0; i < 128; i++)
            {
                MMSequence entry = new MMSequence();
                if (i == 0x1E)
                {
                    entry.Addr = 2;
                    entry.Size = 0;
                    OldSeq.Add(entry);
                    continue;
                }

                int entryaddr = Addresses.SeqTable + (i * 16);
                entry.Addr = (int)ReadWriteUtils.Arr_ReadU32(RomData.MMFileList[f].Data, entryaddr - basea);
                entry.Size = (int)ReadWriteUtils.Arr_ReadU32(RomData.MMFileList[f].Data, (entryaddr - basea) + 4);
                if (entry.Size > 0)
                {
                    entry.Data = new byte[entry.Size];
                    Array.Copy(RomData.MMFileList[4].Data, entry.Addr, entry.Data, 0, entry.Size);
                }
                else
                {
                    int j = SequenceList.FindIndex(u => u.Replaces == i);
                    if (j != -1)
                    {
                        if ((entry.Addr > 0) && (entry.Addr < 128))
                        {
                            if (SequenceList[j].Replaces != 0x28)
                            {
                                SequenceList[j].Replaces = entry.Addr;
                            }
                            else
                            {
                                entry.Data = OldSeq[0x18].Data;
                                entry.Size = OldSeq[0x18].Size;
                            }
                        }
                    }
                }
                OldSeq.Add(entry);
            }

            List <MMSequence> NewSeq = new List <MMSequence>();
            int addr = 0;

            byte[] NewAudioSeq = new byte[0];
            for (int i = 0; i < 128; i++)
            {
                MMSequence newentry = new MMSequence();
                if (OldSeq[i].Size == 0)
                {
                    newentry.Addr = OldSeq[i].Addr;
                }
                else
                {
                    newentry.Addr = addr;
                }

                int j = SequenceList.FindIndex(u => u.Replaces == i);
                if (j != -1)
                {
                    if (SequenceList[j].MM_seq != -1)
                    {
                        newentry.Size = OldSeq[SequenceList[j].MM_seq].Size;
                        newentry.Data = OldSeq[SequenceList[j].MM_seq].Data;
                    }
                    else
                    {
                        BinaryReader sequence = new BinaryReader(File.Open(SequenceList[j].Name, FileMode.Open));
                        int          len      = (int)sequence.BaseStream.Length;
                        byte[]       data     = new byte[len];
                        sequence.Read(data, 0, len);
                        sequence.Close();

                        if (data[1] != 0x20)
                        {
                            data[1] = 0x20;
                        }

                        newentry.Size = len;
                        newentry.Data = data;
                    }
                }
                else
                {
                    newentry.Size = OldSeq[i].Size;
                    newentry.Data = OldSeq[i].Data;
                }
                NewSeq.Add(newentry);

                if (newentry.Data != null)
                {
                    NewAudioSeq = NewAudioSeq.Concat(newentry.Data).ToArray();
                }

                addr += newentry.Size;
            }

            if (addr > (RomData.MMFileList[4].End - RomData.MMFileList[4].Addr))
            {
                MMFile newa = new MMFile();
                newa.Addr         = RomData.MMFileList[RomData.MMFileList.Count - 1].End;
                newa.End          = newa.Addr + addr;
                newa.IsCompressed = false;
                newa.Data         = NewAudioSeq;
                RomData.MMFileList.Add(newa);
                ResourceUtils.ApplyHack(Values.ModsDirectory + "reloc-audio");
                RomData.MMFileList[4].Data     = new byte[0];
                RomData.MMFileList[4].Cmp_Addr = -1;
                RomData.MMFileList[4].Cmp_End  = -1;
            }
            else
            {
                RomData.MMFileList[4].Data = NewAudioSeq;
            }

            //update pointer table
            f = RomUtils.GetFileIndexForWriting(Addresses.SeqTable);
            for (int i = 0; i < 128; i++)
            {
                ReadWriteUtils.Arr_WriteU32(RomData.MMFileList[f].Data, (Addresses.SeqTable + (i * 16)) - basea, (uint)NewSeq[i].Addr);
                ReadWriteUtils.Arr_WriteU32(RomData.MMFileList[f].Data, 4 + (Addresses.SeqTable + (i * 16)) - basea, (uint)NewSeq[i].Size);
            }

            //update inst sets
            f     = RomUtils.GetFileIndexForWriting(Addresses.InstSetMap);
            basea = RomData.MMFileList[f].Addr;
            for (int i = 0; i < 128; i++)
            {
                int paddr = (Addresses.InstSetMap - basea) + (i * 2) + 2;
                int j     = -1;

                if (NewSeq[i].Size == 0)
                {
                    j = SequenceList.FindIndex(u => u.Replaces == NewSeq[i].Addr);
                }
                else
                {
                    j = SequenceList.FindIndex(u => u.Replaces == i);
                }

                if (j != -1)
                {
                    RomData.MMFileList[f].Data[paddr] = (byte)SequenceList[j].Instrument;
                }
            }
        }
Exemple #8
0
 public static void ResetSceneFlagMask()
 {
     ReadWriteUtils.WriteToROM(Addresses.SceneFlagMasks, (uint)0);
     ReadWriteUtils.WriteToROM(Addresses.SceneFlagMasks + 0xC, (uint)0);
 }