Esempio n. 1
0
        public IncentiveData(MT19337 rng, IIncentiveFlags flags, OverworldMap map)
        {
            Dictionary <MapLocation, Tuple <List <MapChange>, AccessRequirement> > fullLocationRequirements = map.FullLocationRequirements;
            var forcedItemPlacements = ItemLocations.AllOtherItemLocations.ToList();

            if (!flags.NPCItems)
            {
                forcedItemPlacements.AddRange(ItemLocations.AllNPCFreeItemLocations);
            }
            if (!flags.NPCFetchItems)
            {
                forcedItemPlacements.AddRange(ItemLocations.AllNPCFetchItemLocations);
            }
            if (!flags.Treasures)
            {
                forcedItemPlacements.AddRange(ItemLocations.AllTreasures);
            }
            var incentivePool = new List <Item>();

            if (flags.IncentivizeBridge)
            {
                incentivePool.Add(Item.Bridge);
            }
            if (flags.IncentivizeShip)
            {
                incentivePool.Add(Item.Ship);
            }
            if (flags.IncentivizeCanal)
            {
                incentivePool.Add(Item.Canal);
            }
            if (flags.IncentivizeLute)
            {
                incentivePool.Add(Item.Lute);
            }
            if (flags.IncentivizeCrown)
            {
                incentivePool.Add(Item.Crown);
            }
            if (flags.IncentivizeCrystal)
            {
                incentivePool.Add(Item.Crystal);
            }
            if (flags.IncentivizeHerb)
            {
                incentivePool.Add(Item.Herb);
            }
            if (flags.IncentivizeKey)
            {
                incentivePool.Add(Item.Key);
            }
            if (flags.IncentivizeTnt)
            {
                incentivePool.Add(Item.Tnt);
            }
            if (flags.IncentivizeAdamant)
            {
                incentivePool.Add(Item.Adamant);
            }
            if (flags.IncentivizeSlab)
            {
                incentivePool.Add(Item.Slab);
            }
            if (flags.IncentivizeRuby)
            {
                incentivePool.Add(Item.Ruby);
            }
            if (flags.IncentivizeRod)
            {
                incentivePool.Add(Item.Rod);
            }
            if (flags.IncentivizeFloater)
            {
                incentivePool.Add(Item.Floater);
            }
            if (flags.IncentivizeChime)
            {
                incentivePool.Add(Item.Chime);
            }
            if (flags.IncentivizeTail)
            {
                incentivePool.Add(Item.Tail);
            }
            if (flags.IncentivizeCube)
            {
                incentivePool.Add(Item.Cube);
            }
            if (flags.IncentivizeBottle)
            {
                incentivePool.Add(Item.Bottle);
            }
            if (flags.IncentivizeOxyale)
            {
                incentivePool.Add(Item.Oxyale);
            }
            if (flags.IncentivizeCanoe)
            {
                incentivePool.Add(Item.Canoe);
            }

            if (flags.IncentivizeXcalber)
            {
                incentivePool.Add(Item.Xcalber);
            }
            if (flags.IncentivizeMasamune)
            {
                incentivePool.Add(Item.Masamune);
            }
            if (flags.IncentivizeRibbon)
            {
                incentivePool.Add(Item.Ribbon);
            }
            if (flags.IncentivizeRibbon2)
            {
                incentivePool.Add(Item.Ribbon);
            }
            if (flags.IncentivizeOpal)
            {
                incentivePool.Add(Item.Opal);
            }
            if (flags.Incentivize65K)
            {
                incentivePool.Add(Item.Gold65000);
            }
            if (flags.IncentivizeBad)
            {
                incentivePool.Add(Item.Cloth);
            }
            if (flags.IncentivizeDefCastArmor)
            {
                incentivePool.Add(Item.WhiteShirt);
            }
            if (flags.IncentivizeOffCastArmor)
            {
                incentivePool.Add(Item.BlackShirt);
            }
            if (flags.IncentivizeOtherCastArmor)
            {
                incentivePool.Add(Item.PowerGauntlets);
            }
            if (flags.IncentivizeDefCastWeapon)
            {
                incentivePool.Add(Item.Defense);
            }
            if (flags.IncentivizeOffCastWeapon)
            {
                incentivePool.Add(Item.ThorHammer);
            }
            if (flags.IncentivizeOtherCastWeapon)
            {
                incentivePool.Add(Item.BaneSword);
            }

            var incentiveLocationPool = new List <IRewardSource>();

            if (flags.IncentivizeKingConeria)
            {
                incentiveLocationPool.Add(ItemLocations.KingConeria);
            }
            if (flags.IncentivizePrincess)
            {
                incentiveLocationPool.Add(ItemLocations.Princess);
            }
            if (flags.IncentivizeMatoya)
            {
                incentiveLocationPool.Add(ItemLocations.Matoya);
            }
            if (flags.IncentivizeBikke)
            {
                incentiveLocationPool.Add(ItemLocations.Bikke);
            }
            if (flags.IncentivizeElfPrince)
            {
                incentiveLocationPool.Add(ItemLocations.ElfPrince);
            }
            if (flags.IncentivizeAstos)
            {
                incentiveLocationPool.Add(ItemLocations.Astos);
            }
            if (flags.IncentivizeNerrick)
            {
                incentiveLocationPool.Add(ItemLocations.Nerrick);
            }
            if (flags.IncentivizeSmith)
            {
                incentiveLocationPool.Add(ItemLocations.Smith);
            }
            if (flags.IncentivizeSarda)
            {
                incentiveLocationPool.Add(ItemLocations.Sarda);
            }
            if (flags.IncentivizeCanoeSage)
            {
                incentiveLocationPool.Add(ItemLocations.CanoeSage);
            }
            if (flags.IncentivizeCubeBot)
            {
                incentiveLocationPool.Add(ItemLocations.CubeBot);
            }
            if (flags.IncentivizeFairy)
            {
                incentiveLocationPool.Add(ItemLocations.Fairy);
            }
            if (flags.IncentivizeLefein)
            {
                incentiveLocationPool.Add(ItemLocations.Lefein);
            }
            if (flags.IncentivizeVolcano)
            {
                incentiveLocationPool.Add(ItemLocations.VolcanoMajor);
            }
            if (flags.IncentivizeEarth)
            {
                incentiveLocationPool.Add(ItemLocations.EarthCaveMajor);
            }
            if (flags.IncentivizeMarsh)
            {
                incentiveLocationPool.Add(ItemLocations.MarshCaveMajor);
            }
            if (flags.IncentivizeMarshKeyLocked)
            {
                incentiveLocationPool.Add(ItemLocations.MarshCave13);
            }
            if (flags.IncentivizeSkyPalace)
            {
                incentiveLocationPool.Add(ItemLocations.SkyPalaceMajor);
            }
            if (flags.IncentivizeSeaShrine)
            {
                incentiveLocationPool.Add(ItemLocations.SeaShrineMajor);
            }
            if (flags.IncentivizeConeria)
            {
                incentiveLocationPool.Add(ItemLocations.ConeriaMajor);
            }
            if (flags.IncentivizeIceCave)
            {
                incentiveLocationPool.Add(ItemLocations.IceCaveMajor);
            }
            if (flags.IncentivizeOrdeals)
            {
                incentiveLocationPool.Add(ItemLocations.OrdealsMajor);
            }
            if (flags.IncentivizeCaravan)
            {
                incentiveLocationPool.Add(ItemLocations.CaravanItemShop1);
            }
            var itemLocationPool =
                ItemLocations.AllTreasures.Concat(ItemLocations.AllNPCItemLocations)
                .Where(x => !x.IsUnused && !forcedItemPlacements.Any(y => y.Address == x.Address))
                .ToList();

            if (flags.CrownlessOrdeals)
            {
                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 (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 (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))
            {
                incentivePool.Remove(item);
            }

            var validKeyLocations = new List <IRewardSource> {
                ItemLocations.ElfPrince
            };
            var validBridgeLocations = new List <IRewardSource> {
                ItemLocations.KingConeria
            };
            var validShipLocations = new List <IRewardSource> {
                ItemLocations.Bikke
            };
            var validCanoeLocations = new List <IRewardSource> {
                ItemLocations.CanoeSage
            };

            if (flags.NPCFetchItems)
            {
                var validKeyMapLocations = ItemPlacement.AccessibleMapLocations(~(AccessRequirement.BlackOrb | AccessRequirement.Key), MapChange.All, fullLocationRequirements);
                validKeyLocations = itemLocationPool.Where(x => validKeyMapLocations.Contains(x.MapLocation) &&
                                                           validKeyMapLocations.Contains((x as MapObject)?.SecondLocation ?? MapLocation.StartingLocation)).ToList();
                var keyPlacementRank = rng.Between(1, incentivePool.Count);
                if (incentivePool.Contains(Item.Key) && incentiveLocationPool.Any(x => validKeyLocations.Any(y => y.Address == x.Address)) && keyPlacementRank <= incentiveLocationPool.Count)
                {
                    validKeyLocations = validKeyLocations.Where(x => incentiveLocationPool.Any(y => y.Address == x.Address)).ToList();
                }
                else if (!flags.IncentivizeKey && incentivePool.Count >= incentiveLocationPool.Count)
                {
                    validKeyLocations = validKeyLocations.Where(x => !incentiveLocationPool.Any(y => y.Address == x.Address)).ToList();
                }
            }

            if (flags.NPCItems)
            {
                var everythingButCanoe      = ~MapChange.Canoe;
                var everythingButOrbs       = ~AccessRequirement.BlackOrb;
                var startingPotentialAccess = map.StartingPotentialAccess;
                var startingMapLocations    = ItemPlacement.AccessibleMapLocations(startingPotentialAccess, MapChange.None, fullLocationRequirements);
                var validShipMapLocations   = ItemPlacement.AccessibleMapLocations(startingPotentialAccess | AccessRequirement.Crystal, MapChange.Bridge, fullLocationRequirements);
                var validCanoeMapLocations  = ItemPlacement.AccessibleMapLocations(everythingButOrbs, everythingButCanoe, fullLocationRequirements);

                validBridgeLocations =
                    itemLocationPool.Where(x => startingMapLocations.Contains(x.MapLocation) &&
                                           startingMapLocations.Contains((x as MapObject)?.SecondLocation ?? MapLocation.StartingLocation)).ToList();
                validShipLocations =
                    itemLocationPool.Where(x => validShipMapLocations.Contains(x.MapLocation) &&
                                           validShipMapLocations.Contains((x as MapObject)?.SecondLocation ?? MapLocation.StartingLocation)).ToList();
                validCanoeLocations =
                    itemLocationPool.Where(x => validCanoeMapLocations.Contains(x.MapLocation) &&
                                           validCanoeMapLocations.Contains((x as MapObject)?.SecondLocation ?? MapLocation.StartingLocation)).ToList();

                var canoePlacementRank   = rng.Between(1, incentivePool.Count);
                var validCanoeIncentives = validCanoeLocations.Where(x => incentiveLocationPool.Any(y => y.Address == x.Address)).ToList();
                if (incentivePool.Contains(Item.Canoe) && canoePlacementRank <= incentiveLocationPool.Count &&
                    validKeyLocations.Union(validCanoeIncentives).Count() > 1)                     // The Key can be placed in at least one place more than than the Canoe
                {
                    validCanoeLocations = validCanoeIncentives;
                }
                else if (!flags.IncentivizeBridge && incentivePool.Count >= incentiveLocationPool.Count)
                {
                    validCanoeLocations = validCanoeLocations.Where(x => !incentiveLocationPool.Any(y => y.Address == x.Address)).ToList();
                }
            }

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

            BridgeLocations = validBridgeLocations
                              .Where(x => !forcedItemPlacements.Any(y => y.Address == x.Address))
                              .ToList();
            ShipLocations = validShipLocations
                            .Where(x => !forcedItemPlacements.Any(y => y.Address == x.Address))
                            .ToList();
            KeyLocations = validKeyLocations
                           .Where(x => !forcedItemPlacements.Any(y => y.Address == x.Address))
                           .ToList();
            CanoeLocations = validCanoeLocations
                             .Where(x => !forcedItemPlacements.Any(y => y.Address == x.Address))
                             .ToList();
            IncentiveLocations = incentiveLocationPool
                                 .Where(x => !forcedItemPlacements.Any(y => y.Address == x.Address))
                                 .ToList();
            AllValidItemLocations = itemLocationPool.ToList();
        }
        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();
        }
