Exemple #1
0
        public void Randomize(Blob seed, Flags flags, Preferences preferences)
        {
            var rng = new MT19337(BitConverter.ToUInt32(seed, 0));

            // Spoilers => different rng immediately
            if (flags.Spoilers)
            {
                rng = new MT19337(rng.Next());
            }

            UpgradeToMMC3();
            MakeSpace();
            Bank1E();
            Bank1B();
            EasterEggs();
            DynamicWindowColor(preferences.MenuColor);
            PermanentCaravan();
            ShiftEarthOrbDown();
            CastableItemTargeting();

            TeleportShuffle teleporters      = new TeleportShuffle();
            var             palettes         = OverworldMap.GeneratePalettes(Get(OverworldMap.MapPaletteOffset, MapCount * OverworldMap.MapPaletteSize).Chunk(OverworldMap.MapPaletteSize));
            var             overworldMap     = new OverworldMap(this, flags, palettes, teleporters);
            var             maps             = ReadMaps();
            var             shopItemLocation = ItemLocations.CaravanItemShop1;

#if DEBUG
            if (flags.ExperimentalFloorGeneration)
            {
                MapRequirements      reqs;
                MapGeneratorStrategy strategy;
                MapGenerator         generator = new MapGenerator();
                if (flags.EFGWaterfall)
                {
                    reqs = new MapRequirements
                    {
                        MapId = MapId.Waterfall,
                        Rom   = this,
                    };
                    strategy = MapGeneratorStrategy.WaterfallClone;
                    CompleteMap waterfall = generator.Generate(rng, strategy, reqs);

                    // Should add more into the reqs so that this can be done inside the generator.
                    teleporters.Waterfall.SetEntrance(waterfall.Entrance);
                    overworldMap.PutOverworldTeleport(OverworldTeleportIndex.Waterfall, teleporters.Waterfall);
                    maps[(int)MapId.Waterfall] = waterfall.Map;
                }

                if (flags.EFGEarth1)
                {
                    reqs = new MapRequirements
                    {
                        MapId = MapId.EarthCaveB1,
                        Rom   = this,
                    };

                    strategy = MapGeneratorStrategy.Square;
                    var earthB1 = generator.Generate(rng, strategy, reqs);

                    // Should add more into the reqs so that this can be done inside the generator.
                    teleporters.EarthCave1.SetEntrance(earthB1.Entrance);
                    overworldMap.PutOverworldTeleport(OverworldTeleportIndex.EarthCave1, teleporters.EarthCave1);
                    maps[(int)MapId.EarthCaveB1] = earthB1.Map;
                }
                if (flags.EFGEarth2)
                {
                    reqs = new MapRequirements
                    {
                        MapId = MapId.EarthCaveB2,
                        Rom   = this,
                    };

                    strategy = MapGeneratorStrategy.Square;
                    var earthB2 = generator.Generate(rng, strategy, reqs);

                    // Should add more into the reqs so that this can be done inside the generator.
                    teleporters.EarthCave2.SetEntrance(earthB2.Entrance);
                    overworldMap.PutStandardTeleport(TeleportIndex.EarthCave2, teleporters.EarthCave2, OverworldTeleportIndex.EarthCave1);
                    maps[(int)MapId.EarthCaveB2] = earthB2.Map;
                }
            }
#endif

            if (preferences.ModernBattlefield)
            {
                EnableModernBattlefield();
            }

            if (flags.TitansTrove)
            {
                EnableTitansTrove(maps);
            }

            if (flags.LefeinShops)
            {
                EnableLefeinShops(maps);
            }

            // This has to be done before we shuffle spell levels.
            if (flags.SpellBugs)
            {
                FixSpellBugs();
            }

            if (flags.RebalanceSpells)
            {
                RebalanceSpells();
            }

            if (flags.EnemySpellsTargetingAllies)
            {
                FixEnemyAOESpells();
            }

            if (flags.ItemMagic)
            {
                ShuffleItemMagic(rng);
            }

            if (flags.ShortToFR)
            {
                ShortenToFR(maps, flags.PreserveFiendRefights, rng);
            }

            if (flags.Treasures && flags.ShardHunt && !flags.ChaosRush)
            {
                EnableShardHunt(rng, flags.ExtraShards ? rng.Between(24, 30) : 16, flags.NPCItems);
            }

            if (flags.TransformFinalFormation)
            {
                TransformFinalFormation((FinalFormation)rng.Between(0, Enum.GetValues(typeof(FinalFormation)).Length - 1));
            }

            var maxRetries = 8;
            for (var i = 0; i < maxRetries; i++)
            {
                try
                {
                    overworldMap = new OverworldMap(this, flags, palettes, teleporters);
                    if ((flags.Entrances || flags.Floors || flags.Towns) && flags.Treasures && flags.NPCItems)
                    {
                        overworldMap.ShuffleEntrancesAndFloors(rng, flags);
                    }

                    if (flags.ShuffleObjectiveNPCs)
                    {
                        overworldMap.ShuffleObjectiveNPCs(rng);
                    }

                    IncentiveData incentivesData = new IncentiveData(rng, flags, overworldMap, shopItemLocation);

                    if (flags.Shops)
                    {
                        var excludeItemsFromRandomShops = new List <Item>();
                        if (flags.Treasures)
                        {
                            excludeItemsFromRandomShops = incentivesData.ForcedItemPlacements.Select(x => x.Item).Concat(incentivesData.IncentiveItems).ToList();
                        }

                        if (!flags.RandomWaresIncludesSpecialGear)
                        {
                            excludeItemsFromRandomShops.AddRange(ItemLists.SpecialGear);
                        }

                        shopItemLocation = ShuffleShops(rng, flags.ImmediatePureAndSoftRequired, flags.RandomWares, excludeItemsFromRandomShops, flags.WorldWealth);
                        incentivesData   = new IncentiveData(rng, flags, overworldMap, shopItemLocation);
                    }

                    if (flags.Treasures)
                    {
                        ShuffleTreasures(rng, flags, incentivesData, shopItemLocation, overworldMap, teleporters);
                    }
                    break;
                }
                catch (InsaneException e)
                {
                    Console.WriteLine(e.Message);
                    if (maxRetries > (i + 1))
                    {
                        continue;
                    }
                    throw new InvalidOperationException(e.Message);
                }
            }

            if (flags.MagicShops)
            {
                ShuffleMagicShops(rng);
            }

            if (flags.MagicLevels)
            {
                FixWarpBug();                 // The warp bug only needs to be fixed if the magic levels are being shuffled
                ShuffleMagicLevels(rng, flags.MagicPermissions);
            }

            /*
             * if (flags.WeaponPermissions)
             * {
             *      ShuffleWeaponPermissions(rng);
             * }
             *
             * if (flags.ArmorPermissions)
             * {
             *      ShuffleArmorPermissions(rng);
             * }
             */

            if (flags.Rng)
            {
                ShuffleRng(rng);
            }

            if (flags.EnemyScripts)
            {
                ShuffleEnemyScripts(rng, flags.AllowUnsafePirates);
            }

            if (flags.EnemySkillsSpells)
            {
                ShuffleEnemySkillsSpells(rng);
            }

            if (flags.EnemyStatusAttacks)
            {
                if (flags.RandomStatusAttacks)
                {
                    RandomEnemyStatusAttacks(rng, flags.AllowUnsafePirates);
                }
                else
                {
                    ShuffleEnemyStatusAttacks(rng, flags.AllowUnsafePirates);
                }
            }

            if (flags.EnemyFormationsUnrunnable)
            {
                if (flags.EverythingUnrunnable)
                {
                    CompletelyUnrunnable();
                }
                else
                {
                    ShuffleUnrunnable(rng);
                }
            }

            if (flags.UnrunnablesStrikeFirstAndSuprise)
            {
                AllowStrikeFirstAndSuprise();
            }


            if (flags.EnemyFormationsSurprise)
            {
                ShuffleSurpriseBonus(rng);
            }

            // Put this before other encounter / trap tile edits.
            if (flags.AllowUnsafeMelmond)
            {
                EnableMelmondGhetto();
            }

            // After unrunnable shuffle and before formation shuffle. Perfect!
            if (flags.WarMECHMode != WarMECHMode.Vanilla)
            {
                WarMECHNpc(flags.WarMECHMode, rng, maps);
            }

            if (flags.WarMECHMode == WarMECHMode.Unleashed)
            {
                UnleashWarMECH();
            }

            if (flags.FiendShuffle)
            {
                FiendShuffle(rng);
            }

            if (flags.FormationShuffleMode != FormationShuffleModeEnum.None)
            {
                ShuffleEnemyFormations(rng, flags.FormationShuffleMode);
            }

            if (flags.EnemyTrapTiles)
            {
                ShuffleTrapTiles(rng, flags.RandomTrapFormations);
            }

            if (flags.OrdealsPillars)
            {
                ShuffleOrdeals(rng, maps);
            }

            if (flags.SkyCastle4FMazeMode == SkyCastle4FMazeMode.Maze)
            {
                DoSkyCastle4FMaze(rng, maps);
            }
            else if (flags.SkyCastle4FMazeMode == SkyCastle4FMazeMode.Teleporters)
            {
                ShuffleSkyCastle4F(rng, maps);
            }

            if (flags.ConfusedOldMen)
            {
                EnableConfusedOldMen(rng);
            }

            if (flags.EarlyOrdeals)
            {
                EnableEarlyOrdeals();
            }

            if (flags.ChaosRush)
            {
                EnableChaosRush();
            }

            if (flags.EarlySarda && !flags.NPCItems)
            {
                EnableEarlySarda();
            }

            if (flags.EarlySage && !flags.NPCItems)
            {
                EnableEarlySage();
            }

            if (flags.FreeBridge)
            {
                EnableFreeBridge();
            }

            if (flags.FreeAirship)
            {
                EnableFreeAirship();
            }

            if (flags.FreeOrbs)
            {
                EnableFreeOrbs();
            }

            if (flags.FreeCanal)
            {
                EnableFreeCanal();
            }

            if (flags.FreeLute)
            {
                EnableFreeLute();
            }

            if (flags.NoPartyShuffle)
            {
                DisablePartyShuffle();
            }

            if (flags.SpeedHacks)
            {
                EnableSpeedHacks();
            }

            if (flags.IdentifyTreasures)
            {
                EnableIdentifyTreasures();
            }

            if (flags.Dash)
            {
                EnableDash();
            }

            if (flags.BuyTen)
            {
                EnableBuyTen();
            }

            if (flags.WaitWhenUnrunnable)
            {
                ChangeUnrunnableRunToWait();
            }

            if (flags.EnableCritNumberDisplay)
            {
                EnableCritNumberDisplay();
            }

            if (flags.NPCSwatter)
            {
                EnableNPCSwatter();
            }

            if (flags.EasyMode)
            {
                EnableEasyMode();
            }

            if (flags.HouseMPRestoration || flags.HousesFillHp)
            {
                FixHouse(flags.HouseMPRestoration, flags.HousesFillHp);
            }

            if (flags.WeaponStats)
            {
                FixWeaponStats();
            }

            if (flags.ChanceToRun)
            {
                FixChanceToRun();
            }

            if (flags.EnemyStatusAttackBug)
            {
                FixEnemyStatusAttackBug();
            }

            if (flags.BlackBeltAbsorb)
            {
                FixBBAbsorbBug();
            }

            if (flags.BlackBeltMDEF)
            {
                RemakeStyleMasterMDEF();
            }

            if (flags.ImproveTurnOrderRandomization)
            {
                ImproveTurnOrderRandomization(rng);
            }

            if (flags.EnemyElementalResistancesBug)
            {
                FixEnemyElementalResistances();
            }

            if (preferences.FunEnemyNames)
            {
                FunEnemyNames(preferences.TeamSteak);
            }

            var itemText = ReadText(ItemTextPointerOffset, ItemTextPointerBase, ItemTextPointerCount);
            itemText[(int)Item.Ribbon].Trim();

            ExpGoldBoost(flags.ExpBonus, flags.ExpMultiplier);
            ScalePrices(flags, itemText, rng, flags.ClampMinimumPriceScale, shopItemLocation);
            ScaleEncounterRate(flags.EncounterRate / 30.0, flags.DungeonEncounterRate / 30.0);

            overworldMap.ApplyMapEdits();
            WriteMaps(maps);

            WriteText(itemText, ItemTextPointerOffset, ItemTextPointerBase, ItemTextOffset, UnusedGoldItems);

            if (flags.EnemyScaleFactor > 1)
            {
                ScaleEnemyStats(flags.EnemyScaleFactor, flags.WrapStatOverflow, flags.IncludeMorale, rng, flags.ClampMinimumStatScale);
            }

            if (flags.BossScaleFactor > 1)
            {
                ScaleBossStats(flags.BossScaleFactor, flags.WrapStatOverflow, flags.IncludeMorale, rng, flags.ClampMinimumBossStatScale);
            }

            PartyComposition(rng, flags);

            if (flags.RecruitmentMode)
            {
                PubReplaceClinic(rng);
            }

            if (flags.MapCanalBridge)
            {
                EnableCanalBridge();
            }

            if (flags.NoDanMode)
            {
                NoDanMode();
            }

            SetProgressiveScaleMode(flags.ProgressiveScaleMode);

            // We have to do "fun" stuff last because it alters the RNG state.
            RollCredits(rng);

            if (preferences.DisableDamageTileFlicker)
            {
                DisableDamageTileFlicker();
            }

            if (preferences.ThirdBattlePalette)
            {
                UseVariablePaletteForCursorAndStone();
            }

            if (preferences.PaletteSwap)
            {
                PaletteSwap(rng);
            }

            if (preferences.TeamSteak)
            {
                TeamSteak();
            }

            if (preferences.Music != MusicShuffle.None)
            {
                ShuffleMusic(preferences.Music, rng);
            }

            WriteSeedAndFlags(Version, seed.ToHex(), Flags.EncodeFlagsText(flags));
            ExtraTrackingAndInitCode();
        }
