Пример #1
0
        public void PacifistEnd(TalkRoutines talkroutines, NPCdata npcdata, bool extendedtraptiles)
        {
            // Remove ToFR Fiends tiles
            var tilesets = Get(TilesetDataOffset, TilesetDataCount * TilesetDataSize * TilesetCount).Chunk(TilesetDataSize).ToList();

            tilesets.ForEach(tile =>
            {
                if (IsBossTrapTile(tile))
                {
                    tile[1] = (byte)(extendedtraptiles ? 0x00 : 0x80);
                }
            });
            Put(TilesetDataOffset, tilesets.SelectMany(tileset => tileset.ToBytes()).ToArray());

            // Update Chaos script
            var Talk_Ending = talkroutines.Add(Blob.FromHex("4C38C9"));

            npcdata.SetRoutine((ObjectId)0x1A, (newTalkRoutines)Talk_Ending);

            //Update Fiends, Garland, Vampire, Astos and Bikke
            var battleJump = Blob.FromHex("2020B1");
            var mapreload  = Blob.FromHex("201896");

            talkroutines.ReplaceChunk(newTalkRoutines.Talk_fight, battleJump, Blob.FromHex("EAEAEA"));
            talkroutines.ReplaceChunk(newTalkRoutines.Talk_fight, mapreload, Blob.FromHex("EAEAEA"));
            talkroutines.ReplaceChunk(newTalkRoutines.Talk_Bikke, battleJump, Blob.FromHex("EAEAEA"));
            talkroutines.ReplaceChunk(newTalkRoutines.Talk_Bikke, mapreload, Blob.FromHex("EAEAEA"));
            talkroutines.ReplaceChunk(newTalkRoutines.Talk_Astos, battleJump, Blob.FromHex("EAEAEA"));
            talkroutines.ReplaceChunk(newTalkRoutines.Talk_Astos, mapreload, Blob.FromHex("EAEAEA"));
        }
Пример #2
0
 public BaseHintPlacementProvider(MT19337 _rng, NPCdata _npcData, Flags _flags, OverworldMap _overworldMap, FF1Rom _rom)
 {
     rng          = _rng;
     npcData      = _npcData;
     flags        = _flags;
     overworldMap = _overworldMap;
     rom          = _rom;
 }
Пример #3
0
        public BaseHintSource(MT19337 _rng, NPCdata _npcData, Flags _flags, OverworldMap _overworldMap, FF1Rom _rom)
        {
            rng          = _rng;
            npcData      = _npcData;
            flags        = _flags;
            overworldMap = _overworldMap;
            rom          = _rom;

            translator = new Translator(rom);
        }
Пример #4
0
        private void EnableNPCSwatter(NPCdata npcdata)
        {
            for (int i = 0; i < npcdata.GetNPCCount(); i++)
            {
                if (npcdata.GetRoutine((ObjectId)i) == newTalkRoutines.Talk_norm)
                {
                    npcdata.SetRoutine((ObjectId)i, newTalkRoutines.Talk_kill);
                }
            }

            // Protect Lute and Rod Plate
            npcdata.SetRoutine(ObjectId.LutePlate, newTalkRoutines.Talk_norm);
            npcdata.SetRoutine(ObjectId.RodPlate, newTalkRoutines.Talk_norm);
        }
Пример #5
0
        public SCMain(List <Map> _maps, OverworldMap _overworldMap, NPCdata _npcdata, OwLocationData locations, FF1Rom _rom)
        {
            maps         = _maps;
            overworldMap = _overworldMap;
            rom          = _rom;
            npcdata      = _npcdata;

            mapTileSets = new MapTileSets(rom);
            enter       = new EnterTeleData(rom);
            tele        = new NormTeleData(rom);
            exit        = new ExitTeleData(rom);

            mapTileSets.LoadTable();
            enter.LoadData();
            tele.LoadData();
            exit.LoadData();

            for (int i = 0; i < 8; i++)
            {
                tileSets[i] = new SCTileSet(rom, (byte)i);
            }

            owtileset = new SCTileSet(rom, TileSet.OverworldIndex);

            Stopwatch w = Stopwatch.StartNew();

            List <SCMap> tmpscmaps = new List <SCMap>();

            //Parallel.ForEach(Enum.GetValues<MapId>(), mapid => ProcessMap(mapid, tmpscmaps));

            foreach (var mapid in Enum.GetValues <MapId>())
            {
                ProcessMap(mapid, tmpscmaps);
            }

            scmaps = tmpscmaps.ToDictionary(m => m.MapId);

            ComposeDungeons();

            //SCCoords bridge = new SCCoords(0x98, 0x98);
            //SCCoords canal = new SCCoords(0x66, 0xA4);
            Overworld = new SCOwMap(overworldMap, SCMapCheckFlags.None, _rom, owtileset, enter, exit, locations.BridgeLocation, locations.CanalLocation);

            w.Stop();
        }
