示例#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,
                                                     OverworldMap overworldMap,
                                                     TeleportShuffle teleporters,
                                                     ISanityChecker checker)
        {
            Dictionary <MapLocation, Tuple <List <MapChange>, AccessRequirement> > fullFloorRequirements = overworldMap.FullLocationRequirements;
            Dictionary <MapLocation, OverworldTeleportIndex> overridenOverworld = overworldMap.OverriddenOverworldLocations;

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

            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, checker);
            var           placedItems = placement.PlaceSaneItems(rng, this);

            // 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.IsShipFree ?? false) && !(flags.DesertOfDeath))
            {
                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);
        }
        public static ItemPlacement Create(IItemPlacementFlags flags, IncentiveData incentivesData, List <Item> allTreasures, ItemShopSlot caravanItemLocation, OverworldMap overworldMap, ISanityChecker checker)
        {
            ItemPlacement placement;

            placement = flags.PredictivePlacement && checker is SanityCheckerV2 ? new PredictivePlacement() : new GuidedItemPlacement();

            placement._flags               = flags;
            placement._incentivesData      = incentivesData;
            placement._allTreasures        = allTreasures;
            placement._caravanItemLocation = caravanItemLocation;
            placement._overworldMap        = overworldMap;
            placement._checker             = checker;

            return(placement);
        }
        public IncentiveData(MT19337 rng, IIncentiveFlags flags, OverworldMap map, ItemShopSlot shopSlot, ISanityChecker checker)
        {
            OverworldMap = map;
            _checker     = checker;

            List <(bool, Item)> incentivizedItemsFlags = new() {
                ((bool)flags.IncentivizeBridge, Item.Bridge),
                ((bool)flags.IncentivizeShip, Item.Ship),
                ((bool)flags.IncentivizeCanal, Item.Canal),
                ((bool)flags.IncentivizeLute, Item.Lute),
                ((bool)flags.IncentivizeCrown, Item.Crown),
                ((bool)flags.IncentivizeCrystal, Item.Crystal),
                ((bool)flags.IncentivizeHerb, Item.Herb),
                ((bool)flags.IncentivizeKey, Item.Key),
                ((bool)flags.IncentivizeTnt, Item.Tnt),
                ((bool)flags.IncentivizeAdamant, Item.Adamant),
                ((bool)flags.IncentivizeSlab, Item.Slab),
                ((bool)flags.IncentivizeRuby, Item.Ruby),
                ((bool)flags.IncentivizeRod, Item.Rod),
                ((bool)flags.IncentivizeFloater, Item.Floater),
                ((bool)flags.IncentivizeChime, Item.Chime),
                ((bool)flags.IncentivizePromotion, Item.Tail),
                ((bool)flags.IncentivizeCube, Item.Cube),
                ((bool)flags.IncentivizeBottle, Item.Bottle),
                ((bool)flags.IncentivizeOxyale, Item.Oxyale),
                ((bool)flags.IncentivizeCanoe, Item.Canoe),
                ((bool)flags.IncentivizeXcalber, Item.Xcalber),
                ((bool)flags.IncentivizeMasamune, Item.Masamune),
                ((bool)flags.IncentivizeKatana, Item.Katana),
                ((bool)flags.IncentivizeVorpal, Item.Vorpal),
                ((bool)flags.IncentivizeRibbon, Item.Ribbon),
                ((bool)flags.IncentivizeRibbon2, Item.Ribbon),
                ((bool)flags.IncentivizeOpal, Item.Opal),
                ((bool)flags.Incentivize65K, Item.Gold65000),
                ((bool)flags.IncentivizeBad, Item.Cloth),
                ((bool)flags.IncentivizeDefCastArmor, Item.WhiteShirt),
                ((bool)flags.IncentivizeOffCastArmor, Item.BlackShirt),
                ((bool)flags.IncentivizeOtherCastArmor, Item.PowerGauntlets),
                ((bool)flags.IncentivizePowerRod, Item.PowerRod),
                ((bool)flags.IncentivizeDefCastWeapon, Item.Defense),
                ((bool)flags.IncentivizeOffCastWeapon, Item.ThorHammer),
                ((bool)flags.IncentivizeOtherCastWeapon, Item.BaneSword),
            };

            List <(bool, IRewardSource)> incentivizedNpcsFlags = new() {
                ((bool)flags.IncentivizeKingConeria, ItemLocations.KingConeria),
                ((bool)flags.IncentivizePrincess, ItemLocations.Princess),
                ((bool)flags.IncentivizeMatoya, ItemLocations.Matoya),
                ((bool)flags.IncentivizeBikke, ItemLocations.Bikke),
                ((bool)flags.IncentivizeElfPrince, ItemLocations.ElfPrince),
                ((bool)flags.IncentivizeAstos, ItemLocations.Astos),
                ((bool)flags.IncentivizeNerrick, ItemLocations.Nerrick),
                ((bool)flags.IncentivizeSmith, ItemLocations.Smith),
                ((bool)flags.IncentivizeSarda, ItemLocations.Sarda),
                ((bool)flags.IncentivizeCanoeSage, ItemLocations.CanoeSage),
                ((bool)flags.IncentivizeCubeBot, ItemLocations.CubeBot),
                ((bool)flags.IncentivizeFairy, ItemLocations.Fairy),
                ((bool)flags.IncentivizeLefein, ItemLocations.Lefein),
                ((bool)flags.IncentivizeCaravan, ItemLocations.CaravanItemShop1),
            };

            List <(bool, Item)> removedItemsFlags = new()
            {
                ((bool)flags.NoMasamune, Item.Masamune),
                ((bool)flags.NoXcalber, Item.Xcalber),
                ((bool)flags.NoTail, Item.Tail),
                ((bool)flags.IsFloaterRemoved, Item.Floater),
                ((bool)flags.IsCanoeFree, Item.Canoe),
                ((bool)flags.FreeLute, Item.Lute),
                ((bool)flags.FreeTail, Item.Tail),
                ((bool)flags.IsBridgeFree, Item.Bridge),
                ((bool)flags.IsCanalFree, Item.Canal),
                ((bool)flags.IsShipFree, Item.Ship),
            };

            List <(bool, IRewardSource)> removedNPCItemsLocations = new()
            {
                ((bool)flags.IsCanoeFree, ItemLocations.CanoeSage),
                ((bool)flags.FreeLute, ItemLocations.Princess),
                ((bool)flags.IsBridgeFree, ItemLocations.KingConeria),
                ((bool)flags.IsShipFree, ItemLocations.Bikke),
            };

            List <(bool, IRewardSource)> removedNPCFetchItemsLocations = new()
            {
                ((bool)flags.NoXcalber, ItemLocations.Smith),
                ((bool)flags.IsCanalFree, ItemLocations.Nerrick),
            };

            Dictionary <MapLocation, Tuple <List <MapChange>, AccessRequirement> > fullLocationRequirements = map.FullLocationRequirements;
            var forcedItemPlacements = ItemLocations.AllOtherItemLocations.ToList();

            if (!(flags.NPCItems ?? false))
            {
                forcedItemPlacements.AddRange(ItemLocations.AllNPCFreeItemLocationsExcludingVendor.Except(removedNPCItemsLocations.Where(x => x.Item1 == true).Select(x => x.Item2).ToList()));
                forcedItemPlacements.Add(shopSlot);
            }

            if (!(flags.NPCFetchItems ?? false))
            {
                forcedItemPlacements.AddRange(ItemLocations.AllNPCFetchItemLocations.Except(removedNPCFetchItemsLocations.Where(x => x.Item1 == true).Select(x => x.Item2).ToList()));
            }
            else if (flags.NoOverworld)
            {
                forcedItemPlacements.Add(ItemLocations.Nerrick);
            }

            if ((!flags.Treasures ?? false))
            {
                forcedItemPlacements.AddRange(ItemLocations.AllTreasures);
            }

            if (flags.GuaranteedMasamune ?? false)
            {
                forcedItemPlacements.Add(ItemLocations.ToFRMasmune);
            }

            List <Item> removedItems = removedItemsFlags.Where(x => x.Item1 == true).Select(x => x.Item2).ToList();

            List <Item> incentivePool = incentivizedItemsFlags.Where(x => x.Item1 == true).Select(x => x.Item2).ToList();

            List <IRewardSource> incentiveLocationPool = incentivizedNpcsFlags.Where(x => x.Item1 == true).Select(x => x.Item2).ToList();

            incentiveLocationPool.AddRange(SelectIncentivizedChests(flags, rng));

            var itemLocationPool =
                ItemLocations.AllTreasures.Concat(ItemLocations.AllNPCItemLocations)
                .Where(x => !x.IsUnused && !forcedItemPlacements.Any(y => y.Address == x.Address))
                .ToList();

            if ((bool)flags.EarlyOrdeals)
            {
                forcedItemPlacements =
                    forcedItemPlacements
                    .Select(x => ((x as TreasureChest)?.AccessRequirement.HasFlag(AccessRequirement.Crown) ?? false)
                                                                ? new TreasureChest(x, x.Item, x.AccessRequirement & ~AccessRequirement.Crown)
                                                                : x).ToList();
                itemLocationPool =
                    itemLocationPool
                    .Select(x => ((x as TreasureChest)?.AccessRequirement.HasFlag(AccessRequirement.Crown) ?? false)
                                                                ? new TreasureChest(x, x.Item, x.AccessRequirement & ~AccessRequirement.Crown)
                                                                : x).ToList();
                incentiveLocationPool =
                    incentiveLocationPool
                    .Select(x => ((x as TreasureChest)?.AccessRequirement.HasFlag(AccessRequirement.Crown) ?? false)
                                                        ? new TreasureChest(x, x.Item, x.AccessRequirement & ~AccessRequirement.Crown)
                                                        : x).ToList();
            }
            if ((bool)flags.EarlyKing)
            {
                forcedItemPlacements =
                    forcedItemPlacements
                    .Select(x => x.Address == ItemLocations.KingConeria.Address
                                                                        ? new MapObject(ObjectId.King, MapLocation.ConeriaCastle2, x.Item)
                                                                        : x).ToList();
                itemLocationPool =
                    itemLocationPool
                    .Select(x => x.Address == ItemLocations.KingConeria.Address
                                                                        ? new MapObject(ObjectId.King, MapLocation.ConeriaCastle2, x.Item)
                                                                        : x).ToList();
                incentiveLocationPool =
                    incentiveLocationPool
                    .Select(x => x.Address == ItemLocations.KingConeria.Address
                                                                        ? new MapObject(ObjectId.King, MapLocation.ConeriaCastle2, x.Item)
                                                                        : x).ToList();
            }
            if ((bool)flags.EarlySage)
            {
                forcedItemPlacements =
                    forcedItemPlacements
                    .Select(x => x.Address == ItemLocations.CanoeSage.Address
                                                                        ? new MapObject(ObjectId.CanoeSage, MapLocation.CrescentLake, x.Item)
                                                                        : x).ToList();
                itemLocationPool =
                    itemLocationPool
                    .Select(x => x.Address == ItemLocations.CanoeSage.Address
                                                                        ? new MapObject(ObjectId.CanoeSage, MapLocation.CrescentLake, x.Item)
                                                                        : x).ToList();
                incentiveLocationPool =
                    incentiveLocationPool
                    .Select(x => x.Address == ItemLocations.CanoeSage.Address
                                                                        ? new MapObject(ObjectId.CanoeSage, MapLocation.CrescentLake, x.Item)
                                                                        : x).ToList();
            }
            if ((bool)flags.EarlySarda)
            {
                forcedItemPlacements =
                    forcedItemPlacements
                    .Select(x => x.Address == ItemLocations.Sarda.Address
                                                                ? new MapObject(ObjectId.Sarda, MapLocation.SardasCave, x.Item)
                                                                : x).ToList();
                itemLocationPool =
                    itemLocationPool
                    .Select(x => x.Address == ItemLocations.Sarda.Address
                                                                ? new MapObject(ObjectId.Sarda, MapLocation.SardasCave, x.Item)
                                                                : x).ToList();
                incentiveLocationPool =
                    incentiveLocationPool
                    .Select(x => x.Address == ItemLocations.Sarda.Address
                                                                ? new MapObject(ObjectId.Sarda, MapLocation.SardasCave, x.Item)
                                                                : x).ToList();
            }

            MapLocation elfDoctorLocation = map.ObjectiveNPCs[ObjectId.ElfDoc];

            if (elfDoctorLocation != MapLocation.ElflandCastle)
            {
                forcedItemPlacements =
                    forcedItemPlacements
                    .Select(x => x.Address == ItemLocations.ElfPrince.Address
                                                                ? new MapObject(ObjectId.ElfPrince, MapLocation.ElflandCastle, x.Item, AccessRequirement.Herb, ObjectId.ElfDoc, requiredSecondLocation: elfDoctorLocation)
                                                                : x).ToList();
                itemLocationPool =
                    itemLocationPool
                    .Select(x => x.Address == ItemLocations.ElfPrince.Address
                                                                ? new MapObject(ObjectId.ElfPrince, MapLocation.ElflandCastle, x.Item, AccessRequirement.Herb, ObjectId.ElfDoc, requiredSecondLocation: elfDoctorLocation)
                                                                : x).ToList();
                incentiveLocationPool =
                    incentiveLocationPool
                    .Select(x => x.Address == ItemLocations.ElfPrince.Address
                                                                ? new MapObject(ObjectId.ElfPrince, MapLocation.ElflandCastle, x.Item, AccessRequirement.Herb, ObjectId.ElfDoc, requiredSecondLocation: elfDoctorLocation)
                                                                : x).ToList();
            }

            MapLocation unneLocation = map.ObjectiveNPCs[ObjectId.Unne];

            if (unneLocation != MapLocation.Melmond)
            {
                forcedItemPlacements =
                    forcedItemPlacements
                    .Select(x => x.Address == ItemLocations.Lefein.Address
                                                                ? new MapObject(ObjectId.Lefein, MapLocation.Lefein, x.Item, AccessRequirement.Slab, ObjectId.Unne, requiredSecondLocation: unneLocation)
                                                                : x).ToList();
                itemLocationPool =
                    itemLocationPool
                    .Select(x => x.Address == ItemLocations.Lefein.Address
                                                                ? new MapObject(ObjectId.Lefein, MapLocation.Lefein, x.Item, AccessRequirement.Slab, ObjectId.Unne, requiredSecondLocation: unneLocation)
                                                                : x).ToList();
                incentiveLocationPool =
                    incentiveLocationPool
                    .Select(x => x.Address == ItemLocations.Lefein.Address
                                                                ? new MapObject(ObjectId.Lefein, MapLocation.Lefein, x.Item, AccessRequirement.Slab, ObjectId.Unne, requiredSecondLocation: unneLocation)
                                                                : x).ToList();
            }

            foreach (var item in forcedItemPlacements.Select(x => x.Item))
            {
                if ((bool)flags.GuaranteedMasamune && item == Item.Masamune)
                {
                    continue;
                }
                incentivePool.Remove(item);
            }

            foreach (var item in removedItems)
            {
                incentivePool.Remove(item);
            }

            var nonEndgameMapLocations = _checker.AccessibleMapLocations(~AccessRequirement.BlackOrb, MapChange.All, fullLocationRequirements);

            ForcedItemPlacements = forcedItemPlacements.ToList();
            IncentiveItems       = incentivePool.ToList();

            RemovedItems = removedItems.ToList();

            IncentiveLocations = incentiveLocationPool
                                 .Where(x => !forcedItemPlacements.Any(y => y.Address == x.Address))
                                 .ToList();

            AllValidItemLocations            = itemLocationPool.ToList();
            AllValidPreBlackOrbItemLocations = AllValidItemLocations
                                               .Where(x => nonEndgameMapLocations.Contains(x.MapLocation) && nonEndgameMapLocations.Contains((x as MapObject)?.SecondLocation ?? MapLocation.StartingLocation))
                                               .ToList();
        }
示例#4
0
 public RewardSourcePicker(double _reduction, double _nonchest, ISanityChecker _checker)
 {
     reduction = _reduction;
     nonchest  = _nonchest;
     checker   = _checker;
 }
示例#5
0
 public Init(IAuth auth, INoticeBoard notices, ISanityChecker check)
 {
     this._auth    = auth;
     this._notices = notices;
     this._check   = check;
 }
示例#6
0
 public InitSanityCheckFilter(ISanityChecker checker, INoticeBoard nb)
 {
     this._checker = checker;
     this._nb      = nb;
 }