Beispiel #1
0
        public void ShopUpgrade(Flags flags, Preferences preferences)
        {
            // Modify DrawShopPartySprites to use new DrawOBSprite routines, see 0E_9500_ShopUpgrade.asm
            PutInBank(0x0E, 0xAA04, Blob.FromHex("205795"));
            PutInBank(0x0E, 0xAA0D, Blob.FromHex("205795"));
            PutInBank(0x0E, 0xAA16, Blob.FromHex("205795"));
            PutInBank(0x0E, 0xAA23, Blob.FromHex("4C5795"));

            // Extra routines for Shops, plus equip and magic info, see 0E_9500_ShopUpgrade.asm
            // Insert new routines in Common Shop Loop
            PutInBank(0x0E, 0xA931, Blob.FromHex("200095"));
            PutInBank(0x0E, 0x9500, Blob.FromHex("A564C928F038A566C904B035C902B017A20020D495A24020D495A28020D495A2C020D4954C4195A200208B95A240208B95A280208B95A2C0208B954C41952047952027A74C2696A9008DD66A8DDA6A8DDE6A8DE26A6060AA4A8510BD0061A8B9A4EC8511BD0161F011C901F0E9C903F004A9038511A9144C8395A5104A4A4AAABDD66A18651085104C24EC8A8515BD00610AAABD00AD8510BD01AD8511A662BD000338E9B0851229078513A5124A4A4AA8B1108514A613BD38AC2514F005A9004CC595A90E8510A5154A4A4A4AAAA5109DD66A608A8515BD00610AAABDB9BC8512BDBABC8513A662BD000338C944B01638E91C0AAABD50BF25128510BD51BF251305104C1896E9440AAABDA0BF25128510BDA1BF25130510C9019005A9004CC595A90E4CC595A522F033A564C928F02DA662BD00038514205E962027A7A520C561F0F7A9008522204D964C46E1A9018538A9128539A90E853CA90A853D60204D96A90E85572063E0A53E8512A53F8513A514380AAAB00DBD0093853EBD0193853F4C8E96BD0094853EBD0194853FA9118557A90E85582036DEA512853EA513853FA900852260"));

            if (flags.ChestInfo && !preferences.RenounceChestInfo)
            {
                // Shorten TreasureChest Dialog
                InsertDialogs(320, "You found.. #");
                InsertDialogs(321, "Can't hold.. #");

                PutInBank(0x1F, 0xD536, Blob.FromHex("68482064DB4CD0DD"));
                PutInBank(0x1F, 0xDDD0, Blob.FromHex("A9B648A9FF48A9114C03FE8A20DA8760"));
                PutInBank(0x11, 0xB700, Blob.FromHex("A911855768C9F1D004A905D003ADFB602010B8A545D00160A561C91CB00160C96C900160482089C6A9008561A639E88AC91E9002E91E8539A9068D0080A91C8D0180680AAAB00DBD0093853EBD0193853F4C5EB7BD0094853EBD0194853FA9068D0080A9228D0180A200A003B13EC8C902F05AC914F00B9D006BE8C900D0ED4C05B8A53E48A53F489848B13E0AA8B00DB9009A853EB9019A853F4CA7B7B9009B853EB9019B853FA000B13EC8C900F0079D006BE84CA9B7A9068D0080A9228D018068A8C868853F68853E4C6CB7A53E48A53F489848B13E0AA8A9068D0080A9158D0180B010B90097853EB9019738E920853F4CA7B7B90098853EB9019838E920853F4CA7B7A900853EA96B853F4C8ADBA23F8E0620A20E8E06208D0720A23F8E0620A2008E06208E06208E062020A1CC60"));
                if (preferences.RenounceCantHoldRed)
                {
                    PutInBank(0x11, 0xB707, Blob.FromHex("EAEAEAEAEAEA"));
                }

                if (flags.ExtConsumableSet != ExtConsumableSet.None)
                {
                    PutInBank(0x11, 0xB71B, Blob.FromHex("20"));
                }
            }

            // Patch in the equip menu loop to add gear info
            PutInBank(0x0E, 0xBB8F, Blob.FromHex("4CE090EA"));
            // Patch in the magic menu loop to add spell info
            PutInBank(0x0E, 0xAECD, Blob.FromHex("4C2691EA"));
            // the UpgradedEquipMenu and UpgradedMagicMenu code that the above patches jump to
            PutInBank(0x0E, 0x90E0, Blob.FromHex("A525D007A522D0044C93BB60A662BD0003F030297FA466C018D005691A4C029169428514203CC4205E9620F9BCA520C561F0F7A9008D0120853720F3BD2083B720DAEC4C93BBA525D007A522D0044CD1AE60A9018537A5664A6A6A0562AA0A2938187D00631869AF8514205E962080B72025B6A9008D01208537857F20029CA56248206DBA688562A90720EFB8A9292059B92080B74CD1AE"));

            // Modify DrawComplexString, this sets control code 14-19 to use a new words table in bank 11
            //  could be used to move some stuff in items name table and make some space
            //  see 1F_DEBC_DrawComplexString.asm
            PutInBank(0x1F, 0xDEBC, Blob.FromHex("C910B005A2204C83DEC914B07B")); // Change branching to enable CC14
            PutInBank(0x1F, 0xDF44, Blob.FromHex("4CCEDF"));                     // Jump to routine because we're too far, put in unused char weapons CC
            PutInBank(0x1F, 0xDFCE, Blob.FromHex("A91185572003FE4CA099"));       // Routine, put in unused char weapons routine

            // Routine to load the right word from the new words table
            PutInBank(0x11, 0x99A0, Blob.FromHex("A91185578558B13EE63ED002E63F203EE00AAAB00BBD009A853EBD019A4CC899BD009B853EBD019B853F2045DEA90E85584C4EE0"));

            const int weaponOffset = 0x1C;            // $28 entries
            const int armorOffset  = 0x44;            // $28 entries
            const int spellOffset  = 0xB0;            // $40 entries

            var weaponsData = new List <Weapon>();
            var armorsData  = new List <Armor>();

            for (int i = 0; i < WeaponCount; i++)
            {
                weaponsData.Add(new Weapon(i, this));
            }

            for (int i = 0; i < ArmorCount; i++)
            {
                armorsData.Add(new Armor(i, this));
            }

            var spellsData = GetSpells();

            // 12 char per row, 5 rows
            var descriptionsList = new List <string>();

            for (int i = 0; i < weaponOffset; i++)
            {
                descriptionsList.Add("");
            }

            // Insert the new words table
            int  offsetWordsPointers = 0x9A00;
            int  offsetWords         = 0x9B00;
            var  pointersWords       = new ushort[shopInfoWordsList.Count()];
            Blob generatedWords      = Blob.FromHex("");

            for (int i = 0; i < shopInfoWordsList.Count(); i++)
            {
                var blob = FF1Text.TextToBytes(shopInfoWordsList[i], useDTE: true);

                generatedWords += blob;

                pointersWords[i] = (ushort)(offsetWords);
                offsetWords     += blob.Length;
            }

            PutInBank(0x11, 0x9B00, generatedWords);
            PutInBank(0x11, offsetWordsPointers, Blob.FromUShorts(pointersWords));

            // Build the info boxes
            for (int i = weaponOffset; i < armorOffset; i++)
            {
                descriptionsList.Add("\n" + GenerateWeaponDescription(i - weaponOffset, preferences.ShopInfoIcons));
            }

            for (int i = armorOffset; i < (armorOffset + 0x28); i++)
            {
                descriptionsList.Add("\n" + GenerateArmorDescription(i - armorOffset, preferences.ShopInfoIcons));
            }

            for (int i = (armorOffset + 0x28); i < spellOffset; i++)
            {
                descriptionsList.Add("");
            }

            for (int i = spellOffset; i < spellOffset + 0x40; i++)
            {
                descriptionsList.Add("" + GenerateSpellDescription(i, spellsData[i - spellOffset].Data, preferences.ShopInfoIcons));
            }

            // Convert all dialogues to bytes
            int  offset        = 0xA000;
            var  pointers      = new ushort[descriptionsList.Count()];
            Blob generatedText = Blob.FromHex("");

            for (int i = 0; i < descriptionsList.Count(); i++)
            {
                var blob = new byte[] { 0x02, (byte)i } +FF1Text.TextToBytesInfo(descriptionsList[i], useDTE: true);
                if (blob.Length <= 3)
                {
                    blob = new byte[0];
                }

                generatedText += blob;

                pointers[i] = (ushort)(offset);
                offset     += blob.Length;
            }

            // Check if dialogs are too long
            if (generatedText.Length > 0x1400)
            {
                throw new Exception("ShopInfo text size maximum exceeded.");
            }

            // Insert dialogs
            PutInBank(0x11, 0xA000, generatedText);
            PutInBank(0x0E, 0x9300, Blob.FromUShorts(pointers));
        }