Esempio n. 1
0
        public static double ExtConsumablePriceFix(Item item, double value, IScaleFlags flags)
        {
            if (flags.ExtConsumableSet == ExtConsumableSet.SetA)
            {
                if (item == Item.WoodenNunchucks)
                {
                    return(49152.0);
                }
                if (item == Item.SmallKnife)
                {
                    return(262144.0);
                }
                if (item == Item.WoodenRod)
                {
                    return(16384.0);
                }
                if (item == Item.Rapier)
                {
                    return(12288.0);
                }
            }
            else if (flags.ExtConsumableSet == ExtConsumableSet.SetB)
            {
                if (item == Item.WoodenNunchucks)
                {
                    return(49152.0);
                }
                if (item == Item.SmallKnife)
                {
                    return(32768.0);
                }
                if (item == Item.WoodenRod)
                {
                    return(16384.0);
                }
                if (item == Item.Rapier)
                {
                    return(16384.0);
                }
            }
            else if (flags.ExtConsumableSet == ExtConsumableSet.SetC)
            {
                if (item == Item.WoodenNunchucks)
                {
                    return(49152.0);
                }
                if (item == Item.SmallKnife)
                {
                    return(32768.0);
                }
                if (item == Item.WoodenRod)
                {
                    return(8192.0);
                }
                if (item == Item.Rapier)
                {
                    return(12288.0);
                }
            }

            return(value);
        }
Esempio n. 2
0
        // Scale is the geometric scale factor used with RNG.  Multiplier is where we make everything cheaper
        // instead of enemies giving more gold, so we don't overflow.
        public void ScalePrices(IScaleFlags flags, string[] text, MT19337 rng, bool increaseOnly, ItemShopSlot shopItemLocation)
        {
            var scale      = flags.PriceScaleFactor;
            var multiplier = flags.ExpMultiplier;
            var prices     = Get(PriceOffset, PriceSize * PriceCount).ToUShorts();

            for (int i = 0; i < prices.Length; i++)
            {
                var newPrice = Scale(prices[i] / multiplier, scale, 1, rng, increaseOnly);
                prices[i] = (ushort)(flags.WrapPriceOverflow ? ((newPrice - 1) % 0xFFFF) + 1 : Min(newPrice, 0xFFFF));
            }
            var questItemPrice = prices[(int)Item.Bottle];

            // If we don't do this before checking for the item shop location factor, Ribbons and Shirts will end up being really cheap
            // This realistically doesn't matter without Shop Wares shuffle on because nobody wants to sell Ribbons/Shirts, but if it is...
            prices[(int)Item.WhiteShirt] = (ushort)(questItemPrice / 2);
            prices[(int)Item.BlackShirt] = (ushort)(questItemPrice / 2);
            prices[(int)Item.Ribbon]     = questItemPrice;
            var itemShopFactor = new Dictionary <MapLocation, int>()
            {
                { MapLocation.Coneria, 8 },
                { MapLocation.Pravoka, 2 }
            };

            if (itemShopFactor.TryGetValue(shopItemLocation.MapLocation, out int divisor))
            {
                questItemPrice = (ushort)(prices[(int)Item.Bottle] / divisor);
            }
            for (var i = 0; i < (int)Item.Tent; i++)
            {
                prices[i] = questItemPrice;
            }
            Put(PriceOffset, Blob.FromUShorts(prices));

            for (int i = GoldItemOffset; i < GoldItemOffset + GoldItemCount; i++)
            {
                text[i] = prices[i].ToString() + " G";
            }

            var pointers = Get(ShopPointerOffset, ShopPointerCount * ShopPointerSize).ToUShorts();

            RepackShops(pointers);

            for (int i = (int)ShopType.Clinic; i < (int)ShopType.Inn + ShopSectionSize; i++)
            {
                if (pointers[i] != ShopNullPointer)
                {
                    var priceBytes = Get(ShopPointerBase + pointers[i], 2);
                    var priceValue = BitConverter.ToUInt16(priceBytes, 0);

                    priceValue = (ushort)Scale(priceValue / multiplier, scale, 1, rng, increaseOnly);
                    priceBytes = BitConverter.GetBytes(priceValue);
                    Put(ShopPointerBase + pointers[i], priceBytes);
                }
            }
            if (flags.StartingGold)
            {
                var startingGold = BitConverter.ToUInt16(Get(StartingGoldOffset, 2), 0);

                startingGold = (ushort)Min(Scale(startingGold / multiplier, scale, 1, rng, increaseOnly), 0xFFFF);

                Put(StartingGoldOffset, BitConverter.GetBytes(startingGold));
            }
        }