Exemple #2
0
        public void Randomize(Blob seed, Flags flags, Preferences preferences)
        {
            MT19337 rng;

            using (SHA256 hasher = SHA256.Create())
            {
                Blob FlagsBlob    = Encoding.UTF8.GetBytes(Flags.EncodeFlagsText(flags));
                Blob SeedAndFlags = Blob.Concat(new Blob[] { FlagsBlob, seed });
                Blob hash         = hasher.ComputeHash(SeedAndFlags);
                rng = new MT19337(BitConverter.ToUInt32(hash, 0));
            }
            if (flags.TournamentSafe)
            {
                AssureSafe();
            }

            UpgradeToMMC3();
            MakeSpace();
            Bank1E();
            Bank1B();
            EasterEggs();
            DynamicWindowColor(preferences.MenuColor);
            PermanentCaravan();
            ShiftEarthOrbDown();
            CastableItemTargeting();
            FixEnemyPalettes();       // fixes a bug in the original game's programming that causes third enemy slot's palette to render incorrectly
            FixWarpBug();             // The warp bug must be fixed for magic level shuffle and spellcrafter
            SeparateUnrunnables();
            var talkroutines = new TalkRoutines();
            var npcdata      = new NPCdata(this);

            UpdateDialogs(npcdata);

            if (flags.TournamentSafe)
            {
                Put(0x3FFE3, Blob.FromHex("66696E616C2066616E74617379"));
            }

            flags = Flags.ConvertAllTriState(flags, rng);

            TeleportShuffle teleporters      = new TeleportShuffle();
            var             palettes         = OverworldMap.GeneratePalettes(Get(OverworldMap.MapPaletteOffset, MapCount * OverworldMap.MapPaletteSize).Chunk(OverworldMap.MapPaletteSize));
            var             overworldMap     = new OverworldMap(this, flags, palettes, teleporters);
            var             maps             = ReadMaps();
            var             shopItemLocation = ItemLocations.CaravanItemShop1;
            var             oldItemNames     = ReadText(ItemTextPointerOffset, ItemTextPointerBase, ItemTextPointerCount);

            if (flags.EFGWaterfall || flags.EFGEarth1 || flags.EFGEarth2)
            {
                MapRequirements      reqs;
                MapGeneratorStrategy strategy;
                MapGenerator         generator = new MapGenerator();
                if (flags.EFGWaterfall)
                {
                    reqs = new MapRequirements
                    {
                        MapId = MapId.Waterfall,
                        Rom   = this,
                    };
                    strategy = MapGeneratorStrategy.WaterfallClone;
                    CompleteMap waterfall = generator.Generate(rng, strategy, reqs);

                    // Should add more into the reqs so that this can be done inside the generator.
                    teleporters.Waterfall.SetEntrance(waterfall.Entrance);
                    overworldMap.PutOverworldTeleport(OverworldTeleportIndex.Waterfall, teleporters.Waterfall);
                    maps[(int)MapId.Waterfall] = waterfall.Map;
                }

                if (flags.EFGEarth1)
                {
                    reqs = new MapRequirements
                    {
                        MapId = MapId.EarthCaveB1,
                        Rom   = this,
                    };

                    strategy = MapGeneratorStrategy.Square;
                    var earthB1 = generator.Generate(rng, strategy, reqs);

                    // Should add more into the reqs so that this can be done inside the generator.
                    teleporters.EarthCave1.SetEntrance(earthB1.Entrance);
                    overworldMap.PutOverworldTeleport(OverworldTeleportIndex.EarthCave1, teleporters.EarthCave1);
                    maps[(int)MapId.EarthCaveB1] = earthB1.Map;
                }
                if (flags.EFGEarth2)
                {
                    reqs = new MapRequirements
                    {
                        MapId = MapId.EarthCaveB2,
                        Rom   = this,
                    };

                    strategy = MapGeneratorStrategy.Square;
                    var earthB2 = generator.Generate(rng, strategy, reqs);

                    // Should add more into the reqs so that this can be done inside the generator.
                    teleporters.EarthCave2.SetEntrance(earthB2.Entrance);
                    overworldMap.PutStandardTeleport(TeleportIndex.EarthCave2, teleporters.EarthCave2, OverworldTeleportIndex.EarthCave1);
                    maps[(int)MapId.EarthCaveB2] = earthB2.Map;
                }
            }

            var flippedMaps = new List <MapId>();

            if ((bool)flags.FlipDungeons)
            {
                flippedMaps = HorizontalFlipDungeons(rng, maps, teleporters, overworldMap);
            }

            if ((bool)flags.RandomizeFormationEnemizer)
            {
                DoEnemizer(rng, (bool)flags.RandomizeEnemizer, (bool)flags.RandomizeFormationEnemizer, flags.EnemizerDontMakeNewScripts);
            }

            if (preferences.ModernBattlefield)
            {
                EnableModernBattlefield();
            }

            if ((bool)flags.TitansTrove)
            {
                EnableTitansTrove(maps);
            }

            if ((bool)flags.LefeinShops)
            {
                EnableLefeinShops(maps);
            }

            // This has to be done before we shuffle spell levels.
            if (flags.SpellBugs)
            {
                FixSpellBugs();
            }

            //must be done before spells get shuffled around otherwise we'd be changing a spell that isnt lock
            if (flags.LockMode != LockHitMode.Vanilla)
            {
                ChangeLockMode(flags.LockMode);
            }

            if (flags.EnemySpellsTargetingAllies)
            {
                FixEnemyAOESpells();
            }

            if (flags.AllSpellLevelsForKnightNinja)
            {
                KnightNinjaChargesForAllLevels();
            }

            if (flags.BuffHealingSpells)
            {
                BuffHealingSpells();
            }

            UpdateMagicAutohitThreshold(rng, flags.MagicAutohitThreshold);

            if ((bool)flags.GenerateNewSpellbook)
            {
                CraftNewSpellbook(rng, (bool)flags.SpellcrafterMixSpells, flags.LockMode, (bool)flags.MagicLevels, (bool)flags.SpellcrafterRetainPermissions);
            }

            if ((bool)flags.MagisizeWeapons)
            {
                MagisizeWeapons(rng, (bool)flags.MagisizeWeaponsBalanced);
            }

            if ((bool)flags.ItemMagic)
            {
                ShuffleItemMagic(rng, (bool)flags.BalancedItemMagicShuffle);
            }

            if ((bool)flags.GuaranteedRuseItem)
            {
                CraftRuseItem();
            }

            if ((bool)flags.ShortToFR)
            {
                ShortenToFR(maps, (bool)flags.PreserveFiendRefights, (bool)flags.PreserveAllFiendRefights, rng);
            }

            if (((bool)flags.Treasures) && flags.ShardHunt && !flags.FreeOrbs)
            {
                EnableShardHunt(rng, talkroutines, flags.ShardCount);
            }

            if ((bool)flags.TransformFinalFormation && !flags.SpookyFlag)
            {
                TransformFinalFormation((FinalFormation)rng.Between(0, Enum.GetValues(typeof(FinalFormation)).Length - 1), flags.EvadeCap);
            }

            var maxRetries = 8;

            for (var i = 0; i < maxRetries; i++)
            {
                try
                {
                    overworldMap = new OverworldMap(this, flags, palettes, teleporters);
                    if (((bool)flags.Entrances || (bool)flags.Floors || (bool)flags.Towns) && ((bool)flags.Treasures) && ((bool)flags.NPCItems))
                    {
                        overworldMap.ShuffleEntrancesAndFloors(rng, flags);

                        // Disable the Princess Warp back to Castle Coneria
                        if ((bool)flags.Entrances || (bool)flags.Floors)
                        {
                            talkroutines.ReplaceChunk(newTalkRoutines.Talk_Princess1, Blob.FromHex("20CC90"), Blob.FromHex("EAEAEA"));
                        }
                    }

                    if ((bool)flags.Treasures && (bool)flags.ShuffleObjectiveNPCs)
                    {
                        overworldMap.ShuffleObjectiveNPCs(rng);
                    }

                    IncentiveData incentivesData = new IncentiveData(rng, flags, overworldMap, shopItemLocation);

                    if (((bool)flags.Shops))
                    {
                        var excludeItemsFromRandomShops = new List <Item>();
                        if ((bool)flags.Treasures)
                        {
                            excludeItemsFromRandomShops = incentivesData.ForcedItemPlacements.Select(x => x.Item).Concat(incentivesData.IncentiveItems).ToList();
                        }

                        if (!((bool)flags.RandomWaresIncludesSpecialGear))
                        {
                            excludeItemsFromRandomShops.AddRange(ItemLists.SpecialGear);
                            if ((bool)flags.GuaranteedRuseItem)
                            {
                                excludeItemsFromRandomShops.Add(Item.PowerRod);
                            }
                        }

                        if ((bool)flags.NoMasamune)
                        {
                            excludeItemsFromRandomShops.Add(Item.Masamune);
                        }

                        shopItemLocation = ShuffleShops(rng, (bool)flags.ImmediatePureAndSoftRequired, ((bool)flags.RandomWares), excludeItemsFromRandomShops, flags.WorldWealth);
                        incentivesData   = new IncentiveData(rng, flags, overworldMap, shopItemLocation);
                    }

                    if ((bool)flags.Treasures)
                    {
                        generatedPlacement = ShuffleTreasures(rng, flags, incentivesData, shopItemLocation, overworldMap, teleporters);
                    }
                    break;
                }
                catch (InsaneException e)
                {
                    Console.WriteLine(e.Message);
                    if (maxRetries > (i + 1))
                    {
                        continue;
                    }
                    throw new InvalidOperationException(e.Message);
                }
            }

            // Change Astos routine so item isn't lost in wall of text
            if ((bool)flags.NPCItems || (bool)flags.NPCFetchItems || (bool)flags.ShuffleAstos)
            {
                talkroutines.Replace(newTalkRoutines.Talk_Astos, Blob.FromHex("A674F005BD2060F027A5738561202096B020A572203D96A575200096A476207F90207392A5611820109F201896A9F060A57060"));
            }

            npcdata.UpdateItemPlacement(generatedPlacement);

            if ((bool)flags.MagicShopLocs)
            {
                ShuffleMagicLocations(rng);
            }

            if (((bool)flags.MagicShops))
            {
                ShuffleMagicShops(rng);
            }

            if (((bool)flags.MagicLevels))
            {
                ShuffleMagicLevels(rng, ((bool)flags.MagicPermissions), (bool)flags.MagicLevelsTiered, (bool)flags.MagicLevelsMixed, (bool)!flags.GenerateNewSpellbook);
            }

            new StartingInventory(rng, flags, this).SetStartingInventory();

            /*
             * if (flags.WeaponPermissions)
             * {
             *      ShuffleWeaponPermissions(rng);
             * }
             *
             * if (flags.ArmorPermissions)
             * {
             *      ShuffleArmorPermissions(rng);
             * }
             */

            if (flags.SaveGameWhenGameOver)
            {
                EnableSaveOnDeath(flags);
            }

            // Ordered before RNG shuffle. In the event that both flags are on, RNG shuffle depends on this.
            if (((bool)flags.FixMissingBattleRngEntry))
            {
                FixMissingBattleRngEntry();
            }

            if (((bool)flags.Rng))
            {
                ShuffleRng(rng);
            }

            if (((bool)flags.EnemyScripts))
            {
                ShuffleEnemyScripts(rng, (bool)flags.AllowUnsafePirates, (bool)!flags.BossScriptsOnly, ((bool)flags.EnemySkillsSpellsTiered || (bool)flags.ScaryImps), (bool)flags.ScaryImps);
            }

            if (((bool)flags.EnemySkillsSpells))
            {
                if ((bool)flags.EnemySkillsSpellsTiered && (bool)!flags.BossSkillsOnly)
                {
                    GenerateBalancedEnemyScripts(rng, (bool)flags.SwolePirates);
                    ShuffleEnemySkillsSpells(rng, false);
                }
                else
                {
                    ShuffleEnemySkillsSpells(rng, (bool)!flags.BossSkillsOnly);
                }
            }

            if (((bool)flags.EnemyStatusAttacks))
            {
                if (((bool)flags.RandomStatusAttacks))
                {
                    RandomEnemyStatusAttacks(rng, (bool)flags.AllowUnsafePirates, (bool)flags.DisableStunTouch);
                }
                else
                {
                    ShuffleEnemyStatusAttacks(rng, (bool)flags.AllowUnsafePirates);
                }
            }

            if (flags.Runnability == Runnability.Random)
            {
                flags.Runnability = (Runnability)Rng.Between(rng, 0, 3);
            }

            if (flags.Runnability == Runnability.AllRunnable)
            {
                CompletelyRunnable();
            }
            else if (flags.Runnability == Runnability.AllUnrunnable)
            {
                CompletelyUnrunnable();
            }
            else if (flags.Runnability == Runnability.Shuffle)
            {
                ShuffleUnrunnable(rng);
            }

            // Always on to supply the correct changes for WaitWhenUnrunnable
            AllowStrikeFirstAndSurprise(flags.WaitWhenUnrunnable, (bool)flags.UnrunnablesStrikeFirstAndSurprise);

            if (((bool)flags.EnemyFormationsSurprise))
            {
                ShuffleSurpriseBonus(rng);
            }

            // Put this before other encounter / trap tile edits.
            if ((bool)flags.AllowUnsafeMelmond)
            {
                EnableMelmondGhetto(flags.EnemizerEnabled);
            }

            // After unrunnable shuffle and before formation shuffle. Perfect!
            if (flags.WarMECHMode != WarMECHMode.Vanilla)
            {
                WarMECHNpc(flags.WarMECHMode, npcdata, rng, maps);
            }

            if (flags.WarMECHMode == WarMECHMode.Unleashed)
            {
                UnleashWarMECH();
            }

            if ((bool)flags.ClassAsNpcFiends || (bool)flags.ClassAsNpcKeyNPC)
            {
                ClassAsNPC(flags, talkroutines, npcdata, flippedMaps, rng);
            }

            if ((bool)flags.FiendShuffle)
            {
                FiendShuffle(rng);
            }

            if (flags.FormationShuffleMode != FormationShuffleMode.None && !flags.EnemizerEnabled)
            {
                ShuffleEnemyFormations(rng, flags.FormationShuffleMode);
            }

            if ((bool)flags.RemoveTrapTiles)
            {
                RemoveTrapTiles(flags.EnemizerEnabled);
            }

            if (((bool)flags.EnemyTrapTiles) && !flags.EnemizerEnabled)
            {
                ShuffleTrapTiles(rng, ((bool)flags.RandomTrapFormations));
            }

            if ((bool)flags.OrdealsPillars)
            {
                ShuffleOrdeals(rng, maps);
            }

            if (flags.SkyCastle4FMazeMode == SkyCastle4FMazeMode.Maze)
            {
                DoSkyCastle4FMaze(rng, maps);
            }
            else if (flags.SkyCastle4FMazeMode == SkyCastle4FMazeMode.Teleporters)
            {
                ShuffleSkyCastle4F(rng, maps);
            }

            if ((bool)flags.ConfusedOldMen)
            {
                EnableConfusedOldMen(rng);
            }

            if ((bool)flags.EarlyOrdeals)
            {
                EnableEarlyOrdeals();
            }

            if (flags.ChaosRush)
            {
                EnableChaosRush();
            }
            if ((bool)flags.EarlyKing)
            {
                EnableEarlyKing(npcdata);
            }

            if ((bool)flags.EarlySarda)
            {
                EnableEarlySarda(npcdata);
            }

            if ((bool)flags.EarlySage)
            {
                EnableEarlySage(npcdata);
            }

            if ((bool)flags.FreeBridge)
            {
                EnableFreeBridge();
            }

            if ((bool)flags.FreeAirship)
            {
                EnableFreeAirship();
            }

            if ((bool)flags.FreeShip)
            {
                EnableFreeShip();
            }

            if (flags.FreeOrbs)
            {
                EnableFreeOrbs();
            }

            if ((bool)flags.FreeCanal)
            {
                EnableFreeCanal((bool)flags.NPCItems, npcdata);
            }

            if ((bool)flags.FreeCanoe)
            {
                EnableFreeCanoe();
            }

            if ((bool)flags.FreeLute)
            {
                EnableFreeLute();
            }

            if ((bool)flags.FreeTail && !(bool)flags.NoTail)
            {
                EnableFreeTail();
            }

            if (flags.NoPartyShuffle)
            {
                DisablePartyShuffle();
            }

            if (flags.SpeedHacks)
            {
                EnableSpeedHacks();
            }

            if (flags.IdentifyTreasures)
            {
                EnableIdentifyTreasures();
            }

            if (flags.Dash)
            {
                EnableDash();
            }

            if (flags.BuyTen)
            {
                EnableBuyQuantity();
            }

            if (flags.WaitWhenUnrunnable)
            {
                ChangeUnrunnableRunToWait();
            }

            if (flags.SpeedHacks && flags.EnableCritNumberDisplay)
            {
                EnableCritNumberDisplay();
            }

            if (flags.BattleMagicMenuWrapAround)
            {
                BattleMagicMenuWrapAround();
            }

            if (flags.NPCSwatter)
            {
                EnableNPCSwatter(npcdata);
            }

            if (flags.EasyMode)
            {
                EnableEasyMode();
            }

            if ((bool)flags.TrappedChests || (bool)flags.TCMasaGuardian || (bool)flags.TrappedShards)
            {
                MonsterInABox(rng, flags);
            }

            if (flags.HouseMPRestoration || flags.HousesFillHp)
            {
                FixHouse(flags.HouseMPRestoration, flags.HousesFillHp);
            }

            if (flags.BBCritRate)
            {
                DontDoubleBBCritRates();
            }

            if (flags.WeaponCritRate)
            {
                DoubleWeaponCritRates();
            }

            //needs to go after item magic, moved after double weapon crit to have more control over the actual number of crit gained.
            if ((bool)flags.RandomWeaponBonus)
            {
                RandomWeaponBonus(rng, flags.RandomWeaponBonusLow, flags.RandomWeaponBonusHigh, (bool)flags.RandomWeaponBonusExcludeMasa);
            }

            if ((bool)flags.RandomArmorBonus)
            {
                RandomArmorBonus(rng, flags.RandomArmorBonusLow, flags.RandomArmorBonusHigh);
            }

            if (flags.WeaponBonuses)
            {
                IncreaseWeaponBonus(flags.WeaponTypeBonusValue);
            }

            if (flags.WeaponStats)
            {
                FixWeaponStats();
            }

            if (flags.ChanceToRun)
            {
                FixChanceToRun();
            }

            if (flags.EnemyStatusAttackBug)
            {
                FixEnemyStatusAttackBug();
            }

            if (flags.BlackBeltAbsorb)
            {
                FixBBAbsorbBug();
            }

            if (flags.MDefMode != MDEFGrowthMode.None)
            {
                MDefChanges(flags.MDefMode);
            }

            if (flags.ThiefHitRate)
            {
                ThiefHitRate();
            }

            if (flags.ImproveTurnOrderRandomization)
            {
                ImproveTurnOrderRandomization(rng);
            }

            if (flags.FixHitChanceCap)
            {
                FixHitChanceCap();
            }

            if (flags.EnemyElementalResistancesBug)
            {
                FixEnemyElementalResistances();
            }

            if (preferences.FunEnemyNames && !flags.EnemizerEnabled)
            {
                FunEnemyNames(preferences.TeamSteak);
            }

            var itemText = ReadText(ItemTextPointerOffset, ItemTextPointerBase, ItemTextPointerCount);

            itemText[(int)Item.Ribbon] = itemText[(int)Item.Ribbon].Remove(7);

            if ((bool)flags.HintsVillage || (bool)flags.HintsDungeon)
            {
                if ((bool)flags.HintsDungeon)
                {
                    SetDungeonNPC(flippedMaps, rng);
                }

                NPCHints(rng, npcdata, flags, overworldMap);
            }

            ExpGoldBoost(flags.ExpBonus, flags.ExpMultiplier);
            ScalePrices(flags, itemText, rng, ((bool)flags.ClampMinimumPriceScale), shopItemLocation);
            ScaleEncounterRate(flags.EncounterRate / 30.0, flags.DungeonEncounterRate / 30.0);

            overworldMap.ApplyMapEdits();
            WriteMaps(maps);

            WriteText(itemText, ItemTextPointerOffset, ItemTextPointerBase, ItemTextOffset, UnusedGoldItems);

            if ((bool)flags.SwolePirates)
            {
                EnableSwolePirates();
            }

            if (flags.EnemyScaleStatsHigh != 100 || flags.EnemyScaleStatsLow != 100 || ((bool)flags.SeparateEnemyHPScaling && (flags.EnemyScaleHpLow != 100 || flags.EnemyScaleHpHigh != 100)))
            {
                ScaleEnemyStats(rng, flags);
            }

            if (flags.BossScaleStatsHigh != 100 || flags.BossScaleStatsLow != 100 || ((bool)flags.SeparateBossHPScaling && (flags.BossScaleHpLow != 100 || flags.BossScaleHpHigh != 100)))
            {
                ScaleBossStats(rng, flags);
            }

            PartyComposition(rng, flags, preferences);

            if (((bool)flags.RecruitmentMode))
            {
                PubReplaceClinic(rng, flags);
            }

            if ((bool)flags.ChangeMaxMP)
            {
                SetMPMax(flags.RedMageMaxMP, flags.WhiteMageMaxMP, flags.BlackMageMaxMP, flags.KnightMaxMP, flags.NinjaMaxMP);
            }

            if ((bool)flags.ShuffleAstos)
            {
                ShuffleAstos(flags, npcdata, talkroutines, rng);
            }

            if ((bool)flags.EnablePoolParty)
            {
                EnablePoolParty(flags, rng);
            }

            if ((bool)flags.MapCanalBridge)
            {
                EnableCanalBridge();
            }

            if (flags.NoDanMode)
            {
                NoDanMode();
            }

            SetProgressiveScaleMode(flags);

            if ((bool)flags.RandomizeClass)
            {
                RandomizeClass(rng, flags, oldItemNames);
            }

            if ((bool)flags.EnableRandomPromotions)
            {
                EnableRandomPromotions(flags, rng);
            }

            if (flags.DisableTentSaving)
            {
                CannotSaveOnOverworld();
            }

            if (flags.DisableInnSaving)
            {
                CannotSaveAtInns();
            }

            if (flags.PacifistMode && !flags.SpookyFlag)
            {
                PacifistEnd(talkroutines, npcdata, (bool)flags.EnemyTrapTiles || flags.EnemizerEnabled);
            }

            if (flags.ShopInfo)
            {
                ShopUpgrade();
            }

            if (flags.SpookyFlag)
            {
                Spooky(talkroutines, npcdata, rng, flags);
            }

            if (flags.InventoryAutosort && !(preferences.RenounceAutosort))
            {
                EnableInventoryAutosort();
            }

            // We have to do "fun" stuff last because it alters the RNG state.
            // Back up Rng so that fun flags are uniform when different ones are selected
            uint funRngSeed = rng.Next();

            RollCredits(rng);

            if (preferences.DisableDamageTileFlicker)
            {
                DisableDamageTileFlicker();
            }

            if (preferences.ThirdBattlePalette)
            {
                UseVariablePaletteForCursorAndStone();
            }

            if (preferences.PaletteSwap && !flags.EnemizerEnabled)
            {
                rng = new MT19337(funRngSeed);
                PaletteSwap(rng);
            }

            if (preferences.TeamSteak && !(bool)flags.RandomizeEnemizer)
            {
                TeamSteak();
            }

            if (preferences.ChangeLute)
            {
                rng = new MT19337(funRngSeed);
                ChangeLute(rng);
            }

            rng = new MT19337(funRngSeed);

            HurrayDwarfFate(preferences.HurrayDwarfFate, npcdata, rng);

            if (preferences.Music != MusicShuffle.None)
            {
                rng = new MT19337(funRngSeed);
                ShuffleMusic(preferences.Music, rng);
            }

            if (preferences.DisableSpellCastFlash)
            {
                DisableSpellCastScreenFlash();
            }

            npcdata.WriteNPCdata(this);
            talkroutines.WriteRoutines(this);
            talkroutines.UpdateNPCRoutines(this, npcdata);

            WriteSeedAndFlags(seed.ToHex(), Flags.EncodeFlagsText(flags));
            ExtraTrackingAndInitCode(flags);
        }