Пример #6
0
        public SanityCheckerV2(List <Map> _maps, OverworldMap _overworldMap, NPCdata _npcdata, FF1Rom _rom, ItemShopSlot _declaredShopSlot, ShipLocations _shiplocations)
        {
            rom          = _rom;
            overworldMap = _overworldMap;
            maps         = _maps;
            npcdata      = _npcdata;

            locations = new OwLocationData(rom);
            locations.LoadData();

            Shiplocations = _shiplocations;

            allTreasures     = ItemLocations.AllTreasures.Select(r => r as TreasureChest).Where(r => r != null).ToDictionary(r => (byte)(r.Address - 0x3100));
            allQuestNpcs     = ItemLocations.AllNPCItemLocations.Select(r => r as MapObject).Where(r => r != null).ToDictionary(r => r.ObjectId);
            declaredShopSlot = _declaredShopSlot;

            UpdateNpcRequirements();

            Main = new SCMain(_maps, _overworldMap, _npcdata, locations, _rom);
        }
Пример #7
0
        public SCMap(MapId _mapid, Map _map, SCMapCheckFlags cflags, FF1Rom _rom, NPCdata _npcData, SCTileSet _tileSet, EnterTeleData _enter, ExitTeleData _exit, NormTeleData _tele)
        {
            MapId  = _mapid;
            CFlags = cflags;

            map     = _map;
            rom     = _rom;
            tileSet = _tileSet;

            enter = _enter;
            exit  = _exit;
            tele  = _tele;

            npcdata = _npcData;

            ProcessTiles();
            ProcessNPCs();
            ProcessTeleporters();
            ProcessPointsOfInterest();
            ComposeAreas();
        }
Пример #8
0
        public ExtensiveHints(MT19337 _rng, NPCdata _npcData, Flags _flags, OverworldMap _overworldMap, FF1Rom _rom)
        {
            rng          = _rng;
            npcData      = _npcData;
            flags        = _flags;
            overworldMap = _overworldMap;
            rom          = _rom;

            hintSources = new IHintSource[]
            {
                new LooseFloorHintSource(rng, npcData, flags, overworldMap, rom),
                new LooseNameHintSource(rng, npcData, flags, overworldMap, rom),
                new IncNameHintSource(rng, npcData, flags, overworldMap, rom),
                new FloorHintsHintSource(rng, npcData, flags, overworldMap, rom),
                new EqFloorHintSource(rng, npcData, flags, overworldMap, rom),
            };

            hintPlacementProviders = new IHintPlacementProvider[]
            {
                new DefaultHintPlacmentProvider(rng, npcData, flags, overworldMap, rom),
            };
        }
Пример #9
0
        public void HurrayDwarfFate(Fate fate, NPCdata npcdata, MT19337 rng)
        {
            if (fate == Fate.Spare)
            {
                // Protect Hurray Dwarf from NPC guillotine
                npcdata.SetRoutine(ObjectId.DwarfcaveDwarfHurray, newTalkRoutines.Talk_norm);
            }
            else
            {
                // Whether NPC guillotine is on or not, kill Hurray Dwarf
                npcdata.SetRoutine(ObjectId.DwarfcaveDwarfHurray, newTalkRoutines.Talk_kill);

                // Change the dialogue
                var dialogueStrings = new List <string>
                {
                    "No! I'm gonna disappear.\nYou'll never see\nme again. Please,\nI don't want to die.",
                    "If you strike me down,\nI shall become more\npowerful than you can\npossibly imagine.",
                    "Freeeeedom!!",
                    "I've seen things you\npeople wouldn't believe.\nAll those moments will\nbe lost in time..\nlike tears in rain..\nTime to die.",
                    "Become vengeance, David.\nBecome wrath.",
                    "My only regret..\nis that I have boneitis.",
                    "No, not the bees!\nNOT THE BEES!\nAAAAAAAAGH!\nTHEY'RE IN MY EYES!\nMY EYES! AAAAAAAAAAGH!",
                    "This is blasphemy!\nThis is madness!",
                    "Not like this..\nnot like this..",
                    "Suicide squad, attack!\n\n\n\nThat showed 'em, huh?",
                    "Well, what are you\nwaiting for?\nDo it. DO IT!!",
                    "The path you walk on has\nno end. Each step you\ntake is paved with the\ncorpses of your enemies.\nTheir souls will haunt\nyou forever. Hear me!\nMy spirit will be\nwatching you!",
                    "K-Kefka..!\nY-you're insane.."
                };

                //Put new dialogue to E6 since another Dwarf also says hurray
                InsertDialogs(0xE6, dialogueStrings.PickRandom(rng));
                npcdata.GetTalkArray(ObjectId.DwarfcaveDwarfHurray)[(int)TalkArrayPos.dialogue_1] = 0xE6;
                npcdata.GetTalkArray(ObjectId.DwarfcaveDwarfHurray)[(int)TalkArrayPos.dialogue_2] = 0xE6;
                npcdata.GetTalkArray(ObjectId.DwarfcaveDwarfHurray)[(int)TalkArrayPos.dialogue_3] = 0xE6;
            }
        }