Esempio n. 3
0
        // Scale is the geometric scale factor used with RNG.  Multiplier is where we make everything cheaper
        // instead of enemies giving more gold, so we don't overflow.
        public void ScalePrices(IScaleFlags flags, MT19337 rng, bool increaseOnly, ItemShopSlot shopItemLocation, bool FreeClinic = false)
        {
            IEnumerable <Item> tmpExcludedItems = Array.Empty <Item>();

            if (flags.ExcludeGoldFromScaling ?? false)
            {
                tmpExcludedItems = tmpExcludedItems.Concat(ItemLists.AllGoldTreasure);
            }
            if ((flags.ExcludeGoldFromScaling ?? false) && flags.CheapVendorItem)
            {
                tmpExcludedItems = tmpExcludedItems.Concat(ItemLists.AllQuestItems);
            }

            HashSet <Item> excludedItems = new HashSet <Item>(tmpExcludedItems);
            HashSet <Item> questItems    = new HashSet <Item>(ItemLists.AllQuestItems);

            int rawScaleLow  = increaseOnly ? 100 : flags.PriceScaleFactorLow;
            int rawScaleHigh = increaseOnly ? Math.Max(100, flags.PriceScaleFactorHigh) : flags.PriceScaleFactorHigh;

            double scaleLow  = (double)rawScaleLow / 100.0;
            double scaleHigh = (double)rawScaleHigh / 100.0;

            var multiplier = flags.ExcludeGoldFromScaling ?? false ? 1.0 : flags.ExpMultiplier;
            var prices     = Get(PriceOffset, PriceSize * PriceCount).ToUShorts();

            for (int i = 0; i < prices.Length; i++)
            {
                if (excludedItems.Contains((Item)i))
                {
                    var price = (int)prices[i];

                    if (flags.CheapVendorItem && questItems.Contains((Item)i))
                    {
                        price = 20000;
                    }

                    var newPrice = price + rng.Between(-price / 10, price / 10);
                    prices[i] = (ushort)Math.Min(Math.Max(newPrice, 1), 65535);
                }
                else
                {
                    var price    = ExtConsumables.ExtConsumablePriceFix((Item)i, prices[i], flags);
                    var newPrice = RangeScaleWithZero(price / multiplier, scaleLow, scaleHigh, 1e-5 * multiplier, 1, rng);
                    prices[i] = (ushort)Min(newPrice, 0xFFFF);
                }
            }
            var questItemPrice = prices[(int)Item.Bottle];

            // If we don't do this before checking for the item shop location factor, Ribbons and Shirts will end up being really cheap
            // This realistically doesn't matter without Shop Wares shuffle on because nobody wants to sell Ribbons/Shirts, but if it is...
            prices[(int)Item.WhiteShirt] = (ushort)(questItemPrice / 2);
            prices[(int)Item.BlackShirt] = (ushort)(questItemPrice / 2);
            prices[(int)Item.Ribbon]     = questItemPrice;
            var itemShopFactor = new Dictionary <MapLocation, int>()
            {
                { MapLocation.Coneria, 8 },
                { MapLocation.Pravoka, 2 }
            };

            if (itemShopFactor.TryGetValue(shopItemLocation.MapLocation, out int divisor))
            {
                questItemPrice = (ushort)(prices[(int)Item.Bottle] / divisor);
            }
            for (var i = 0; i < (int)Item.Tent; i++)
            {
                prices[i] = questItemPrice;
            }
            Put(PriceOffset, Blob.FromUShorts(prices));

            for (int i = GoldItemOffset; i < GoldItemOffset + GoldItemCount; i++)
            {
                ItemsText[i] = prices[i].ToString() + " G";
            }

            var pointers = Get(ShopPointerOffset, ShopPointerCount * ShopPointerSize).ToUShorts();

            RepackShops(pointers);

            for (int i = (int)ShopType.Clinic; i < (int)ShopType.Inn + ShopSectionSize; i++)
            {
                if (pointers[i] != ShopNullPointer)
                {
                    var priceBytes = Get(ShopPointerBase + pointers[i], 2);
                    var priceValue = BitConverter.ToUInt16(priceBytes, 0);

                    priceValue = (ushort)RangeScale(priceValue / multiplier, scaleLow, scaleHigh, 1, rng);
                    if (FreeClinic && i < (int)ShopType.Clinic + ShopSectionSize)
                    {
                        priceValue = 0;
                    }
                    priceBytes = BitConverter.GetBytes(priceValue);
                    Put(ShopPointerBase + pointers[i], priceBytes);
                }
            }

            List <(StartingGold, ushort)> startingGold = new()
            {
                (StartingGold.None, 0),
                (StartingGold.Gp100, 100),
                (StartingGold.Gp200, 200),
                (StartingGold.Gp400, 400),
                (StartingGold.Gp800, 800),
                (StartingGold.Gp2500, 2500),
                (StartingGold.Gp9999, 9999),
                (StartingGold.Gp65535, 65535),
                (StartingGold.RandomLow, (ushort)rng.Between(0, 800)),
                (StartingGold.RandomHigh, (ushort)rng.Between(0, 65535)),
            };

            Put(StartingGoldOffset, BitConverter.GetBytes(startingGold[(int)flags.StartingGold].Item2));
        }