Exemple #3
0
        private void ExtraTrackingAndInitCode(Flags flags)
        {
            // Expanded game init code, does several things:
            //	- Encounter table emu/hardware fix
            //	- track hard/soft resets
            //	- initialize tracking variables if no game is saved
            PutInBank(0x0F, 0x8000, Blob.FromHex("A9008D00208D012085FEA90885FF85FDA51BC901D00160A901851BA94DC5F9F008A9FF85F585F685F7182088C8B049A94DC5F918F013ADA36469018DA364ADA46469008DA464189010ADA56469018DA564ADA66469008DA664A9008DFD64A200187D00647D00657D00667D0067E8D0F149FF8DFD64189010A2A0A9009D00609D0064E8D0F7EEFB64ADFB648DFB6060"));
            Put(0x7C012, Blob.FromHex("A90F2003FE200080EAEAEAEAEAEAEAEA"));


            // Move controller handling out of bank 1F
            // This bit of code is also altered to allow a hard reset using Up+A on controller 2
            PutInBank(0x0F, 0x8200, Blob.FromHex("20108220008360"));
            PutInBank(0x0F, 0x8210, Blob.FromHex("A9018D1640A9008D1640A208AD16402903C9012620AD17402903C901261ECAD0EBA51EC988F008C948F001604C2EFE20A8FE20A8FE20A8FEA2FF9AA900851E9500CAD0FBA6004C12C0"));
            PutInBank(0x0F, 0x8300, Blob.FromHex("A5202903F002A2038611A520290CF0058A090C8511A52045212511452185214520AA2910F00EA5202910F002E623A521491085218A2920F00EA5202920F002E622A521492085218A2940F00EA5202940F002E625A521494085218A2980F00EA5202980F002E624A5214980852160"));
            PutInBank(0x1F, 0xD7C2, CreateLongJumpTableEntry(0x0F, 0x8200));

            // Battles use 2 separate and independent controller handlers for a total of 3 (because why not), so we patch these to respond to Up+A also
            PutInBank(0x0F, 0x8580, Blob.FromHex("A0018C1640888C1640A008AD16404AB0014A6EB368AD17402903C901261E88D0EAA51EC988F00BC948F004ADB368604C2EFE20A8FE20A8FE20A8FEA2FF9AA900851E9500CAD0FBA6004C12C0"));
            PutInBank(0x1F, 0xD828, CreateLongJumpTableEntry(0x0F, 0x8580));
            // PutInBank(0x0B, 0x9A06, Blob.FromHex("4C28D8")); Included in bank 1B changes
            PutInBank(0x0C, 0x97C7, Blob.FromHex("2027F22028D82029ABADB36860"));


            // Put LongJump routine 6 bytes after UpdateJoy used to be
            PutInBank(0x1F, 0xD7C8, Blob.FromHex("85E99885EA6885EB6885ECA001B1EB85EDC8B1EB85EEC8ADFC6085E8B1EB2003FEA9D748A9F548A5E9A4EA6CED0085E9A5E82003FEA5E960"));
            // LongJump entries can start at 0xD800 and must stop before 0xD850 (at which point additional space will need to be freed to make room)

            // Patches for various tracking variables follow:
            // Pedometer + chests opened
            PutInBank(0x0F, 0x8100, Blob.FromHex("18A532D027A52D2901F006A550D01DF00398D018ADA06069018DA060ADA16069008DA160ADA26069008DA260A52F8530A9FF8518A200A000BD00622904F001C8E8D0F5988DB7606060"));
            Put(0x7D023, Blob.FromHex("A90F2003FE200081"));
            // Count number of battles
            PutInBank(0x0F, 0x8400, Blob.FromHex("18ADA76069018DA7609003EEA86020A8FE60"));
            PutInBank(0x1F, 0xD800, CreateLongJumpTableEntry(0x0F, 0x8400));
            PutInBank(0x1F, 0xF28D, Blob.FromHex("2000D8"));
            // Ambushes / Strike First
            PutInBank(0x0F, 0x8420, Blob.FromHex("AD5668C90B9015C95A901F18ADAB6069018DAB609014EEAC6018900E18ADA96069018DA9609003EEAA60AC5668AE576860"));
            PutInBank(0x1F, 0xD806, CreateLongJumpTableEntry(0x0F, 0x8420));
            Put(0x313FB, Blob.FromHex("eaeaea2006D8"));
            // Runs
            PutInBank(0x0F, 0x8480, Blob.FromHex("AD5868F00E18ADAD6069018DAD609003EEAE60AD586860"));
            PutInBank(0x1F, 0xD81C, CreateLongJumpTableEntry(0x0F, 0x8480));
            Put(0x32418, Blob.FromHex("201CD8"));
            // Physical Damage
            PutInBank(0x0F, 0x84B0, Blob.FromHex("8E7D68AD8768F01DADB2606D82688DB260ADB3606D83688DB360ADB46069008DB46018901AADAF606D82688DAF60ADB0606D83688DB060ADB16069008DB160AE7D6860"));
            PutInBank(0x1F, 0xD822, CreateLongJumpTableEntry(0x0F, 0x84B0));
            Put(0x32968, Blob.FromHex("2022D8"));
            // Magic Damage
            PutInBank(0x0F, 0x8500, Blob.FromHex("AD8A6C2980F01CADB2606D58688DB260ADB3606D59688DB360ADB46069008DB460901AADAF606D58688DAF60ADB0606D59688DB060ADB16069008DB160A912A212A00160"));
            PutInBank(0x1F, 0xD83A, CreateLongJumpTableEntry(0x0F, 0x8500));
            PutInBank(0x0C, 0xB8ED, Blob.FromHex("203AD8eaeaea"));
            // Party Wipes
            PutInBank(0x0F, 0x85D0, Blob.FromHex("EEB564A9008DFD64A200187D00647D00657D00667D0067E8D0F149FF8DFD64A952854B60"));
            PutInBank(0x1F, 0xD82E, CreateLongJumpTableEntry(0x0F, 0x85D0));
            //PutInBank(0x0B, 0x9AF5, Blob.FromHex("202ED8EAEA")); included in 1B changes
            // "Nothing Here"s
            PutInBank(0x0F, 0x8600, Blob.FromHex("A54429C2D005A545F00360A900EEB66060"));
            PutInBank(0x1F, 0xD834, CreateLongJumpTableEntry(0x0F, 0x8600));
            PutInBank(0x1F, 0xCBF3, Blob.FromHex("4C34D8"));

            // Add select button handler on game start menu to change color
            PutInBank(0x0F, 0x8620, Blob.FromHex("203CC4A662A9488540ADFB60D003EEFB60A522F022EEFB60ADFB60C90D300EF007A9018DFB60D005A90F8DFB60A90085222029EBA90060A90160"));
            PutInBank(0x1F, 0xD840, CreateLongJumpTableEntry(0x0F, 0x8620));
            Put(0x3A1B5, Blob.FromHex("2040D8D0034C56A1EA"));
            // Move Most of LoadBorderPalette_Blue out of the way to do a dynamic version.
            PutInBank(0x0F, 0x8700, Blob.FromHex("988DCE038DEE03A90F8DCC03A9008DCD03A9308DCF0360"));

            // Move DrawCommandMenu out of Bank F so we can add no Escape to it
            PutInBank(0x0F, 0x8740, Blob.FromHex("A000A200B91BFA9D9E6AE8C01BD015AD916D2903F00EA9139D9E6AE8C8A9F79D9E6AE8C8E005D0052090F6A200C8C01ED0D260"));

            // Create a clone of IsOnBridge that checks the canal too.
            PutInBank(0x0F, 0x8780, Blob.FromHex("AD0860F014A512CD0960D00DA513CD0A60D006A90085451860A512CD0D60D00DA513CD0E60D006A900854518603860"));

            // BB Absorb fix.
            //PutInBank(0x0F, 0x8800, Blob.FromHex("A000B186C902F005C908F00160A018B186301BC8B1863016C8B1863011C8B186300CA026B1861869010AA0209186A01CB186301AC8B1863015C8B1863010C8B186300BA026B186186901A022918660"));

            // Copyright overhaul, see 0F_8960_DrawSeedAndFlags.asm
            PutInBank(0x0F, 0x8980, Blob.FromHex("A9238D0620A9208D0620A200BD00898D0720E8E060D0F560"));

            // Fast Battle Boxes
            PutInBank(0x0F, 0x8A00, Blob.FromHex("A940858AA922858BA91E8588A969858960"));
            PutInBank(0x0F, 0x8A20, Blob.FromHex($"A9{BattleBoxDrawInRows}8DB96820A1F420E8F4A5881869208588A58969008589A58A186920858AA58B6900858BCEB968D0DE60"));

            // Fast Battle Boxes Undraw (Similar... yet different!)
            PutInBank(0x0F, 0x8A80, Blob.FromHex("A9A0858AA923858BA97E8588A96A858960"));
            PutInBank(0x0F, 0x8AA0, Blob.FromHex($"A9{BattleBoxUndrawRows}8DB96820A1F420E8F4A58838E9208588A589E9008589A58A38E920858AA58BE900858BCEB968D0DE60"));

            // Softlock fix
            Put(0x7C956, Blob.FromHex("A90F2003FE4C008B"));
            PutInBank(0x0F, 0x8B00, Blob.FromHex("BAE030B01E8A8D1001A9F4AAA9FBA8BD0001990001CA88E010D0F4AD1001186907AA9AA52948A52A48A50D48A54848A549484C65C9"));

            // Change INT to MDEF in the Status screen
            Put(0x388F5, Blob.FromHex("968D8E8F"));
            Data[0x38DED] = 0x25;

            //Key Items + Progressive Scaling
            if (flags.ProgressiveScaleMode == ProgressiveScaleMode.OrbProgressiveSlow || flags.ProgressiveScaleMode == ProgressiveScaleMode.OrbProgressiveMedium || flags.ProgressiveScaleMode == ProgressiveScaleMode.OrbProgressiveFast || flags.ProgressiveScaleMode == ProgressiveScaleMode.OrbProgressiveVFast)
            {
                if (flags.ShardHunt)
                {
                    PutInBank(0x0F, 0x9000, Blob.FromHex("AD35608DB86060"));
                }
                else
                {
                    PutInBank(0x0F, 0x9000, Blob.FromHex("A200AD3160F001E8AD3260F001E8AD3360F001E8AD3460F001E88EB86060"));
                }
            }
            else
            {
                PutInBank(0x0F, 0x9000, Blob.FromHex("A200AD2160F001E8AD2260F001E8AD2560F001E8AD2A60F001E8AD2B60F001E8AD2C60F001E8AD2E60F001E8AD3060F001E8AD0060F001E8AD1260F001E8AD0460F001E8AD0860F001E8AD0C60D001E8AD2360D007AD0A622902F001E8AD2460D007AD05622902F001E8AD2660D007AD08622902F001E8AD2760D007AD09622902F001E8AD2860D007AD0B622902F001E8AD2960D007AD14622901D001E8AD2D60D007AD0E622902F001E8AD2F60D007AD13622903F001E88EB86060"));
            }
            PutInBank(0x1F, 0xCFCB, CreateLongJumpTableEntry(0x0F, 0x9100));
            //Division routine
            PutInBank(0x0F, 0x90C0, Blob.FromHex("8A48A9008513A210261026112613A513C5129004E512851326102611CAD0EDA513851268AA60"));
            // Progressive scaling also writes to 0x9100 approaching 200 bytes, begin next Put at 0x9200.

            // Replace Overworld to Floor and Floor to Floor teleport code to JSR out to 0x9200 to set X / Y AND inroom from unused high bit of X.
            PutInBank(0x1F, 0xC1E2, Blob.FromHex("A9002003FEA545293FAABD00AC8510BD20AC8511BD40AC8548AABDC0AC8549A90F2003FE200092EAEAEAEAEAEA"));
            PutInBank(0x1F, 0xC968, Blob.FromHex("A9002003FEA645BD00AD8510BD40AD8511BD80AD8548AABDC0AC8549A90F2003FE200092EAEA"));
            PutInBank(0x0F, 0x9200, Blob.FromHex("A200A5100A9002A2814A38E907293F8529A5110A9002860D4A38E907293F852A60"));

            // Critical hit display for number of hits
            PutInBank(0x0F, 0x9280, FF1Text.TextToBytes("Critical hit!!", false));
            PutInBank(0x0F, 0x9290, FF1Text.TextToBytes(" Critical hits!", false));
            PutInBank(0x0F, 0x92A0, Blob.FromHex("AD6B68C901F01EA2019D3A6BA9118D3A6BA900E89D3A6BA0FFC8E8B990929D3A6BD0F6F00EA2FFA0FFC8E8B980929D3A6BD0F6A23AA06BA904201CF7EEF86A60"));

            // Enable 3 palettes in battle
            PutInBank(0x1F, 0xFDF1, CreateLongJumpTableEntry(0x0F, 0x9380));
            PutInBank(0x0F, 0x9380, Blob.FromHex("ADD16A2910F00BA020B9336D99866B88D0F7ADD16A290F8DD16A20A1F4AD0220A9028D1440A93F8D0620A9008D0620A000B9876B8D0720C8C020D0F5A93F8D0620A9008D06208D06208D062060"));
        }
