コード例 #1
0
        public ItemGenerator(List <Item> seedPool, WorldWealthMode wealth)
        {
            // Make a copy
            var treasurePool = seedPool.ToList();

            // Make sure we copy all the input lists so we don't modify anything static.
            List <List <Item> > tiers = new List <List <Item> >
            {
                ItemLists.UberTier.Where(item => treasurePool.Remove(item)).ToList(),
                ItemLists.LegendaryWeaponTier.Where(item => treasurePool.Remove(item)).ToList(),
                ItemLists.LegendaryArmorTier.Where(item => treasurePool.Remove(item)).ToList(),
                ItemLists.RareWeaponTier.Where(item => treasurePool.Remove(item)).ToList(),
                ItemLists.RareArmorTier.Where(item => treasurePool.Remove(item)).ToList(),
                ItemLists.CommonWeaponTier.Where(item => treasurePool.Remove(item)).ToList(),
                ItemLists.CommonArmorTier.Where(item => treasurePool.Remove(item)).ToList(),
                ItemLists.AllConsumables.Where(item => treasurePool.Remove(item)).ToList(),
                treasurePool.Where(x => x >= Item.Gold10 && x <= Item.Gold65000).ToList(),
            };

            List <int> ratios = Ratios[(int)wealth];

            System.Diagnostics.Debug.Assert(tiers.Count == ratios.Count);
            System.Diagnostics.Debug.Assert(Enum.GetValues(typeof(WorldWealthMode)).Length == Ratios.Length);

            // Now populate the comined pool with a weighted average of all those above lists.
            _pool = new List <List <Item> >();
            for (int i = 0; i < ratios.Count(); ++i)
            {
                for (int j = 0; j < ratios[i]; ++j)
                {
                    if (tiers[i].Any())
                    {
                        _pool.Add(tiers[i]);
                    }
                }
            }
        }
コード例 #2
0
        public ItemShopSlot ShuffleShops(MT19337 rng, bool earlyAilments, bool randomizeWeaponsAndArmor, IEnumerable <Item> excludeItemsFromRandomShops, WorldWealthMode wealth, int coneriaEntranceShopIndex)
        {
            var pointers = Get(ShopPointerOffset, ShopPointerCount * ShopPointerSize).ToUShorts();

            RepackShops(pointers);

            ShuffleShopType(ShopType.Weapon, pointers, rng, randomizeWeaponsAndArmor, excludeItemsFromRandomShops, wealth);
            ShuffleShopType(ShopType.Armor, pointers, rng, randomizeWeaponsAndArmor, excludeItemsFromRandomShops, wealth);
            ItemShopSlot result = null;

            do
            {
                result = ShuffleShopType(ShopType.Item, pointers, rng);
            } while (earlyAilments && !AilmentsCovered(pointers, coneriaEntranceShopIndex));
            if (result == null)
            {
                throw new InvalidOperationException("Shop Location for Bottle was not set");
            }

            Put(ShopPointerOffset, Blob.FromUShorts(pointers));
            return(result);
        }