Пример #10
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();
            }
            else if (flags.BuyTenOld)
            {
                EnableBuyTen();
            }

            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);
            }

            if (flags.Etherizer && !flags.HouseMPRestoration && !flags.HousesFillHp)
            {
                Etherizer();
                itemText[(int)Item.Tent]  = "ETHR@p";
                itemText[(int)Item.Cabin] = "DRY@p ";
                itemText[(int)Item.House] = "XETH@p";
            }

            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);
        }
Пример #11
0
        public void TitanSnack(TitanSnack snack, NPCdata npcdata, MT19337 rng)
        {
            if (snack == FF1Lib.TitanSnack.Ruby)
            {
                return;
            }

            var snackOptions  = new List <string>();           // { "NEWRUBY(max 7 characters);NEWRUBYPLURALIZED(max 8 characters);IS/ARE(relating to plural form);DESCRIPTOR(max 6 characters);ONOMATOPOEIA(max 6 chars, how ingestion sounds)" }
            var mineralSnacks = new List <string> {
                "DIAMOND;DIAMONDS;ARE;SWEET;CRUNCH", "GEODE;GEODES;ARE;SWEET;CRUNCH", "COAL;COAL;IS;SMOKY;CRUNCH", "PEARL;PEARLS;ARE;SWEET;CRUNCH", "FOSSIL;FOSSILS;ARE;SWEET;CRUNCH", "EMERALD;EMERALDS;ARE;SWEET;CRUNCH", "TOPAZ;TOPAZ;IS;SWEET;CRUNCH", "QUARTZ;QUARTZ;IS;SWEET;CRUNCH", "ONYX;ONYXES;ARE;SWEET;CRUNCH", "MARBLE;MARBLE;IS;SWEET;CRUNCH", "AMETHST;AMETHST;IS;SWEET;CRUNCH", "JADE;JADES;ARE;SWEET;CRUNCH", "SAPHIRE;SAPHIRE;IS;SWEET;CRUNCH", "GRANITE;GRANITE;IS;SWEET;CRUNCH", "OBSDIAN;OBSDIAN;IS;SWEET;CRUNCH", "CONCRET;CONCRET;IS;SALTY;CRUNCH", "ASPHALT;ASPHALT;IS;SALTY;CRUNCH", "PUMICE;PUMICE;IS;SWEET;CRUNCH", "LIMESTN;LIMESTN;IS;SOUR;CRUNCH", "SNDSTON;SNDSTON;IS;SALTY;CRUNCH", "MYTHRL;MYTHRL;IS;SWEET;CRUNCH"
            };
            var junkFoodSnacks = new List <string> {
                "DANISH;DANISHES;ARE;SWEET;MUNCH", "HOT DOG;HOT DOGS;ARE;GREAT;MUNCH", "TACO;TACOS;ARE;GREAT;MUNCH", "SUB;SUBS;ARE;GREAT;MUNCH", "PIZZA;PIZZA;IS;YUMMY;MUNCH", "BURGER;BURGERS;ARE;YUMMY;MUNCH", "EGGROLL;EGGROLLS;ARE;YUMMY;MUNCH", "BISCUIT;BISCUITS;ARE;YUMMY;MUNCH", "WAFFLE;WAFFLES;ARE;YUMMY;MUNCH", "CAKE;CAKE;IS;SWEET;MUNCH", "PIE;PIE;IS;SWEET;MUNCH", "DONUT;DONUTS;ARE;SWEET;MUNCH", "FRIES;FRIES;ARE;SALTY;MUNCH", "CHIPS;CHIPS;ARE;SALTY;CRUNCH", "CANDY;CANDY;IS;SWEET;MUNCH", "PANCAKE;PANCAKES;ARE;SWEET;MUNCH", "ICE CRM;ICE CRM;IS;CREAMY;MUNCH", "PUDDING;PUDDING;IS;YUMMY;MUNCH", "BROWNIE;BROWNIES;ARE;SWEET;MUNCH", "CRAYON;CRAYONS;ARE;WEIRD;MUNCH", "GLUE;GLUE;IS;WEIRD;MUNCH", "PASTE;PASTE;IS;WEIRD;MUNCH", "LASAGNA;LASAGNA;IS;YUMMY;MUNCH", "POUTINE;POUTINE;IS;GREAT;MUNCH", "PASTA;PASTA;IS;YUMMY;MUNCH", "RAMEN;RAMEN;IS;GREAT;MUNCH", "STEAK;STEAK;IS;GREAT;MUNCH", "NACHOS;NACHOS;ARE;SALTY;CRUNCH", "BACON;BACON;IS;SALTY;MUNCH", "MUTTON;MUTTON;IS;GREAT;MUNCH", "BAGEL;BAGELS;ARE;GREAT;MUNCH", "CHEESE;CHEESE;IS;GREAT;MUNCH", "POPCORN;POPCORN;IS;SALTY;MUNCH", "CHICKEN;CHICKEN;IS;GREAT;MUNCH", "BEEF;BEEF;IS;GREAT;MUNCH", "HAM;HAM;IS;GREAT;MUNCH", "BOLOGNA;BOLOGNA;IS;GREAT;MUNCH", "HOAGIE;HOAGIES;ARE;GREAT;MUNCH", "FILET;FILET;IS;DIVINE;MUNCH", "LOBSTER;LOBSTER;IS;DIVINE;MUNCH"
            };
            var healthySnacks = new List <string> {
                "EDAMAME;EDAMAME;IS;SALTY;MUNCH", "SALAD;SALAD;IS;GREAT;MUNCH", "APPLE;APPLES;ARE;SWEET;CRUNCH", "PEAR;PEARS;ARE;SWEET;MUNCH", "MELON;MELONS;ARE;SWEET;MUNCH", "ORANGE;ORANGES;ARE;SWEET;MUNCH", "LEMON;LEMONS;ARE;SOUR;MUNCH", "YOGURT;YOGURT;IS;GREAT;MUNCH", "GRANOLA;GRANOLA;IS;GREAT;CRUNCH", "SPINACH;SPINACH;IS;YUMMY;MUNCH", "EGG;EGGS;ARE;YUMMY;MUNCH", "GRAPES;GRAPES;ARE;YUMMY;MUNCH", "OATMEAL;OATMEAL;IS;GREAT;MUNCH", "TOFU;TOFU;IS;WEIRD;MUNCH", "CABBAGE;CABBAGE;IS;FRESH;MUNCH", "LETTUCE;LETTUCE;IS;FRESH;MUNCH", "TOMATO;TOMATOES;ARE;YUMMY;MUNCH", "SUSHI;SUSHI;IS;FISHY;MUNCH", "TUNA;TUNA;IS;FISHY;MUNCH", "SALMON;SALMON;IS;FISHY;MUNCH", "FISH;FISH;IS;FRESH;MUNCH", "BEANS;BEANS;ARE;YUMMY;MUNCH", "CEREAL;CEREAL;IS;GREAT;MUNCH", "PRETZEL;PRETZELS;ARE;SALTY;MUNCH", "EGGSALD;EGGSALAD;IS;GREAT;MUNCH", "RICE;RICE;IS;PLAIN;MUNCH", "CAVIAR;CAVIAR;IS;DIVINE;MUNCH"
            };
            var beverages = new List <string> {
                "BEER;BEER;IS;SMOOTH;GULP", "WINE;WINE;IS;RICH;GULP", "TEA;TEA;IS;FRESH;GULP", "COFFEE;COFFEE;IS;FRESH;GULP", "COLA;COLA;IS;SWEET;GULP", "COCOA;COCOA;IS;SWEET;GULP", "ICEDTEA;ICEDTEA;IS;SWEET;GULP", "LMONADE;LEMONADE;IS;SWEET;GULP", "MILK;MILK;IS;GREAT;GULP", "LATTE;LATTES;ARE;CREAMY;GULP", "WATER;WATER;IS;FRESH;GULP", "TEQUILA;TEQUILA;IS;SMOOTH;GULP"
            };

            switch (snack)
            {
            case FF1Lib.TitanSnack.Minerals:
                snackOptions = mineralSnacks;
                break;

            case FF1Lib.TitanSnack.Junk:
                snackOptions = junkFoodSnacks;
                break;

            case FF1Lib.TitanSnack.Healthy:
                snackOptions = healthySnacks;
                break;

            case FF1Lib.TitanSnack.Beverages:
                snackOptions = beverages;
                break;

            case FF1Lib.TitanSnack.All:
                // combine all lists together
                foreach (string mineral in mineralSnacks)
                {
                    snackOptions.Add(mineral);
                }
                foreach (string junkFood in junkFoodSnacks)
                {
                    snackOptions.Add(junkFood);
                }
                foreach (string healthySnack in healthySnacks)
                {
                    snackOptions.Add(healthySnack);
                }
                foreach (string beverage in beverages)
                {
                    snackOptions.Add(beverage);
                }
                break;

            default:
                return;
            }

            var dialogs = ReadText(dialogsPointerOffset, dialogsPointerBase, dialogsPointerCount);

            var randomRuby = snackOptions.PickRandom(rng);

            var newRubyItemDescription = "A tasty treat.";  // Replaces "A large red stone." (can't be too long else it'll overwrite next phrase: "The plate shatters,")
            var newTitanCraving        = "is hungry.";      // replaces "eat gems." (can't be too long or will appear outside window)

            if (beverages.Contains(randomRuby))
            {
                newRubyItemDescription = "A tasty drink.";
                newTitanCraving        = "is thirsty.";
            }
            else if (mineralSnacks.Contains(randomRuby))
            {
                newRubyItemDescription = "Feels heavy.";
            }
            // replace "A red stone." item description (0x38671) originally "8AFFAF2FAA1A23A724285AC000"
            Put(0x38671, FF1Text.TextToBytes(newRubyItemDescription, useDTE: true));

            // phrase parts
            var newRubyContent              = randomRuby.Split(";");
            var newRuby                     = newRubyContent[0];
            var newRubyPluralized           = newRubyContent[1];
            var newRubySubjectVerbAgreement = newRubyContent[2];
            var newRubyTastes               = newRubyContent[3];
            var newRubyOnomatopoeia         = newRubyContent[4];
            var newRubyArticle              = ""; // newRubySubjectVerbAgreement;

            if (newRubySubjectVerbAgreement == "ARE")
            {
                if (newRuby[0] == 'A' || newRuby[0] == 'E' || newRuby[0] == 'I' || newRuby[0] == 'O' || newRuby[0] == 'U')
                {
                    newRubyArticle = "an ";
                }
                else
                {
                    newRubyArticle = "a ";
                }
            }

            // handle extra dialogues that might contain the RUBY if the NPChints flag is enabled
            var dialogsUpdate = SubstituteKeyItemInExtraNPCDialogues("RUBY", newRuby, dialogs);

            // begin substitute phrase parts
            var titanDeepDungeon   = dialogs[0x29].Split(new string[] { "a RUBY" }, System.StringSplitOptions.RemoveEmptyEntries);
            var titanDialogue      = dialogs[0x2A].Split(new string[] { "RUBY", "Crunch, crunch, crunch,", "sweet", "Rubies are" }, System.StringSplitOptions.RemoveEmptyEntries);
            var melmondManDialogue = dialogs[0x7B].Split(new string[] { "eats gems.", "RUBIES" }, System.StringSplitOptions.RemoveEmptyEntries);

            // Bring me a {newRuby} if you
            // wish to skip to floor 22.
            if (titanDeepDungeon.Length > 1)
            {
                dialogsUpdate.Add(0x29, titanDeepDungeon[0] + newRubyArticle + newRuby + titanDeepDungeon[1]);
            }

            // If you want pass, give
            // me the {newRuby}..
            // {Onomatopoeia}, {onomatopoeia}, {onomatopoeia},
            // mmm, it tastes so {newRubyTastes}.
            // {newRubyPluralized} {newRubySubjectVerbAgreement} my favorite.
            if (titanDialogue.Length > 3)
            {
                dialogsUpdate.Add(0x2A, titanDialogue[0] + newRuby + titanDialogue[1]
                                  + CapitalizeFirstLowercaseRest(newRubyOnomatopoeia) + ", " + newRubyOnomatopoeia.ToLower() + ", " + newRubyOnomatopoeia.ToLower() + "," + titanDialogue[2]
                                  + newRubyTastes.ToLower() + titanDialogue[3]
                                  + CapitalizeFirstLowercaseRest(newRubyPluralized) + " " + newRubySubjectVerbAgreement.ToLower() + titanDialogue[4]);
            }
            else if (titanDialogue.Length > 1)
            {
                // handle Shuffle Astos, alternate Titan dialog "If you want pass, give\nme the RUBY..\nHa, it mine! Now, you in\ntrouble. Me am Astos,\nKing of the Titans!"
                dialogsUpdate.Add(0x2A, titanDialogue[0] + newRuby + titanDialogue[1]);
            }
            // The Titan who lives in
            // the tunnel {newTitanCraving}
            // He loves {newRubyPluralized}.
            if (melmondManDialogue.Length > 2)
            {
                dialogsUpdate.Add(0x7B, melmondManDialogue[0] + newTitanCraving + melmondManDialogue[1] + newRubyPluralized + melmondManDialogue[2]);
            }
            // end substitute phrase parts

            if (dialogsUpdate.Count > 0)
            {
                InsertDialogs(dialogsUpdate);
            }

            // substitute key item
            ItemsText[(int)Item.Ruby] = newRuby;
        }
 public DefaultHintPlacmentProvider(MT19337 _rng, NPCdata _npcData, Flags _flags, OverworldMap _overworldMap, FF1Rom _rom) : base(_rng, _npcData, _flags, _overworldMap, _rom)
 {
     PlacementPools = StrategyDic.Select(s => (key: s.Key, values: s.Value.SelectMany(l => LocationDic[l]))).ToDictionary(s => s.key, s => s.values.ToList());
 }