Exemple #4
0
        public void Randomize(Blob seed, Flags flags)
        {
            var rng = new MT19337(BitConverter.ToUInt32(seed, 0));

            UpgradeToMMC3();
            MakeSpaceIn1F();
            EasterEggs();
            DynamicWindowColor();
            PermanentCaravan();
            ShiftEarthOrbDown();

            var overworldMap     = new OverworldMap(this, flags);
            var maps             = ReadMaps();
            var incentivesData   = new IncentiveData(rng, flags, overworldMap.MapLocationRequirements);
            var shopItemLocation = ItemLocations.CaravanItemShop1;

            if (flags.ModernBattlefield)
            {
                EnableModernBattlefield();
            }

            if (flags.TitansTrove)
            {
                EnableTitansTrove(maps);
            }

            // This has to be done before we shuffle spell levels.
            if (flags.SpellBugs)
            {
                FixSpellBugs();
            }

            if (flags.EnemySpellsTargetingAllies)
            {
                FixEnemyAOESpells();
            }

            if (flags.ItemMagic)
            {
                ShuffleItemMagic(rng);
            }

            if (flags.Shops)
            {
                var excludeItemsFromRandomShops = flags.Treasures
                                        ? incentivesData.ForcedItemPlacements.Select(x => x.Item).Concat(incentivesData.IncentiveItems).ToList()
                                        : new List <Item>();
                shopItemLocation = ShuffleShops(rng, flags.EnemyStatusAttacks, flags.RandomWares, excludeItemsFromRandomShops);
            }

            if (flags.Treasures || flags.NPCItems || flags.NPCFetchItems)
            {
                ShuffleTreasures(rng, flags, incentivesData, shopItemLocation, overworldMap.MapLocationRequirements);
            }

            if (flags.Treasures && flags.ShardHunt && !flags.ChaosRush)
            {
                EnableShardHunt(rng, flags.ExtraShards ? rng.Between(24, 30) : 16, maps, flags.NPCItems);
            }

            if (flags.TransformFinalFormation)
            {
                TransformFinalFormation((FinalFormation)rng.Between(0, Enum.GetValues(typeof(FinalFormation)).Length - 1));
            }

            if (flags.MagicShops)
            {
                ShuffleMagicShops(rng);
            }

            if (flags.MagicLevels)
            {
                FixWarpBug();                 // The warp bug only needs to be fixed if the magic levels are being shuffled
                ShuffleMagicLevels(rng, flags.MagicPermissions);
            }

            if (flags.Rng)
            {
                ShuffleRng(rng);
            }

            if (flags.EnemyScripts)
            {
                ShuffleEnemyScripts(rng, flags.AllowUnsafePirates);
            }

            if (flags.EnemySkillsSpells)
            {
                ShuffleEnemySkillsSpells(rng);
            }

            if (flags.EnemyStatusAttacks)
            {
                ShuffleEnemyStatusAttacks(rng, flags.AllowUnsafePirates);
            }

            if (flags.EnemyFormationsUnrunnable)
            {
                ShuffleUnrunnable(rng);
            }

            if (flags.EnemyFormationsSurprise)
            {
                ShuffleSurpriseBonus(rng);
            }

            if (flags.EnemyFormationsFrequency)
            {
                ShuffleEnemyFormations(rng);
            }

            if (flags.OrdealsPillars)
            {
                ShuffleOrdeals(rng, maps);
            }

            if (flags.SkyCastle4FTeleporters)
            {
                ShuffleSkyCastle4F(rng, maps);
            }

            if (flags.CrownlessOrdeals)
            {
                EnableEarlyOrdeals();
            }

            if (flags.ChaosRush)
            {
                EnableChaosRush();
            }

            if (flags.EarlySarda && !flags.NPCItems)
            {
                EnableEarlySarda();
            }

            if (flags.EarlySage && !flags.NPCItems)
            {
                EnableEarlySage();
            }

            if (flags.FreeBridge)
            {
                EnableFreeBridge();
            }

            if (flags.FreeAirship)
            {
                EnableFreeAirship();
            }

            if (flags.FreeOrbs)
            {
                EnableFreeOrbs();
            }

            if (flags.NoPartyShuffle)
            {
                DisablePartyShuffle();
            }

            if (flags.SpeedHacks)
            {
                EnableSpeedHacks();
            }

            if (flags.IdentifyTreasures)
            {
                EnableIdentifyTreasures();
            }

            if (flags.Dash)
            {
                EnableDash();
            }

            if (flags.BuyTen)
            {
                EnableBuyTen();
            }

            if (flags.WaitWhenUnrunnable)
            {
                ChangeUnrunnableRunToWait();
            }

            if (flags.EasyMode)
            {
                EnableEasyMode();
            }

            if (flags.HouseMPRestoration)
            {
                FixHouse();
            }

            if (flags.WeaponStats)
            {
                FixWeaponStats();
            }

            if (flags.ChanceToRun)
            {
                FixChanceToRun();
            }

            if (flags.EnemyStatusAttackBug)
            {
                FixEnemyStatusAttackBug();
            }

            if (flags.BlackBeltAbsorb)
            {
                FixBBAbsorbBug();
            }

            if (flags.ImproveTurnOrderRandomization)
            {
                ImproveTurnOrderRandomization(rng);
            }

            if (flags.EnemyElementalResistancesBug)
            {
                FixEnemyElementalResistances();
            }

            if (flags.FunEnemyNames)
            {
                FunEnemyNames(flags.TeamSteak);
            }

            var itemText = ReadText(ItemTextPointerOffset, ItemTextPointerBase, ItemTextPointerCount);

            FixVanillaRibbon(itemText);
            ExpGoldBoost(flags.ExpBonus, flags.ExpMultiplier);
            ScalePrices(flags.PriceScaleFactor, flags.ExpMultiplier, flags.VanillaStartingGold, itemText, rng);

            overworldMap.ApplyMapEdits();
            WriteMaps(maps);

            WriteText(itemText, ItemTextPointerOffset, ItemTextPointerBase, ItemTextOffset, UnusedGoldItems);

            if (flags.EnemyScaleFactor > 1)
            {
                ScaleEnemyStats(flags.EnemyScaleFactor, rng);
            }

            if (flags.ForcedPartyMembers > 0)
            {
                PartyRandomize(rng, flags.ForcedPartyMembers);
            }

            if (flags.MapCanalBridge)
            {
                EnableCanalBridge();
            }

            // We have to do "fun" stuff last because it alters the RNG state.
            RollCredits(rng);

            if (flags.PaletteSwap)
            {
                PaletteSwap(rng);
            }

            if (flags.TeamSteak)
            {
                TeamSteak();
            }

            if (flags.Music != MusicShuffle.None)
            {
                ShuffleMusic(flags.Music, rng);
            }

            WriteSeedAndFlags(Version, seed.ToHex(), Flags.EncodeFlagsText(flags));
            ExtraTrackingAndInitCode();
        }
        public static List <Item> GetIncentivePool(Flags flags)
        {
            var incentivePool = new List <Item>();

            if (flags.IncentivizeMasamune ?? false)
            {
                incentivePool.Add(Item.Masamune);
            }
            if (flags.IncentivizeKatana ?? false)
            {
                incentivePool.Add(Item.Katana);
            }
            if (flags.IncentivizeVorpal ?? false)
            {
                incentivePool.Add(Item.Vorpal);
            }
            if (flags.IncentivizeDefCastWeapon ?? false)
            {
                incentivePool.Add(Item.Defense);
            }
            if (flags.IncentivizeOffCastWeapon ?? false)
            {
                incentivePool.Add(Item.ThorHammer);
            }
            if (flags.IncentivizeOpal ?? false)
            {
                incentivePool.Add(Item.Opal);
            }
            if (flags.IncentivizeOtherCastArmor ?? false)
            {
                incentivePool.Add(Item.PowerGauntlets);
            }
            if (flags.IncentivizeDefCastArmor ?? false)
            {
                incentivePool.Add(Item.WhiteShirt);
            }
            if (flags.IncentivizeOffCastArmor ?? false)
            {
                incentivePool.Add(Item.BlackShirt);
            }
            if (flags.IncentivizeRibbon ?? false)
            {
                incentivePool.Add(Item.Ribbon);
            }
            if (flags.IncentivizeSlab ?? false)
            {
                incentivePool.Add(Item.Slab);
            }
            if (flags.IncentivizeRuby ?? false)
            {
                incentivePool.Add(Item.Ruby);
            }
            if (flags.IncentivizeFloater ?? false)
            {
                incentivePool.Add(Item.Floater);
            }
            if (flags.IncentivizeTnt ?? false)
            {
                incentivePool.Add(Item.Tnt);
            }
            if (flags.IncentivizeCrown ?? false)
            {
                incentivePool.Add(Item.Crown);
            }
            if (flags.IncentivizeTail ?? false)
            {
                incentivePool.Add(Item.Tail);
            }
            if (flags.IncentivizeAdamant ?? false)
            {
                incentivePool.Add(Item.Adamant);
            }

            if (flags.IncentivizeBridge)
            {
                incentivePool.Add(Item.Bridge);
            }
            if (flags.IncentivizeLute ?? false)
            {
                incentivePool.Add(Item.Lute);
            }
            if (flags.IncentivizeShip ?? false)
            {
                incentivePool.Add(Item.Ship);
            }
            if (flags.IncentivizeRod ?? false)
            {
                incentivePool.Add(Item.Rod);
            }
            if (flags.IncentivizeCanoe ?? false)
            {
                incentivePool.Add(Item.Canoe);
            }
            if (flags.IncentivizeCube ?? false)
            {
                incentivePool.Add(Item.Cube);
            }
            if (flags.IncentivizeBottle ?? false)
            {
                incentivePool.Add(Item.Bottle);
            }

            if (flags.IncentivizeKey ?? false)
            {
                incentivePool.Add(Item.Key);
            }
            if (flags.IncentivizeCrystal ?? false)
            {
                incentivePool.Add(Item.Crystal);
            }
            if (flags.IncentivizeOxyale ?? false)
            {
                incentivePool.Add(Item.Oxyale);
            }
            if (flags.IncentivizeCanal ?? false)
            {
                incentivePool.Add(Item.Canal);
            }
            if (flags.IncentivizeHerb ?? false)
            {
                incentivePool.Add(Item.Herb);
            }
            if (flags.IncentivizeChime ?? false)
            {
                incentivePool.Add(Item.Chime);
            }
            if (flags.IncentivizeXcalber ?? false)
            {
                incentivePool.Add(Item.Xcalber);
            }

            return(incentivePool.Concat(ItemLists.AllQuestItems).Distinct().ToList());
        }