コード例 #3
0
        private ItemShopSlot ShuffleShopType(ShopType shopType, ushort[] pointers, MT19337 rng, bool randomize = false, IEnumerable <Item> excludeItemsFromRandomShops = null, WorldWealthMode wealth = WorldWealthMode.Normal)
        {
            var shops = GetShops(shopType, pointers);

            bool shopsBlocked;

            List <byte>[] newShops;
            do
            {
                shopsBlocked = false;
                newShops     = new List <byte> [ShopSectionSize];

                var allEntries = shops.SelectMany(list => list).ToList();
                allEntries.Shuffle(rng);

                int entry = 0;
                for (int i = 0; i < ShopSectionSize; i++)
                {
                    newShops[i] = new List <byte>();
                    if (pointers[(int)shopType + i] != ShopNullPointer)
                    {
                        newShops[i].Add(allEntries[entry++]);
                    }
                }

                while (entry < allEntries.Count)
                {
                    var eligibleShops = new List <int>();
                    for (int i = 0; i < newShops.Length; i++)
                    {
                        if (newShops[i].Count > 0 && newShops[i].Count < 5 && !newShops[i].Contains(allEntries[entry]))
                        {
                            eligibleShops.Add(i);
                        }
                    }

                    // We might be unable to place an item in any shop because they're all full, or they already have that item.  Start over.
                    if (eligibleShops.Count == 0)
                    {
                        shopsBlocked = true;
                        break;
                    }

                    int shopIndex = eligibleShops[rng.Between(0, eligibleShops.Count - 1)];
                    newShops[shopIndex].Add(allEntries[entry++]);
                }
            } while (shopsBlocked);

            if (randomize)
            {
                if (shopType == ShopType.Weapon || shopType == ShopType.Armor)
                {
                    // Shuffle up a byte array of random weapons or armor and assign them in place of the existing items.
                    var baseIndex = shopType == ShopType.Armor ? Item.Cloth : Item.WoodenNunchucks;
                    var indeces   = Enumerable.Range((int)baseIndex, 40).Select(i => (Item)i).ToList();
                    foreach (var exclusion in excludeItemsFromRandomShops ?? new List <Item>())
                    {
                        indeces.Remove(exclusion);
                    }

                    ItemGenerator generator = new ItemGenerator(indeces, wealth);
                    for (int i = 0; i < newShops.Length; i++)
                    {
                        newShops[i] = newShops[i].Select(x => (byte)generator.SpliceItem(rng)).ToList();
                    }
                }
            }
            // Zero-terminate the new shops.
            foreach (var newShop in newShops)
            {
                newShop.Add(0);
            }

            ItemShopSlot result  = null;
            var          pointer = pointers[(int)shopType];

            for (int i = 0; i < ShopSectionSize; i++)
            {
                if (newShops[i].Count > 1)
                {
                    var bottle =
                        newShops[i]
                        .Select((item, index) => new { item, index })
                        .FirstOrDefault(x => ((Item)x.item) == Item.Bottle);
                    if (bottle != null)
                    {
                        var location = ShopMapLocationsByIndex[i];
                        result = new ItemShopSlot(ShopPointerBase + pointer + bottle.index,
                                                  $"{Enum.GetName(typeof(MapLocation), location)}Shop{bottle.index + 1}",
                                                  location,
                                                  Item.Bottle);
                    }
                    Put(ShopPointerBase + pointer, newShops[i].ToArray());

                    pointers[(int)shopType + i] = pointer;
                    pointer += (ushort)newShops[i].Count;
                }
            }
            return(result);
        }
コード例 #4
0
        public ItemGenerator(List <Item> seedPool, List <int> unusedGoldItems, List <Item> removedItems, WorldWealthMode wealth)
        {
            // Make a copy
            var treasurePool = seedPool.ToList();

            // Make sure we copy all the input lists so we don't modify anything static.
            List <List <Item> > tiers = new List <List <Item> >
            {
                ItemLists.UberTier.Where(x => !removedItems.Contains(x)).ToList(),
                ItemLists.LegendaryWeaponTier.Where(x => !removedItems.Contains(x)).ToList(),
                ItemLists.LegendaryArmorTier.ToList(),
                ItemLists.RareWeaponTier.ToList(),
                ItemLists.RareArmorTier.ToList(),
                ItemLists.CommonWeaponTier.ToList(),
                ItemLists.CommonArmorTier.ToList(),
                ItemLists.AllConsumables.ToList(),
                ItemLists.AllGoldTreasure.Where(x => !unusedGoldItems.Contains((int)x)).ToList(),
            };

            List <int> ratios = RelativeRatios[(int)wealth].ToList();

            System.Diagnostics.Debug.Assert(tiers.Count == ratios.Count);

            ratios[0] += treasurePool.Where(x => ItemLists.UberTier.Contains(x)).Count();
            ratios[1] += treasurePool.Where(x => ItemLists.LegendaryWeaponTier.Contains(x)).Count();
            ratios[2] += treasurePool.Where(x => ItemLists.LegendaryArmorTier.Contains(x)).Count();
            ratios[3] += treasurePool.Where(x => ItemLists.RareWeaponTier.Contains(x)).Count();
            ratios[4] += treasurePool.Where(x => ItemLists.RareArmorTier.Contains(x)).Count();
            ratios[5] += treasurePool.Where(x => ItemLists.CommonWeaponTier.Contains(x)).Count();
            ratios[6] += treasurePool.Where(x => ItemLists.CommonArmorTier.Contains(x)).Count();
            ratios[7] += treasurePool.Where(x => ItemLists.AllConsumables.Contains(x)).Count();
            ratios[8] += treasurePool.Where(x => ItemLists.AllGoldTreasure.Contains(x)).Count();

            if (!tiers[0].Any())
            {
                ratios[1] += ratios[0];
                ratios[0]  = 0;
            }

            for (int i = 0; i < ratios.Count - 1; i++)
            {
                if (ratios[i] < 0)
                {
                    ratios[8] += ratios[i];
                    ratios[i]  = 0;
                }
            }

            // Now populate the combined pool with a weighted average of all those above lists.
            _pool = new List <List <Item> >();
            for (int i = 0; i < ratios.Count(); ++i)
            {
                for (int j = 0; j < ratios[i]; ++j)
                {
                    if (tiers[i].Any())
                    {
                        _pool.Add(tiers[i]);
                    }
                }
            }

            System.Diagnostics.Debug.Assert(treasurePool.Count == _pool.Count);
        }