Esempio n. 3
0
        public IncentiveData(IIncentiveFlags flags,
                             Dictionary <MapLocation, List <MapChange> > mapLocationRequirements)
        {
            var forcedItemPlacements = ItemLocations.AllOtherItemLocations.ToList();

            if (!flags.NPCItems)
            {
                forcedItemPlacements.AddRange(ItemLocations.AllNonTreasureItemLocations);
            }
            if (!flags.Treasures)
            {
                forcedItemPlacements.AddRange(ItemLocations.AllTreasures);
            }
            var incentivePool = new List <Item>();

            if (flags.IncentivizeBridge)
            {
                incentivePool.Add(Item.Bridge);
            }
            if (flags.IncentivizeShip)
            {
                incentivePool.Add(Item.Ship);
            }
            if (flags.IncentivizeCanal)
            {
                incentivePool.Add(Item.Canal);
            }
            if (flags.IncentivizeLute)
            {
                incentivePool.Add(Item.Lute);
            }
            if (flags.IncentivizeCrown)
            {
                incentivePool.Add(Item.Crown);
            }
            if (flags.IncentivizeCrystal)
            {
                incentivePool.Add(Item.Crystal);
            }
            if (flags.IncentivizeHerb)
            {
                incentivePool.Add(Item.Herb);
            }
            if (flags.IncentivizeKey)
            {
                incentivePool.Add(Item.Key);
            }
            if (flags.IncentivizeTnt)
            {
                incentivePool.Add(Item.Tnt);
            }
            if (flags.IncentivizeAdamant)
            {
                incentivePool.Add(Item.Adamant);
            }
            if (flags.IncentivizeSlab)
            {
                incentivePool.Add(Item.Slab);
            }
            if (flags.IncentivizeRuby)
            {
                incentivePool.Add(Item.Ruby);
            }
            if (flags.IncentivizeRod)
            {
                incentivePool.Add(Item.Rod);
            }
            if (flags.IncentivizeFloater)
            {
                incentivePool.Add(Item.Floater);
            }
            if (flags.IncentivizeChime)
            {
                incentivePool.Add(Item.Chime);
            }
            if (flags.IncentivizeTail)
            {
                incentivePool.Add(Item.Tail);
            }
            if (flags.IncentivizeCube)
            {
                incentivePool.Add(Item.Cube);
            }
            if (flags.IncentivizeBottle)
            {
                incentivePool.Add(Item.Bottle);
            }
            if (flags.IncentivizeOxyale)
            {
                incentivePool.Add(Item.Oxyale);
            }
            if (flags.IncentivizeCanoe)
            {
                incentivePool.Add(Item.Canoe);
            }

            if (flags.IncentivizeXcalber)
            {
                incentivePool.Add(Item.Xcalber);
            }
            if (flags.IncentivizeMasamune)
            {
                incentivePool.Add(Item.Masamune);
            }
            if (flags.IncentivizeRibbon)
            {
                incentivePool.Add(Item.Ribbon);
            }
            if (flags.IncentivizeRibbon2)
            {
                incentivePool.Add(Item.Ribbon);
            }
            if (flags.IncentivizePowerGauntlet)
            {
                incentivePool.Add(Item.PowerGauntlets);
            }
            if (flags.IncentivizeWhiteShirt)
            {
                incentivePool.Add(Item.WhiteShirt);
            }
            if (flags.IncentivizeBlackShirt)
            {
                incentivePool.Add(Item.BlackShirt);
            }
            if (flags.IncentivizeOpal)
            {
                incentivePool.Add(Item.Opal);
            }
            if (flags.Incentivize65K)
            {
                incentivePool.Add(Item.Gold65000);
            }
            if (flags.IncentivizeBad)
            {
                incentivePool.Add(Item.Gold10);
            }

            var incentiveLocationPool = new List <IRewardSource>();

            if (flags.IncentivizeKingConeria)
            {
                incentiveLocationPool.Add(ItemLocations.KingConeria);
            }
            if (flags.IncentivizePrincess)
            {
                incentiveLocationPool.Add(ItemLocations.Princess);
            }
            if (flags.IncentivizeMatoya)
            {
                incentiveLocationPool.Add(ItemLocations.Matoya);
            }
            if (flags.IncentivizeBikke)
            {
                incentiveLocationPool.Add(ItemLocations.Bikke);
            }
            if (flags.IncentivizeElfPrince)
            {
                incentiveLocationPool.Add(ItemLocations.ElfPrince);
            }
            if (flags.IncentivizeAstos)
            {
                incentiveLocationPool.Add(ItemLocations.Astos);
            }
            if (flags.IncentivizeNerrick)
            {
                incentiveLocationPool.Add(ItemLocations.Nerrick);
            }
            if (flags.IncentivizeSmith)
            {
                incentiveLocationPool.Add(ItemLocations.Smith);
            }
            if (flags.IncentivizeSarda)
            {
                incentiveLocationPool.Add(ItemLocations.Sarda);
            }
            if (flags.IncentivizeCanoeSage)
            {
                incentiveLocationPool.Add(ItemLocations.CanoeSage);
            }
            if (flags.IncentivizeCubeBot)
            {
                incentiveLocationPool.Add(ItemLocations.CubeBot);
            }
            if (flags.IncentivizeFairy)
            {
                incentiveLocationPool.Add(ItemLocations.Fairy);
            }
            if (flags.IncentivizeLefein)
            {
                incentiveLocationPool.Add(ItemLocations.Lefein);
            }
            if (flags.IncentivizeVolcano)
            {
                incentiveLocationPool.Add(ItemLocations.VolcanoMajor);
            }
            if (flags.IncentivizeEarth)
            {
                incentiveLocationPool.Add(ItemLocations.EarthCaveMajor);
            }
            if (flags.IncentivizeMarsh)
            {
                incentiveLocationPool.Add(ItemLocations.MarshCaveMajor);
            }
            if (flags.IncentivizeSeaShrine)
            {
                incentiveLocationPool.Add(ItemLocations.SeaShrineLocked);
            }
            if (flags.IncentivizeConeria)
            {
                incentiveLocationPool.Add(ItemLocations.ConeriaMajor);
            }
            if (flags.IncentivizeIceCave)
            {
                incentiveLocationPool.Add(ItemLocations.IceCaveMajor);
            }
            if (flags.IncentivizeOrdeals)
            {
                incentiveLocationPool.Add(ItemLocations.OrdealsMajor);
            }
            var itemLocationPool =
                ItemLocations.AllTreasures.Concat(ItemLocations.AllNPCItemLocations)
                .Where(x => !x.IsUnused && !forcedItemPlacements.Any(y => y.Address == x.Address))
                .ToList();

            if (flags.EarlyOrdeals)
            {
                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 (flags.EarlyCanoe)
            {
                itemLocationPool =
                    itemLocationPool
                    .Select(x => x.Address == ItemLocations.CanoeSage.Address
                                                                        ? new MapObject(ObjectId.CanoeSage, MapLocation.CresentLake, x.Item)
                                                                        : x).ToList();
                incentiveLocationPool =
                    incentiveLocationPool
                    .Select(x => x.Address == ItemLocations.CanoeSage.Address
                                                                        ? new MapObject(ObjectId.CanoeSage, MapLocation.CresentLake, x.Item)
                                                                        : x).ToList();
            }
            if (flags.EarlyRod)
            {
                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();
            }

            var allMapLocations = Enum.GetValues(typeof(MapLocation))
                                  .Cast <MapLocation>().ToList();
            var startingMapLocations = allMapLocations.Where(x => mapLocationRequirements[x].Any(y => y == MapChange.None));
            var bridgeLocations      =
                ItemLocations.AllQuestItemLocations
                .Where(x => x.AccessRequirement == AccessRequirement.None &&
                       startingMapLocations.Contains(x.MapLocation)).ToList();

            if (incentivePool.Remove(Item.Bridge))
            {
                foreach (var incentiveBridgeLocation in incentiveLocationPool.Where(x => bridgeLocations.Any(y => y.Address == x.Address)).ToList())
                {
                    bridgeLocations.Add(incentiveBridgeLocation);
                    bridgeLocations.Add(incentiveBridgeLocation);
                    bridgeLocations.Add(incentiveBridgeLocation);
                }
            }

            var validShipMapLocations =
                allMapLocations.Where(x => mapLocationRequirements[x].Any(y => MapChange.Bridge.HasFlag(y)));
            var shipLocations =
                ItemLocations.AllQuestItemLocations
                .Where(x => AccessRequirement.Crystal.HasFlag(x.AccessRequirement) &&
                       validShipMapLocations.Contains(x.MapLocation)).ToList();

            if (incentivePool.Remove(Item.Ship))
            {
                foreach (var incentiveShipLocation in incentiveLocationPool.Where(x => shipLocations.Any(y => y.Address == x.Address)).ToList())
                {
                    shipLocations.Add(incentiveShipLocation);
                    shipLocations.Add(incentiveShipLocation);
                    shipLocations.Add(incentiveShipLocation);
                    shipLocations.Add(incentiveShipLocation);
                }
            }


            foreach (var item in forcedItemPlacements.Select(x => x.Item))
            {
                incentivePool.Remove(item);
            }
            ForcedItemPlacements = forcedItemPlacements.ToList();
            IncentiveItems       = incentivePool.ToList();
            BridgeLocations      = bridgeLocations
                                   .Where(x => !forcedItemPlacements.Any(y => y.Address == x.Address))
                                   .ToList();
            ShipLocations = shipLocations
                            .Where(x => !forcedItemPlacements.Any(y => y.Address == x.Address))
                            .ToList();
            IncentiveLocations = incentiveLocationPool
                                 .Where(x => !forcedItemPlacements.Any(y => y.Address == x.Address))
                                 .ToList();
            AllValidItemLocations = itemLocationPool.ToList();
        }
        private List <IRewardSource> SelectIncentivizedChests(IIncentiveFlags flags, MT19337 rng)
        {
            List <IRewardSource> incentiveLocationPool = new();

            if (flags.IncentivizeVolcano ?? false)
            {
                if (flags.VolcanoIncentivePlacementType == IncentivePlacementType.RandomAtLocation)
                {
                    incentiveLocationPool.Add(ItemLocations.Volcano.ToList().SpliceRandom(rng));
                }
                else
                {
                    incentiveLocationPool.Add(ItemLocations.VolcanoMajor);
                }
            }
            if (flags.IncentivizeEarth ?? false)
            {
                if (flags.EarthIncentivePlacementType == IncentivePlacementTypeGated.RandomAtLocation)
                {
                    incentiveLocationPool.Add(ItemLocations.EarthCave.ToList().SpliceRandom(rng));
                }
                else if (flags.EarthIncentivePlacementType == IncentivePlacementTypeGated.RandomBehindGating)
                {
                    incentiveLocationPool.Add(ItemLocations.EarthCaveFloor4.ToList().SpliceRandom(rng));
                }
                else if (flags.EarthIncentivePlacementType == IncentivePlacementTypeGated.RandomNoGating)
                {
                    incentiveLocationPool.Add(ItemLocations.EarthCavePreRod.ToList().SpliceRandom(rng));
                }
                else
                {
                    incentiveLocationPool.Add(ItemLocations.EarthCaveMajor);
                }
            }
            if (flags.IncentivizeMarsh ?? false)
            {
                if (flags.MarshIncentivePlacementType == IncentivePlacementType.RandomAtLocation)
                {
                    incentiveLocationPool.Add(ItemLocations.MarshCaveUnlocked.ToList().SpliceRandom(rng));
                }
                else
                {
                    incentiveLocationPool.Add(ItemLocations.MarshCaveMajor);
                }
            }
            if (flags.IncentivizeMarshKeyLocked ?? false)
            {
                if (flags.MarshLockedIncentivePlacementType == IncentivePlacementType.RandomAtLocation)
                {
                    incentiveLocationPool.Add(ItemLocations.MarshCaveLocked.ToList().SpliceRandom(rng));
                }
                else
                {
                    incentiveLocationPool.Add(ItemLocations.MarshCave13);
                }
            }
            if (flags.IncentivizeSkyPalace ?? false)
            {
                if (flags.SkyPalaceIncentivePlacementType == IncentivePlacementTypeGated.RandomAtLocation)
                {
                    incentiveLocationPool.Add(ItemLocations.SkyPalace.Concat(ItemLocations.MirageTower).ToList().SpliceRandom(rng));
                }
                else if (flags.SkyPalaceIncentivePlacementType == IncentivePlacementTypeGated.RandomBehindGating)
                {
                    incentiveLocationPool.Add(ItemLocations.SkyPalace.ToList().SpliceRandom(rng));
                }
                else if (flags.SkyPalaceIncentivePlacementType == IncentivePlacementTypeGated.RandomNoGating)
                {
                    incentiveLocationPool.Add(ItemLocations.MirageTower.ToList().SpliceRandom(rng));
                }
                else
                {
                    incentiveLocationPool.Add(ItemLocations.SkyPalaceMajor);
                }
            }
            if (flags.IncentivizeSeaShrine ?? false)
            {
                if (flags.SeaShrineIncentivePlacementType == IncentivePlacementTypeGated.RandomAtLocation)
                {
                    incentiveLocationPool.Add(ItemLocations.SeaShrine.ToList().SpliceRandom(rng));
                }
                else if (flags.SeaShrineIncentivePlacementType == IncentivePlacementTypeGated.RandomBehindGating)
                {
                    if ((bool)flags.MermaidPrison)
                    {
                        incentiveLocationPool.Add(ItemLocations.SeaShrineMermaids.Append(ItemLocations.SeaShrineLocked).ToList().SpliceRandom(rng));
                    }
                    else
                    {
                        incentiveLocationPool.Add(ItemLocations.SeaShrineLocked);
                    }
                }
                else if (flags.SeaShrineIncentivePlacementType == IncentivePlacementTypeGated.RandomNoGating)
                {
                    incentiveLocationPool.Add(ItemLocations.SeaShrineUnlocked.ToList().SpliceRandom(rng));
                }
                else
                {
                    incentiveLocationPool.Add(ItemLocations.SeaShrineMajor);
                }
            }
            if (flags.IncentivizeConeria ?? false)
            {
                if (flags.CorneriaIncentivePlacementType == IncentivePlacementType.RandomAtLocation)
                {
                    incentiveLocationPool.Add(ItemLocations.Coneria.ToList().SpliceRandom(rng));
                }
                else
                {
                    incentiveLocationPool.Add(ItemLocations.ConeriaMajor);
                }
            }
            if (flags.IncentivizeIceCave ?? false)
            {
                if (flags.IceCaveIncentivePlacementType == IncentivePlacementType.RandomAtLocation)
                {
                    incentiveLocationPool.Add(ItemLocations.IceCave.ToList().SpliceRandom(rng));
                }
                else
                {
                    incentiveLocationPool.Add(ItemLocations.IceCaveMajor);
                }
            }

            if (flags.IncentivizeOrdeals ?? false)
            {
                if (flags.OrdealsIncentivePlacementType == IncentivePlacementType.RandomAtLocation)
                {
                    incentiveLocationPool.Add(ItemLocations.Ordeals.ToList().SpliceRandom(rng));
                }
                else
                {
                    incentiveLocationPool.Add(ItemLocations.OrdealsMajor);
                }
            }
            if (flags.IncentivizeTitansTrove ?? false)
            {
                if (flags.TitansIncentivePlacementType == IncentivePlacementType.RandomAtLocation)
                {
                    incentiveLocationPool.Add(ItemLocations.TitansTunnel.ToList().SpliceRandom(rng));
                }
                else
                {
                    incentiveLocationPool.Add(ItemLocations.TitansTunnel1);
                }
            }
            if (flags.IncentivizeCardia ?? false)
            {
                if (flags.CardiaIncentivePlacementType == IncentivePlacementType.RandomAtLocation)
                {
                    incentiveLocationPool.Add(ItemLocations.Cardia.ToList().SpliceRandom(rng));
                }
                else
                {
                    incentiveLocationPool.Add(ItemLocations.Cardia4);
                }
            }

            return(incentiveLocationPool);
        }