示例#1
0
        public static readonly List <int> UsedTreasureIndices = Enumerable.Range(0, 256).Except(UnusedTreasureIndices).ToList();        // This maps a compacted list back to the game's array, skipping the unused slots.

        public List <IRewardSource> ShuffleTreasures(MT19337 rng,
                                                     IItemPlacementFlags flags,
                                                     IncentiveData incentivesData,
                                                     ItemShopSlot caravanItemLocation,
                                                     Dictionary <MapLocation, List <MapChange> > mapLocationRequirements)
        {
            var vanillaNPCs = !flags.NPCItems && !flags.NPCFetchItems;

            if (!vanillaNPCs)
            {
                EnableBridgeShipCanalAnywhere();
                EnableNPCsGiveAnyItem();
                // This extends Vampire's routine to set a flag for Sarda, but it also clobers Sarda's routine
                if (!flags.EarlySarda)
                {
                    Put(0x393E1, Blob.FromHex("207F90A51160"));
                }
            }

            var treasureBlob = Get(TreasureOffset, TreasureSize * TreasureCount);
            var treasurePool = UsedTreasureIndices.Select(x => (Item)treasureBlob[x])
                               .Concat(ItemLists.AllNonTreasureChestItems).ToList();

            if (flags.ShardHunt)
            {
                treasurePool = treasurePool.Select(ShardHuntTreasureSelector).ToList();
                int shardsAdded = treasurePool.Count(item => item == Item.Shard);
                Debug.Assert(shardsAdded == TotalOrbsToInsert);
            }

            var placedItems =
                ItemPlacement.PlaceSaneItems(rng,
                                             flags,
                                             incentivesData,
                                             treasurePool,
                                             caravanItemLocation,
                                             mapLocationRequirements);

            if (flags.FreeBridge)
            {
                placedItems = placedItems.Select(x => x.Item != Item.Bridge ? x : ItemPlacement.NewItemPlacement(x, ReplacementItem)).ToList();
            }
            if (flags.FreeAirship)
            {
                placedItems = placedItems.Select(x => x.Item != Item.Floater ? x : ItemPlacement.NewItemPlacement(x, ReplacementItem)).ToList();
            }

            // Output the results to the ROM
            foreach (var item in placedItems.Where(x => !x.IsUnused && x.Address < 0x80000 && (!vanillaNPCs || x is TreasureChest)))
            {
                //Debug.WriteLine(item.SpoilerText);
                item.Put(this);
            }

            MoveShipToRewardSource(placedItems.Find(reward => reward.Item == Item.Ship));
            return(placedItems);
        }
示例#2
0
        public static readonly List <int> UsedTreasureIndices = Enumerable.Range(0, 256).Except(UnusedTreasureIndices).ToList();        // This maps a compacted list back to the game's array, skipping the unused slots.

        public List <IRewardSource> ShuffleTreasures(MT19337 rng,
                                                     IItemPlacementFlags flags,
                                                     IncentiveData incentivesData,
                                                     ItemShopSlot caravanItemLocation,
                                                     OverworldMap overworldMap,
                                                     TeleportShuffle teleporters)
        {
            Dictionary <MapLocation, Tuple <List <MapChange>, AccessRequirement> > fullFloorRequirements = overworldMap.FullLocationRequirements;
            Dictionary <MapLocation, OverworldTeleportIndex> overridenOverworld = overworldMap.OverriddenOverworldLocations;

            var vanillaNPCs = !(flags.NPCItems ?? false) && !(flags.NPCFetchItems ?? false);

            if (!vanillaNPCs)
            {
                EnableBridgeShipCanalAnywhere();
                EnableNPCsGiveAnyItem();
                // This extends Vampire's routine to set a flag for Sarda, but it also clobers Sarda's routine
                if (!(bool)flags.EarlySarda)
                {
                    Put(0x393E1, Blob.FromHex("207F90A51160"));
                }
            }

            var treasureBlob = Get(TreasureOffset, TreasureSize * TreasureCount);
            var treasurePool = UsedTreasureIndices.Select(x => (Item)treasureBlob[x])
                               .Concat(ItemLists.AllNonTreasureChestItems).ToList();

            if (flags.ShardHunt)
            {
                treasurePool = treasurePool.Select(ShardHuntTreasureSelector).ToList();
                int shardsAdded = treasurePool.Count(item => item == Item.Shard);
                Debug.Assert(shardsAdded == TotalOrbsToInsert);
            }

            ItemPlacement placement   = ItemPlacement.Create(flags, incentivesData, treasurePool, caravanItemLocation, overworldMap);
            var           placedItems = placement.PlaceSaneItems(rng);

            // Output the results to the ROM
            foreach (var item in placedItems.Where(x => !x.IsUnused && x.Address < 0x80000 && (!vanillaNPCs || x is TreasureChest)))
            {
                //Debug.WriteLine(item.SpoilerText);
                item.Put(this);
            }
            // Move the ship someplace closer to where it really ends up.
            if (!(flags.FreeShip ?? false))
            {
                MapLocation shipLocation = placedItems.Find(reward => reward.Item == Item.Ship).MapLocation;
                if (overridenOverworld != null && overridenOverworld.TryGetValue(shipLocation, out var overworldIndex))
                {
                    shipLocation = teleporters.OverworldMapLocations.TryGetValue(overworldIndex, out var vanillaShipLocation) ? vanillaShipLocation : shipLocation;
                }
                MoveShipToRewardSource(shipLocation);
            }
            return(placedItems);
        }
示例#3
0
        public static readonly List <int> UsedTreasureIndices = Enumerable.Range(0, 256).Except(UnusedTreasureIndices).ToList();        // This maps a compacted list back to the game's array, skipping the unused slots.

        public List <IRewardSource> ShuffleTreasures(MT19337 rng,
                                                     ITreasureShuffleFlags flags,
                                                     IncentiveData incentivesData,
                                                     ItemShopSlot caravanItemLocation,
                                                     Dictionary <MapLocation, List <MapChange> > mapLocationRequirements)
        {
            if (flags.NPCItems)
            {
                EnableBridgeShipCanalAnywhere();
                EnableNPCsGiveAnyItem();
                // This extends Vampire's routine to set a flag for Sarda, but it also clobers Sarda's routine
                if (!flags.EarlyRod)
                {
                    Put(0x393E1, Blob.FromHex("207F90A51160"));
                }
            }

            var treasureBlob = Get(TreasureOffset, TreasureSize * TreasureCount);
            var treasurePool = UsedTreasureIndices.Select(x => (Item)treasureBlob[x])
                               .Concat(ItemLists.AllNonTreasureChestItems).ToList();

            if (flags.OrbHunt)
            {
                treasurePool = treasurePool.Select(OrbHuntTreasureSelector).ToList();
                System.Diagnostics.Debug.Assert(treasurePool.Count(item => item == Item.Shard) == TotalOrbsToInsert);
            }

            var placedItems =
                ItemPlacement.PlaceSaneItems(rng,
                                             flags,
                                             incentivesData,
                                             treasurePool,
                                             caravanItemLocation,
                                             mapLocationRequirements);

            // Output the results tothe ROM
            foreach (var item in placedItems.Where(x => !x.IsUnused && x.Address < 0x80000 && !incentivesData.ForcedItemPlacements.Any(y => y.Address == x.Address)))
            {
                //Debug.WriteLine(item.SpoilerText);
                item.Put(this);
            }
            return(placedItems);
        }