Пример #13
0
		public LooseFloorHintSource(MT19337 _rng, NPCdata _npcData, Flags _flags, OverworldMap _overworldMap, FF1Rom _rom) : base(_rng, _npcData, _flags, _overworldMap, _rom)
		{
		}
Пример #14
0
        public void Load(BinaryReader reader, float saveVersion)
        {
            int count = reader.ReadInt32();

            RoomTemplates = new List <string>(count);
            for (int i = 0; i < count; i++)
            {
                this.RoomTemplates.Add(reader.ReadString());
            }

            count         = reader.ReadInt32();
            RoomInstances = new List <RoomInstance>(count);
            for (int j = 0; j < count; j++)
            {
                RoomInstance roomInstance = new RoomInstance();
                roomInstance.Load(reader);
                this.RoomInstances.Add(roomInstance);
            }

            this.TransitionLeftEnd  = new RoomInstance();
            this.TransitionRightEnd = new RoomInstance();
            if (reader.ReadBoolean())
            {
                this.TransitionLeftEnd.Load(reader);
                this.TransitionRightEnd.Load(reader);
            }
            count           = reader.ReadInt32();
            RoomTransitions = new HashSet <int>();
            for (int k = 0; k < count; k++)
            {
                this.RoomTransitions.Add(reader.ReadInt32());
            }

            count = reader.ReadInt32();
            Areas = new Dictionary <string, List <Dungeon> >(count);
            for (int l = 0; l < count; l++)
            {
                string key       = reader.ReadString();
                int    areaCount = reader.ReadInt32();
                var    area      = new List <Dungeon>(areaCount);
                for (int m = 0; m < areaCount; m++)
                {
                    Dungeon dungeon = new Dungeon();
                    dungeon.Load(reader);
                    area.Add(dungeon);
                }
                Areas.Add(key, area);
            }
            foreach (var areas in Areas.Values)
            {
                foreach (var dungeon in areas)
                {
                    dungeon.LoadConnections(reader);
                }
            }

            count = reader.ReadInt32();
            for (int n = 0; n < count; n++)
            {
                int key  = reader.ReadInt32();
                var room = this.RoomInstances.Where(x => x.Id == key).First();
                room.LoadChests(reader);
            }

            NPCinventory = new NPCdata();
            NPCinventory.LoadInventory(reader, saveVersion);
        }
 public FloorHintsHintSource(MT19337 _rng, NPCdata _npcData, Flags _flags, OverworldMap _overworldMap, FF1Rom _rom) : base(_rng, _npcData, _flags, _overworldMap, _rom)
 {
     Prices = new ItemPrices(_rom);
 }