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