Exemple #6
0
        public void Randomize(Blob seed, Flags flags)
        {
            var rng = new MT19337(BitConverter.ToUInt32(seed, 0));

            UpgradeToMMC3();
            MakeSpaceIn1F();
            EasterEggs();
            DynamicWindowColor();
            PermanentCaravan();
            ShiftEarthOrbDown();

            var palettes         = OverworldMap.GeneratePalettes(Get(OverworldMap.MapPaletteOffset, MapCount * OverworldMap.MapPaletteSize).Chunk(OverworldMap.MapPaletteSize));
            var overworldMap     = new OverworldMap(this, flags, palettes);
            var maps             = ReadMaps();
            var shopItemLocation = ItemLocations.CaravanItemShop1;

            if (flags.ModernBattlefield)
            {
                EnableModernBattlefield();
            }

            if (flags.TitansTrove)
            {
                EnableTitansTrove(maps);
            }

            // This has to be done before we shuffle spell levels.
            if (flags.SpellBugs)
            {
                FixSpellBugs();
            }

            if (flags.EnemySpellsTargetingAllies)
            {
                FixEnemyAOESpells();
            }

            if (flags.ItemMagic)
            {
                ShuffleItemMagic(rng);
            }

            if (flags.ShortToFR)
            {
                ShortenToFR(maps, flags.PreserveFiendRefights, rng);
            }

            if (flags.Treasures && flags.ShardHunt && !flags.ChaosRush)
            {
                EnableShardHunt(rng, flags.ExtraShards ? rng.Between(24, 30) : 16, flags.NPCItems);
            }

            if (flags.TransformFinalFormation)
            {
                TransformFinalFormation((FinalFormation)rng.Between(0, Enum.GetValues(typeof(FinalFormation)).Length - 1));
            }

            var maxRetries = 500;

            for (var i = 0; i < maxRetries; i++)
            {
                try
                {
                    overworldMap = new OverworldMap(this, flags, palettes);
                    if ((flags.Entrances || flags.Floors || flags.Towns) && flags.Treasures && flags.NPCItems)
                    {
                        overworldMap.ShuffleEntrancesAndFloors(rng, flags);
                    }

                    var incentivesData = new IncentiveData(rng, flags, overworldMap);

                    if (flags.Shops)
                    {
                        var excludeItemsFromRandomShops = flags.Treasures
                                                        ? incentivesData.ForcedItemPlacements.Select(x => x.Item).Concat(incentivesData.IncentiveItems).ToList()
                                                        : new List <Item>();
                        shopItemLocation = ShuffleShops(rng, flags.EnemyStatusAttacks, flags.RandomWares, excludeItemsFromRandomShops);
                    }

                    if (flags.Treasures)
                    {
                        ShuffleTreasures(rng, flags, incentivesData, shopItemLocation, overworldMap);
                    }
                    break;
                }
                catch (InsaneException)
                {
                    Console.WriteLine("Insane seed. Retrying");
                    if (maxRetries > (i + 1))
                    {
                        continue;
                    }
                    throw new InvalidOperationException("Failed Sanity Check too many times");
                }
            }

            if (flags.MagicShops)
            {
                ShuffleMagicShops(rng);
            }

            if (flags.MagicLevels)
            {
                FixWarpBug();                 // The warp bug only needs to be fixed if the magic levels are being shuffled
                ShuffleMagicLevels(rng, flags.MagicPermissions);
            }

            if (flags.Rng)
            {
                ShuffleRng(rng);
            }

            if (flags.EnemyScripts)
            {
                ShuffleEnemyScripts(rng, flags.AllowUnsafePirates);
            }

            if (flags.EnemySkillsSpells)
            {
                ShuffleEnemySkillsSpells(rng);
            }

            if (flags.EnemyStatusAttacks)
            {
                ShuffleEnemyStatusAttacks(rng, flags.AllowUnsafePirates);
            }

            if (flags.EnemyFormationsUnrunnable)
            {
                ShuffleUnrunnable(rng);
            }

            if (flags.EnemyFormationsSurprise)
            {
                ShuffleSurpriseBonus(rng);
            }

            if (flags.EnemyFormationsFrequency)
            {
                ShuffleEnemyFormations(rng);
            }

            if (flags.EnemyTrapTiles)
            {
                ShuffleTrapTiles(rng, flags.RandomTrapFormations);
            }

            if (flags.OrdealsPillars)
            {
                ShuffleOrdeals(rng, maps);
            }

            if (flags.SkyCastle4FTeleporters)
            {
                ShuffleSkyCastle4F(rng, maps);
            }

            if (flags.ConfusedOldMen)
            {
                EnableConfusedOldMen(rng);
            }

            if (flags.CrownlessOrdeals)
            {
                EnableEarlyOrdeals();
            }

            if (flags.ChaosRush)
            {
                EnableChaosRush();
            }

            if (flags.EarlySarda && !flags.NPCItems)
            {
                EnableEarlySarda();
            }

            if (flags.EarlySage && !flags.NPCItems)
            {
                EnableEarlySage();
            }

            if (flags.FreeBridge)
            {
                EnableFreeBridge();
            }

            if (flags.FreeAirship)
            {
                EnableFreeAirship();
            }

            if (flags.FreeOrbs)
            {
                EnableFreeOrbs();
            }

            if (flags.NoPartyShuffle)
            {
                DisablePartyShuffle();
            }

            if (flags.SpeedHacks)
            {
                EnableSpeedHacks();
            }

            if (flags.IdentifyTreasures)
            {
                EnableIdentifyTreasures();
            }

            if (flags.Dash)
            {
                EnableDash();
            }

            if (flags.BuyTen)
            {
                EnableBuyTen();
            }

            if (flags.WaitWhenUnrunnable)
            {
                ChangeUnrunnableRunToWait();
            }

            if (flags.EnableCritNumberDisplay)
            {
                EnableCritNumberDisplay();
            }

            if (flags.EasyMode)
            {
                EnableEasyMode();
            }

            if (flags.HouseMPRestoration)
            {
                FixHouse();
            }

            if (flags.WeaponStats)
            {
                FixWeaponStats();
            }

            if (flags.ChanceToRun)
            {
                FixChanceToRun();
            }

            if (flags.EnemyStatusAttackBug)
            {
                FixEnemyStatusAttackBug();
            }

            if (flags.BlackBeltAbsorb)
            {
                FixBBAbsorbBug();
            }

            if (flags.ImproveTurnOrderRandomization)
            {
                ImproveTurnOrderRandomization(rng);
            }

            if (flags.EnemyElementalResistancesBug)
            {
                FixEnemyElementalResistances();
            }

            if (flags.FunEnemyNames)
            {
                FunEnemyNames(flags.TeamSteak);
            }

            var itemText = ReadText(ItemTextPointerOffset, ItemTextPointerBase, ItemTextPointerCount);

            // var dialogueText = ReadText(DialogueTextPointerOffset, DialogueTextPointerBase, DialogueTextPointerCount);
            FixVanillaRibbon(itemText);
            ExpGoldBoost(flags.ExpBonus, flags.ExpMultiplier);
            ScalePrices(flags, itemText, rng, shopItemLocation);
            ScaleEncounterRate(flags.EncounterRate / 30.0, flags.DungeonEncounterRate / 30.0);


            if (flags.WarMECHMode != WarMECHMode.Vanilla)
            {
                WarMECHNpc(flags.WarMECHMode, rng, maps);
            }

            overworldMap.ApplyMapEdits();
            WriteMaps(maps);

            WriteText(itemText, ItemTextPointerOffset, ItemTextPointerBase, ItemTextOffset, UnusedGoldItems);
            // WriteText(dialogueText, DialogueTextPointerOffset, DialogueTextPointerBase, DialogueTextOffset);

            if (flags.EnemyScaleFactor > 1)
            {
                ScaleEnemyStats(flags.EnemyScaleFactor, flags.WrapStatOverflow, flags.IncludeMorale, rng);
            }

            if (flags.BossScaleFactor > 1)
            {
                ScaleBossStats(flags.BossScaleFactor, flags.WrapStatOverflow, flags.IncludeMorale, rng);
            }

            if (flags.ForcedPartyMembers > 0)
            {
                PartyRandomize(rng, flags.ForcedPartyMembers);
            }

            if (flags.MapCanalBridge)
            {
                EnableCanalBridge();
            }

            SetProgressiveScaleMode(flags.ProgressiveScaleMode);

            // We have to do "fun" stuff last because it alters the RNG state.
            RollCredits(rng);

            if (flags.PaletteSwap)
            {
                PaletteSwap(rng);
            }

            if (flags.TeamSteak)
            {
                TeamSteak();
            }

            if (flags.Music != MusicShuffle.None)
            {
                ShuffleMusic(flags.Music, rng);
            }

            WriteSeedAndFlags(Version, seed.ToHex(), Flags.EncodeFlagsText(flags));
            ExtraTrackingAndInitCode();
        }
