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(); }
public RewardSourcePicker(double _reduction, double _nonchest, ISanityChecker _checker) { reduction = _reduction; nonchest = _nonchest; checker = _checker; }
public Init(IAuth auth, INoticeBoard notices, ISanityChecker check) { this._auth = auth; this._notices = notices; this._check = check; }
public InitSanityCheckFilter(ISanityChecker checker, INoticeBoard nb) { this._checker = checker; this._nb = nb; }