Exemple #7
0
 public IncNameHintSource(MT19337 _rng, NPCdata _npcData, Flags _flags, OverworldMap _overworldMap, FF1Rom _rom) : base(_rng, _npcData, _flags, _overworldMap, _rom)
 {
 }
Exemple #8
0
        public void PartyComposition(MT19337 rng, Flags flags)
        {
            var options = new List <FF1Class>();

            // Do each slot - so ugly!
            if (flags.FIGHTER1)
            {
                options.Add(FF1Class.Fighter);
            }
            if (flags.THIEF1)
            {
                options.Add(FF1Class.Thief);
            }
            if (flags.BLACK_BELT1)
            {
                options.Add(FF1Class.BlackBelt);
            }
            if (flags.RED_MAGE1)
            {
                options.Add(FF1Class.RedMage);
            }
            if (flags.WHITE_MAGE1)
            {
                options.Add(FF1Class.WhiteMage);
            }
            if (flags.BLACK_MAGE1)
            {
                options.Add(FF1Class.BlackMage);
            }
            updateCharacterFromOptions(1, flags.FORCED1, options, rng);

            if (flags.FIGHTER2)
            {
                options.Add(FF1Class.Fighter);
            }
            if (flags.THIEF2)
            {
                options.Add(FF1Class.Thief);
            }
            if (flags.BLACK_BELT2)
            {
                options.Add(FF1Class.BlackBelt);
            }
            if (flags.RED_MAGE2)
            {
                options.Add(FF1Class.RedMage);
            }
            if (flags.WHITE_MAGE2)
            {
                options.Add(FF1Class.WhiteMage);
            }
            if (flags.BLACK_MAGE2)
            {
                options.Add(FF1Class.BlackMage);
            }
            if (flags.NONE_CLASS2)
            {
                options.Add(FF1Class.None);
            }
            updateCharacterFromOptions(2, flags.FORCED2, options, rng);

            if (flags.FIGHTER3)
            {
                options.Add(FF1Class.Fighter);
            }
            if (flags.THIEF3)
            {
                options.Add(FF1Class.Thief);
            }
            if (flags.BLACK_BELT3)
            {
                options.Add(FF1Class.BlackBelt);
            }
            if (flags.RED_MAGE3)
            {
                options.Add(FF1Class.RedMage);
            }
            if (flags.WHITE_MAGE3)
            {
                options.Add(FF1Class.WhiteMage);
            }
            if (flags.BLACK_MAGE3)
            {
                options.Add(FF1Class.BlackMage);
            }
            if (flags.NONE_CLASS3)
            {
                options.Add(FF1Class.None);
            }
            updateCharacterFromOptions(3, flags.FORCED3, options, rng);

            if (flags.FIGHTER4)
            {
                options.Add(FF1Class.Fighter);
            }
            if (flags.THIEF4)
            {
                options.Add(FF1Class.Thief);
            }
            if (flags.BLACK_BELT4)
            {
                options.Add(FF1Class.BlackBelt);
            }
            if (flags.RED_MAGE4)
            {
                options.Add(FF1Class.RedMage);
            }
            if (flags.WHITE_MAGE4)
            {
                options.Add(FF1Class.WhiteMage);
            }
            if (flags.BLACK_MAGE4)
            {
                options.Add(FF1Class.BlackMage);
            }
            if (flags.NONE_CLASS4)
            {
                options.Add(FF1Class.None);
            }
            updateCharacterFromOptions(4, flags.FORCED4, options, rng);

            // Load stats for None
            PutInBank(0x1F, 0xC783, Blob.FromHex("2080B3C931F053EA"));
            PutInBank(0x00, 0xB380, Blob.FromHex("BD0061C9FFD013A9019D0161A9009D07619D08619D0961A931600A0A0A0AA860"));

            //clinic stuff
            PutInBank(0x0E, 0xA6F3, Blob.FromHex("203E9B"));
            PutInBank(0x0E, 0x9B3E, Blob.FromHex("BD0061C9FFD00568684C16A7BD016160"));

            // curing ailments out of battle, allow the waste of things in battle
            PutInBank(0x0E, 0xB388, Blob.FromHex("2077C2EAEAEAEAEAEAEAEA"));
            PutInBank(0x1F, 0xC277, CreateLongJumpTableEntry(0x0F, 0x8BB0));
            PutInBank(0x0F, 0x8BB0, Blob.FromHex("A5626A6A6A29C0AABD0061C9FFD003A90060BD016160"));

            // Better Battle sprite, in 0C_9910_DrawCharacter.asm
            PutInBank(0x0F, 0x8BD0, Blob.FromHex("A86A6A6AAABD0061C9FFF00898AABDA86B8DB36860"));
            PutInBank(0x0C, 0x9910, Blob.FromHex("20A4C8C9FFD001608A0A0AA8"));
            PutInBank(0x1F, 0xC8A4, CreateLongJumpTableEntry(0x0F, 0x8BD0));

            // MapMan for Nones
            PutInBank(0x1F, 0xE92E, Blob.FromHex("20608FEAEAEAEA"));
            PutInBank(0x02, 0x8F60, Blob.FromHex("A9008510AD0061C9FFF00160A92560"));

            // Draw Complex String extension for class FF
            PutInBank(0x1F, 0xC27D, Blob.FromHex("C9FFF0041869F060203EE0A997853EA9C2853F2045DE4C4EE0EA973CA800"));
            PutInBank(0x1F, 0xDF0C, Blob.FromHex("207DC2"));

            // Skip targeting None with aoe spells
            PutInBank(0x0C, 0xB453, Blob.FromHex("20AAC8C9FFF015EA"));
            PutInBank(0x1F, 0xC8AA, CreateLongJumpTableEntry(0x0F, 0x8BF0));
            PutInBank(0x0F, 0x8BF0, Blob.FromHex("ADCE6BAA6A6A6AA8B90061C9FFF0068A09808D8A6C60"));

            // Rewrite class promotion to not promote NONEs, See 0E_95AE_DoClassChange.asm
            PutInBank(0x0E, 0x95AE, Blob.FromHex("A203BCD095B900613006186906990061CA10EFE65660"));
            PutInBank(0x0E, 0x95D0, Blob.FromHex("C0804000"));             // lut used by the above code
        }
Exemple #9
0
 public ViewModelFlags()
 {
     Flags = new Flags();
 }
 public FloorHintsHintSource(MT19337 _rng, NPCdata _npcData, Flags _flags, OverworldMap _overworldMap, FF1Rom _rom) : base(_rng, _npcData, _flags, _overworldMap, _rom)
 {
     Prices = new ItemPrices(_rom);
 }
Exemple #11
0
        public static Flags DecodeFlagsText(string text)
        {
            var sum = StringToBigInteger(text);

            var flags = new Flags
            {
                Spoilers = GetBoolean(ref sum),
                AllowStartAreaDanager       = GetBoolean(ref sum),
                WorldWealth                 = (WorldWealth)GetNumeric(ref sum, Enum.GetValues(typeof(WorldWealth)).Cast <int>().Max() + 1),
                FormationShuffleMode        = (FormationShuffleModeEnum)GetNumeric(ref sum, Enum.GetValues(typeof(FormationShuffleModeEnum)).Cast <int>().Max() + 1),
                FiendShuffle                = GetBoolean(ref sum),
                EFGEarth2                   = GetBoolean(ref sum),
                EFGEarth1                   = GetBoolean(ref sum),
                EFGWaterfall                = GetBoolean(ref sum),
                ExperimentalFloorGeneration = GetBoolean(ref sum),
                ClampMinimumPriceScale      = GetBoolean(ref sum),
                ClampMinimumBossStatScale   = GetBoolean(ref sum),
                ClampMinimumStatScale       = GetBoolean(ref sum),
                RecruitmentMode             = GetBoolean(ref sum),
                ArmorPermissions            = GetBoolean(ref sum),
                WeaponPermissions           = GetBoolean(ref sum),
                FORCED4                        = GetBoolean(ref sum),
                FORCED3                        = GetBoolean(ref sum),
                FORCED2                        = GetBoolean(ref sum),
                FORCED1                        = GetBoolean(ref sum),
                NONE_CLASS4                    = GetBoolean(ref sum),
                NONE_CLASS3                    = GetBoolean(ref sum),
                NONE_CLASS2                    = GetBoolean(ref sum),
                BLACK_MAGE4                    = GetBoolean(ref sum),
                WHITE_MAGE4                    = GetBoolean(ref sum),
                RED_MAGE4                      = GetBoolean(ref sum),
                BLACK_BELT4                    = GetBoolean(ref sum),
                THIEF4                         = GetBoolean(ref sum),
                FIGHTER4                       = GetBoolean(ref sum),
                BLACK_MAGE3                    = GetBoolean(ref sum),
                WHITE_MAGE3                    = GetBoolean(ref sum),
                RED_MAGE3                      = GetBoolean(ref sum),
                BLACK_BELT3                    = GetBoolean(ref sum),
                THIEF3                         = GetBoolean(ref sum),
                FIGHTER3                       = GetBoolean(ref sum),
                BLACK_MAGE2                    = GetBoolean(ref sum),
                WHITE_MAGE2                    = GetBoolean(ref sum),
                RED_MAGE2                      = GetBoolean(ref sum),
                BLACK_BELT2                    = GetBoolean(ref sum),
                THIEF2                         = GetBoolean(ref sum),
                FIGHTER2                       = GetBoolean(ref sum),
                BLACK_MAGE1                    = GetBoolean(ref sum),
                WHITE_MAGE1                    = GetBoolean(ref sum),
                RED_MAGE1                      = GetBoolean(ref sum),
                BLACK_BELT1                    = GetBoolean(ref sum),
                THIEF1                         = GetBoolean(ref sum),
                FIGHTER1                       = GetBoolean(ref sum),
                ProgressiveScaleMode           = (ProgressiveScaleMode)GetNumeric(ref sum, Enum.GetValues(typeof(ProgressiveScaleMode)).Cast <int>().Max() + 1),
                DungeonEncounterRate           = GetNumeric(ref sum, 46),
                EncounterRate                  = GetNumeric(ref sum, 46),
                ExpBonus                       = GetNumeric(ref sum, 51) * 10,
                ExpMultiplier                  = (GetNumeric(ref sum, 41) + 10) / 10.0,
                PriceScaleFactor               = (GetNumeric(ref sum, 41) + 10) / 10.0,
                BossScaleFactor                = (GetNumeric(ref sum, 41) + 10) / 10.0,
                EnemyScaleFactor               = (GetNumeric(ref sum, 41) + 10) / 10.0,
                NoDanMode                      = GetBoolean(ref sum),
                RandomWaresIncludesSpecialGear = GetBoolean(ref sum),
                IncludeMorale                  = GetBoolean(ref sum),
                WrapPriceOverflow              = GetBoolean(ref sum),
                WrapStatOverflow               = GetBoolean(ref sum),
                StartingGold                   = GetBoolean(ref sum),
                ImproveTurnOrderRandomization  = GetBoolean(ref sum),
                EnemyElementalResistancesBug   = GetBoolean(ref sum),
                EnemySpellsTargetingAllies     = GetBoolean(ref sum),
                EnemyStatusAttackBug           = GetBoolean(ref sum),
                NPCSwatter                     = GetBoolean(ref sum),
                BlackBeltMDEF                  = GetBoolean(ref sum),
                BlackBeltAbsorb                = GetBoolean(ref sum),
                SpellBugs                      = GetBoolean(ref sum),
                ChanceToRun                    = GetBoolean(ref sum),
                WeaponStats                    = GetBoolean(ref sum),
                HouseMPRestoration             = GetBoolean(ref sum),
                WaitWhenUnrunnable             = GetBoolean(ref sum),
                IdentifyTreasures              = GetBoolean(ref sum),
                BuyTen                         = GetBoolean(ref sum),
                Dash                             = GetBoolean(ref sum),
                NoPartyShuffle                   = GetBoolean(ref sum),
                SpeedHacks                       = GetBoolean(ref sum),
                HousesFillHp                     = GetBoolean(ref sum),
                EasyMode                         = GetBoolean(ref sum),
                FreeCanal                        = GetBoolean(ref sum),
                EnableCritNumberDisplay          = GetBoolean(ref sum),
                FreeOrbs                         = GetBoolean(ref sum),
                FreeAirship                      = GetBoolean(ref sum),
                FreeBridge                       = GetBoolean(ref sum),
                OnlyRequireGameIsBeatable        = GetBoolean(ref sum),
                ShuffleObjectiveNPCs             = GetBoolean(ref sum),
                EarlyOrdeals                     = GetBoolean(ref sum),
                EarlySage                        = GetBoolean(ref sum),
                EarlySarda                       = GetBoolean(ref sum),
                IncentivizeOtherCastWeapon       = GetBoolean(ref sum),
                IncentivizeOffCastWeapon         = GetBoolean(ref sum),
                IncentivizeDefCastWeapon         = GetBoolean(ref sum),
                IncentivizeOtherCastArmor        = GetBoolean(ref sum),
                IncentivizeOffCastArmor          = GetBoolean(ref sum),
                IncentivizeDefCastArmor          = GetBoolean(ref sum),
                IncentivizeRibbon                = GetBoolean(ref sum),
                IncentivizeOpal                  = GetBoolean(ref sum),
                IncentivizeMasamune              = GetBoolean(ref sum),
                BetterTrapChests                 = GetBoolean(ref sum),
                IncentivizeTitansTrove           = GetBoolean(ref sum),
                IncentivizeSkyPalace             = GetBoolean(ref sum),
                IncentivizeMarshKeyLocked        = GetBoolean(ref sum),
                IncentivizeConeria               = GetBoolean(ref sum),
                IncentivizeSeaShrine             = GetBoolean(ref sum),
                IncentivizeOrdeals               = GetBoolean(ref sum),
                IncentivizeIceCave               = GetBoolean(ref sum),
                IncentivizeVolcano               = GetBoolean(ref sum),
                IncentivizeEarth                 = GetBoolean(ref sum),
                IncentivizeMarsh                 = GetBoolean(ref sum),
                ClassicItemPlacement             = GetBoolean(ref sum),
                IncentivizeShipAndCanal          = GetBoolean(ref sum),
                IncentivizeCanoeItem             = GetBoolean(ref sum),
                IncentivizeAirship               = GetBoolean(ref sum),
                IncentivizeFetchItems            = GetBoolean(ref sum),
                IncentivizeMainItems             = GetBoolean(ref sum),
                IncentivizeTail                  = GetBoolean(ref sum),
                IncentivizeFetchNPCs             = GetBoolean(ref sum),
                IncentivizeFreeNPCs              = GetBoolean(ref sum),
                EntrancesMixedWithTowns          = GetBoolean(ref sum),
                EntrancesIncludesDeadEnds        = GetBoolean(ref sum),
                MapOpenProgressionExtended       = GetBoolean(ref sum),
                AllowDeepTowns                   = GetBoolean(ref sum),
                AllowDeepCastles                 = GetBoolean(ref sum),
                Floors                           = GetBoolean(ref sum),
                Towns                            = GetBoolean(ref sum),
                Entrances                        = GetBoolean(ref sum),
                MapOpenProgression               = GetBoolean(ref sum),
                ConfusedOldMen                   = GetBoolean(ref sum),
                LefeinShops                      = GetBoolean(ref sum),
                TitansTrove                      = GetBoolean(ref sum),
                SkyCastle4FMazeMode              = (SkyCastle4FMazeMode)GetNumeric(ref sum, Enum.GetValues(typeof(SkyCastle4FMazeMode)).Cast <int>().Max() + 1),
                OrdealsPillars                   = GetBoolean(ref sum),
                WarMECHMode                      = (WarMECHMode)GetNumeric(ref sum, Enum.GetValues(typeof(WarMECHMode)).Cast <int>().Max() + 1),
                AllowUnsafeMelmond               = GetBoolean(ref sum),
                AllowUnsafePirates               = GetBoolean(ref sum),
                RandomStatusAttacks              = GetBoolean(ref sum),
                EnemyStatusAttacks               = GetBoolean(ref sum),
                EnemySkillsSpells                = GetBoolean(ref sum),
                EnemyScripts                     = GetBoolean(ref sum),
                RandomTrapFormations             = GetBoolean(ref sum),
                EnemyTrapTiles                   = GetBoolean(ref sum),
                UnrunnablesStrikeFirstAndSuprise = GetBoolean(ref sum),
                EnemyFormationsSurprise          = GetBoolean(ref sum),
                EnemyFormationsUnrunnable        = GetBoolean(ref sum),
                EverythingUnrunnable             = GetBoolean(ref sum),
                Rng                     = GetBoolean(ref sum),
                RebalanceSpells         = GetBoolean(ref sum),
                ItemMagic               = GetBoolean(ref sum),
                MagicPermissions        = GetBoolean(ref sum),
                MagicLevels             = GetBoolean(ref sum),
                MagicShops              = GetBoolean(ref sum),
                PreserveFiendRefights   = GetBoolean(ref sum),
                ShortToFR               = GetBoolean(ref sum),
                ChaosRush               = GetBoolean(ref sum),
                TransformFinalFormation = GetBoolean(ref sum),
                ExtraShards             = GetBoolean(ref sum),
                ShardHunt               = GetBoolean(ref sum),
                RandomLoot              = GetBoolean(ref sum),
                RandomWares             = GetBoolean(ref sum),
                NPCFetchItems           = GetBoolean(ref sum),
                NPCItems                = GetBoolean(ref sum),
                Treasures               = GetBoolean(ref sum),
                Shops                   = GetBoolean(ref sum)
            };

            return(flags);
        }
Exemple #12
0
        public static string EncodeFlagsText(Flags flags)
        {
            BigInteger sum = 0;

            sum = AddBoolean(sum, flags.Shops);
            sum = AddBoolean(sum, flags.Treasures);
            sum = AddBoolean(sum, flags.NPCItems);
            sum = AddBoolean(sum, flags.NPCFetchItems);
            sum = AddBoolean(sum, flags.RandomWares);
            sum = AddBoolean(sum, flags.RandomLoot);
            sum = AddBoolean(sum, flags.ShardHunt);
            sum = AddBoolean(sum, flags.ExtraShards);
            sum = AddBoolean(sum, flags.TransformFinalFormation);
            sum = AddBoolean(sum, flags.ChaosRush);
            sum = AddBoolean(sum, flags.ShortToFR);
            sum = AddBoolean(sum, flags.PreserveFiendRefights);
            sum = AddBoolean(sum, flags.MagicShops);
            sum = AddBoolean(sum, flags.MagicLevels);
            sum = AddBoolean(sum, flags.MagicPermissions);
            sum = AddBoolean(sum, flags.ItemMagic);
            sum = AddBoolean(sum, flags.RebalanceSpells);
            sum = AddBoolean(sum, flags.Rng);
            sum = AddBoolean(sum, flags.EverythingUnrunnable);
            sum = AddBoolean(sum, flags.EnemyFormationsUnrunnable);
            sum = AddBoolean(sum, flags.EnemyFormationsSurprise);
            sum = AddBoolean(sum, flags.UnrunnablesStrikeFirstAndSuprise);
            sum = AddBoolean(sum, flags.EnemyTrapTiles);
            sum = AddBoolean(sum, flags.RandomTrapFormations);
            sum = AddBoolean(sum, flags.EnemyScripts);
            sum = AddBoolean(sum, flags.EnemySkillsSpells);
            sum = AddBoolean(sum, flags.EnemyStatusAttacks);
            sum = AddBoolean(sum, flags.RandomStatusAttacks);
            sum = AddBoolean(sum, flags.AllowUnsafePirates);
            sum = AddBoolean(sum, flags.AllowUnsafeMelmond);
            sum = AddNumeric(sum, Enum.GetValues(typeof(WarMECHMode)).Cast <int>().Max() + 1, (int)flags.WarMECHMode);
            sum = AddBoolean(sum, flags.OrdealsPillars);
            sum = AddNumeric(sum, Enum.GetValues(typeof(SkyCastle4FMazeMode)).Cast <int>().Max() + 1, (int)flags.SkyCastle4FMazeMode);
            sum = AddBoolean(sum, flags.TitansTrove);
            sum = AddBoolean(sum, flags.LefeinShops);
            sum = AddBoolean(sum, flags.ConfusedOldMen);
            sum = AddBoolean(sum, flags.MapOpenProgression);
            sum = AddBoolean(sum, flags.Entrances);
            sum = AddBoolean(sum, flags.Towns);
            sum = AddBoolean(sum, flags.Floors);
            sum = AddBoolean(sum, flags.AllowDeepCastles);
            sum = AddBoolean(sum, flags.AllowDeepTowns);
            sum = AddBoolean(sum, flags.MapOpenProgressionExtended);
            sum = AddBoolean(sum, flags.EntrancesIncludesDeadEnds);
            sum = AddBoolean(sum, flags.EntrancesMixedWithTowns);
            sum = AddBoolean(sum, flags.IncentivizeFreeNPCs);
            sum = AddBoolean(sum, flags.IncentivizeFetchNPCs);
            sum = AddBoolean(sum, flags.IncentivizeTail);
            sum = AddBoolean(sum, flags.IncentivizeMainItems);
            sum = AddBoolean(sum, flags.IncentivizeFetchItems);
            sum = AddBoolean(sum, flags.IncentivizeAirship);
            sum = AddBoolean(sum, flags.IncentivizeCanoeItem);
            sum = AddBoolean(sum, flags.IncentivizeShipAndCanal);
            sum = AddBoolean(sum, flags.ClassicItemPlacement);
            sum = AddBoolean(sum, flags.IncentivizeMarsh);
            sum = AddBoolean(sum, flags.IncentivizeEarth);
            sum = AddBoolean(sum, flags.IncentivizeVolcano);
            sum = AddBoolean(sum, flags.IncentivizeIceCave);
            sum = AddBoolean(sum, flags.IncentivizeOrdeals);
            sum = AddBoolean(sum, flags.IncentivizeSeaShrine);
            sum = AddBoolean(sum, flags.IncentivizeConeria);
            sum = AddBoolean(sum, flags.IncentivizeMarshKeyLocked);
            sum = AddBoolean(sum, flags.IncentivizeSkyPalace);
            sum = AddBoolean(sum, flags.IncentivizeTitansTrove);
            sum = AddBoolean(sum, flags.BetterTrapChests);
            sum = AddBoolean(sum, flags.IncentivizeMasamune);
            sum = AddBoolean(sum, flags.IncentivizeOpal);
            sum = AddBoolean(sum, flags.IncentivizeRibbon);
            sum = AddBoolean(sum, flags.IncentivizeDefCastArmor);
            sum = AddBoolean(sum, flags.IncentivizeOffCastArmor);
            sum = AddBoolean(sum, flags.IncentivizeOtherCastArmor);
            sum = AddBoolean(sum, flags.IncentivizeDefCastWeapon);
            sum = AddBoolean(sum, flags.IncentivizeOffCastWeapon);
            sum = AddBoolean(sum, flags.IncentivizeOtherCastWeapon);
            sum = AddBoolean(sum, flags.EarlySarda);
            sum = AddBoolean(sum, flags.EarlySage);
            sum = AddBoolean(sum, flags.EarlyOrdeals);
            sum = AddBoolean(sum, flags.ShuffleObjectiveNPCs);
            sum = AddBoolean(sum, flags.OnlyRequireGameIsBeatable);
            sum = AddBoolean(sum, flags.FreeBridge);
            sum = AddBoolean(sum, flags.FreeAirship);
            sum = AddBoolean(sum, flags.FreeOrbs);
            sum = AddBoolean(sum, flags.EnableCritNumberDisplay);
            sum = AddBoolean(sum, flags.FreeCanal);
            sum = AddBoolean(sum, flags.EasyMode);
            sum = AddBoolean(sum, flags.HousesFillHp);
            sum = AddBoolean(sum, flags.SpeedHacks);
            sum = AddBoolean(sum, flags.NoPartyShuffle);
            sum = AddBoolean(sum, flags.Dash);
            sum = AddBoolean(sum, flags.BuyTen);
            sum = AddBoolean(sum, flags.IdentifyTreasures);
            sum = AddBoolean(sum, flags.WaitWhenUnrunnable);
            sum = AddBoolean(sum, flags.HouseMPRestoration);
            sum = AddBoolean(sum, flags.WeaponStats);
            sum = AddBoolean(sum, flags.ChanceToRun);
            sum = AddBoolean(sum, flags.SpellBugs);
            sum = AddBoolean(sum, flags.BlackBeltAbsorb);
            sum = AddBoolean(sum, flags.BlackBeltMDEF);
            sum = AddBoolean(sum, flags.NPCSwatter);
            sum = AddBoolean(sum, flags.EnemyStatusAttackBug);
            sum = AddBoolean(sum, flags.EnemySpellsTargetingAllies);
            sum = AddBoolean(sum, flags.EnemyElementalResistancesBug);
            sum = AddBoolean(sum, flags.ImproveTurnOrderRandomization);
            sum = AddBoolean(sum, flags.StartingGold);
            sum = AddBoolean(sum, flags.WrapStatOverflow);
            sum = AddBoolean(sum, flags.WrapPriceOverflow);
            sum = AddBoolean(sum, flags.IncludeMorale);
            sum = AddBoolean(sum, flags.RandomWaresIncludesSpecialGear);
            sum = AddBoolean(sum, flags.NoDanMode);
            sum = AddNumeric(sum, 41, (int)(10.0 * flags.EnemyScaleFactor) - 10);
            sum = AddNumeric(sum, 41, (int)(10.0 * flags.BossScaleFactor) - 10);
            sum = AddNumeric(sum, 41, (int)(10.0 * flags.PriceScaleFactor) - 10);
            sum = AddNumeric(sum, 41, (int)(10.0 * flags.ExpMultiplier) - 10);
            sum = AddNumeric(sum, 51, (int)(flags.ExpBonus / 10.0));
            sum = AddNumeric(sum, 46, (int)flags.EncounterRate);
            sum = AddNumeric(sum, 46, (int)flags.DungeonEncounterRate);
            sum = AddNumeric(sum, Enum.GetValues(typeof(ProgressiveScaleMode)).Cast <int>().Max() + 1, (int)flags.ProgressiveScaleMode);
            sum = AddBoolean(sum, flags.FIGHTER1);
            sum = AddBoolean(sum, flags.THIEF1);
            sum = AddBoolean(sum, flags.BLACK_BELT1);
            sum = AddBoolean(sum, flags.RED_MAGE1);
            sum = AddBoolean(sum, flags.WHITE_MAGE1);
            sum = AddBoolean(sum, flags.BLACK_MAGE1);
            sum = AddBoolean(sum, flags.FIGHTER2);
            sum = AddBoolean(sum, flags.THIEF2);
            sum = AddBoolean(sum, flags.BLACK_BELT2);
            sum = AddBoolean(sum, flags.RED_MAGE2);
            sum = AddBoolean(sum, flags.WHITE_MAGE2);
            sum = AddBoolean(sum, flags.BLACK_MAGE2);
            sum = AddBoolean(sum, flags.FIGHTER3);
            sum = AddBoolean(sum, flags.THIEF3);
            sum = AddBoolean(sum, flags.BLACK_BELT3);
            sum = AddBoolean(sum, flags.RED_MAGE3);
            sum = AddBoolean(sum, flags.WHITE_MAGE3);
            sum = AddBoolean(sum, flags.BLACK_MAGE3);
            sum = AddBoolean(sum, flags.FIGHTER4);
            sum = AddBoolean(sum, flags.THIEF4);
            sum = AddBoolean(sum, flags.BLACK_BELT4);
            sum = AddBoolean(sum, flags.RED_MAGE4);
            sum = AddBoolean(sum, flags.WHITE_MAGE4);
            sum = AddBoolean(sum, flags.BLACK_MAGE4);
            sum = AddBoolean(sum, flags.NONE_CLASS2);
            sum = AddBoolean(sum, flags.NONE_CLASS3);
            sum = AddBoolean(sum, flags.NONE_CLASS4);
            sum = AddBoolean(sum, flags.FORCED1);
            sum = AddBoolean(sum, flags.FORCED2);
            sum = AddBoolean(sum, flags.FORCED3);
            sum = AddBoolean(sum, flags.FORCED4);
            sum = AddBoolean(sum, flags.WeaponPermissions);
            sum = AddBoolean(sum, flags.ArmorPermissions);
            sum = AddBoolean(sum, flags.RecruitmentMode);
            sum = AddBoolean(sum, flags.ClampMinimumStatScale);
            sum = AddBoolean(sum, flags.ClampMinimumBossStatScale);
            sum = AddBoolean(sum, flags.ClampMinimumPriceScale);
            sum = AddBoolean(sum, flags.ExperimentalFloorGeneration);
            sum = AddBoolean(sum, flags.EFGWaterfall);
            sum = AddBoolean(sum, flags.EFGEarth1);
            sum = AddBoolean(sum, flags.EFGEarth2);
            sum = AddBoolean(sum, flags.FiendShuffle);
            sum = AddNumeric(sum, Enum.GetValues(typeof(FormationShuffleModeEnum)).Cast <int>().Max() + 1, (int)flags.FormationShuffleMode);
            sum = AddNumeric(sum, Enum.GetValues(typeof(WorldWealth)).Cast <int>().Max() + 1, (int)flags.WorldWealth);
            sum = AddBoolean(sum, flags.AllowStartAreaDanager);
            sum = AddBoolean(sum, flags.Spoilers);

            return(BigIntegerToString(sum));
        }