Example #1
0
        /// <summary>
        /// Gets the level you learn this skill at
        /// </summary>
        /// <returns>
        /// Any value in the given range. Excludes 0, 5, and 10.
        /// Returns 9 if it's 10; returns 1 if it's 0; returns 4 or 6 if it's 5
        /// </returns>
        public int GetLevelLearnedAt()
        {
            Range levelRange     = new Range(OverrideBaseLevelLearnedAt - 3, OverrideBaseLevelLearnedAt + 3);
            int   generatedLevel = levelRange.GetRandomValue();

            if (generatedLevel > 8)
            {
                return(9);
            }
            if (generatedLevel < 1)
            {
                return(1);
            }
            if (generatedLevel == 5)
            {
                generatedLevel = Globals.RNGGetNextBoolean() ? 4 : 6;
            }

            if (!Globals.Config.CraftingRecipies.Randomize || !Globals.Config.CraftingRecipies.RandomizeLevels)
            {
                return(BaseLevelLearnedAt);
            }

            return(generatedLevel);
        }
        /// <summary>
        /// Get a random seed price - the weighted values are as follows:
        /// 10 - 30: 40%
        /// 30 - 60: 30%
        /// 60 - 90: 15%
        /// 90 - 120: 10%
        /// 120 - 150: 5%
        /// </summary>
        /// <returns>
        /// The generated number - this will be an even number because the seed price that
        /// we need to report is actually the sell value, which is half of the price we will
        /// generate here
        /// </returns>
        private static int GetRandomSeedPrice()
        {
            int generatedValue = Range.GetRandomValue(1, 100);
            int baseValue      = 0;

            if (generatedValue < 41)
            {
                baseValue = Range.GetRandomValue(10, 30);
            }
            else if (generatedValue < 71)
            {
                baseValue = Range.GetRandomValue(31, 60);
            }
            else if (generatedValue < 86)
            {
                baseValue = Range.GetRandomValue(61, 90);
            }
            else if (generatedValue < 96)
            {
                baseValue = Range.GetRandomValue(91, 120);
            }
            else
            {
                baseValue = Range.GetRandomValue(121, 150);
            }

            return(baseValue / 2);            // We need to store the sell price, not the buy price
        }
Example #3
0
        /// <summary>
        /// Gets the level you learn this skill at
        /// </summary>
        /// <returns>
        /// Any value in the given range. Excludes 0, 5, and 10.
        /// Returns 9 if it's 10; returns 1 if it's 0; returns 4 or 6 if it's 5
        /// </returns>
        public int GetLevelLearnedAt()
        {
            if (!Globals.Config.RandomizeCraftingRecipeLevels_Needs_Above_Setting_On)
            {
                return(BaseLevelLearnedAt);
            }

            Range levelRange     = new Range(BaseLevelLearnedAt - 3, BaseLevelLearnedAt + 3);
            int   generatedLevel = levelRange.GetRandomValue();

            if (generatedLevel > 8)
            {
                return(9);
            }
            if (generatedLevel < 1)
            {
                return(1);
            }
            if (generatedLevel == 5)
            {
                return(Globals.RNGGetNextBoolean() ? 4 : 6);
            }

            return(generatedLevel);
        }
        /// <summary>
        /// Generates the reward for the bundle
        /// </summary>
        protected override void GenerateReward()
        {
            if (Globals.RNGGetNextBoolean(1))
            {
                Reward = new RequiredItem((int)ObjectIndexes.PrismaticShard);
            }

            else if (Globals.RNGGetNextBoolean(5))
            {
                List <Item> universalLoves = NPC.UniversalLoves.Where(x =>
                                                                      x.Id != (int)ObjectIndexes.PrismaticShard).ToList();

                Reward = Globals.RNGGetRandomValueFromList(RequiredItem.CreateList(universalLoves, 5, 10));
            }

            List <RequiredItem> potentialRewards = new List <RequiredItem>
            {
                new RequiredItem((int)ObjectIndexes.JunimoKartArcadeSystem),
                new RequiredItem((int)ObjectIndexes.PrairieKingArcadeSystem),
                new RequiredItem((int)ObjectIndexes.SodaMachine),
                new RequiredItem((int)ObjectIndexes.Beer, 43),
                new RequiredItem((int)ObjectIndexes.Salad, Range.GetRandomValue(5, 25)),
                new RequiredItem((int)ObjectIndexes.Bread, Range.GetRandomValue(5, 25)),
                new RequiredItem((int)ObjectIndexes.Spaghetti, Range.GetRandomValue(5, 25)),
                new RequiredItem((int)ObjectIndexes.Pizza, Range.GetRandomValue(5, 25)),
                new RequiredItem((int)ObjectIndexes.Coffee, Range.GetRandomValue(5, 25))
            };

            Reward = Globals.RNGGetRandomValueFromList(potentialRewards);
        }
        /// <summary>
        /// Randomizes monster stats/drops/etc.
        /// - Skips coin range randomization - not sure what it's for
        /// - Skips whether a monster is a glider, as flying monster spawns are hard-coded... don't want to
        ///   accidently spawn a non-flying monster somewhere it can't move
        /// </summary>
        /// <returns />
        public static Dictionary <string, string> Randomize()
        {
            Dictionary <string, string> replacements = new Dictionary <string, string>();

            List <Monster>                allMonsters      = MonsterData.GetAllMonsters();
            Dictionary <int, int>         monsterItemSwaps = GetMonsterDropReplacements(allMonsters);
            Dictionary <string, ItemDrop> extraItemDrops   = new Dictionary <string, ItemDrop>();

            foreach (Monster monster in allMonsters)
            {
                monster.HP     = Math.Max(Globals.RNGGetIntWithinPercentage(monster.HP, HPVariance), 1);
                monster.Damage = Math.Max(Globals.RNGGetIntWithinPercentage(monster.Damage, DamageVariance), 1);
                monster.RandomMovementDuration = Globals.RNGGetNextBoolean(35) ? 0 : Range.GetRandomValue(1, 3000);
                RandomizeMonsterDrops(monster, monsterItemSwaps, extraItemDrops);
                RandomizeResilience(monster);
                monster.Jitteriness = Range.GetRandomValue(0, 2) / 100d;
                RandomizeMoveTowardPlayerThreshold(monster);
                monster.Speed      = Range.GetRandomValue(1, 4);
                monster.MissChance = Range.GetRandomValue(0, 5) / 100d;
                monster.Experience = Math.Max(Globals.RNGGetIntWithinPercentage(monster.Experience, ExperienceVariance), 1);

                replacements.Add(monster.Name, monster.ToString());
            }

            WriteToSpoilerLog(allMonsters, monsterItemSwaps, extraItemDrops);

            return(replacements);
        }
        /// <summary>
        /// Randomizes boots - currently only changes defense and immunity
        /// </summary>
        /// <returns />
        public static Dictionary <int, string> Randomize()
        {
            Boots.Clear();
            WeaponAndArmorNameRandomizer nameRandomizer = new WeaponAndArmorNameRandomizer();

            Dictionary <int, string> bootReplacements = new Dictionary <int, string>();
            List <BootItem>          bootsToUse       = new List <BootItem>();

            foreach (BootItem originalBoot in BootData.AllBoots)
            {
                int statPool = Globals.RNGGetIntWithinPercentage(originalBoot.Defense + originalBoot.Immunity, 30);
                int defense  = Range.GetRandomValue(0, statPool);
                int immunity = statPool - defense;

                BootItem newBootItem = new BootItem(
                    originalBoot.Id,
                    nameRandomizer.GenerateRandomBootName(),
                    originalBoot.NotActuallyPrice,
                    defense,
                    immunity,
                    originalBoot.ColorSheetIndex
                    );

                bootsToUse.Add(newBootItem);
                Boots.Add(newBootItem.Id, newBootItem);
            }

            foreach (BootItem bootToAdd in bootsToUse)
            {
                bootReplacements.Add(bootToAdd.Id, bootToAdd.ToString());
            }

            WriteToSpoilerLog(bootsToUse);
            return(bootReplacements);
        }
        /// <summary>
        /// Gets a random Stardew Valley date - excludes the holidays and birthdays already in use
        /// </summary>
        /// <param name="birthdaysInUse">The birthdays in use - this function adds the date to it</param>
        /// <returns>The date added</returns>
        private static SDate AddRandomBirthdayToNPC(Dictionary <SDate, string> birthdaysInUse, string npcName)
        {
            if (npcName == "Wizard")
            {
                return(GetWizardBirthday(birthdaysInUse));
            }

            List <string> seasonStrings = new List <string> {
                "spring", "summer", "fall", "winter"
            };
            string season        = Globals.RNGGetRandomValueFromList(seasonStrings);
            bool   dateRetrieved = false;
            SDate  date          = null;

            do
            {
                date = new SDate(Range.GetRandomValue(1, 28), season, 1);
                if (!birthdaysInUse.ContainsKey(date))
                {
                    birthdaysInUse.Add(date, npcName);
                    dateRetrieved = true;
                }
            } while (!dateRetrieved);

            return(date);
        }
 /// <summary>
 /// Randomizes the weapon type
 /// - 1/4 chance of each type that isn't a slingshot
 /// </summary>
 /// <param name="weapon">The weapon to randomize</param>
 private static void RandomizeWeaponType(WeaponItem weapon)
 {
     weapon.Type = (WeaponType)Range.GetRandomValue(0, 3);
     if (weapon.Type == WeaponType.StabbingSword)
     {
         weapon.Type = WeaponType.SlashingSword;
     }
 }
        /// <summary>
        /// Gets the wizard's birthday - must be from the 15-17, as the game hard-codes the "Night Market" text
        /// to the billboard
        /// </summary>
        /// <param name="birthdaysInUse">The birthdays in use - this function adds the date to it</param>
        /// <returns />
        private static SDate GetWizardBirthday(Dictionary <SDate, string> birthdaysInUse)
        {
            int   day            = Range.GetRandomValue(15, 17);
            SDate wizardBirthday = new SDate(day, "winter", 1);

            birthdaysInUse.Remove(wizardBirthday);
            birthdaysInUse.Add(wizardBirthday, "Wizard");
            return(wizardBirthday);
        }
        /// <summary>
        /// Assigns a random defense value to the weapon
        /// - 95% chance of 0
        /// - else 1-5
        /// </summary>
        /// <param name="weapon">The weapon to add the defense value</param>
        private static void RandomizeWeaponDefense(WeaponItem weapon)
        {
            if (Globals.RNGGetNextBoolean(95))
            {
                weapon.AddedDefense = 0;
            }

            else
            {
                weapon.AddedDefense = Range.GetRandomValue(1, 5);
            }
        }
        /// <summary>
        /// Assigns a random precision value to the weapon
        /// - 80% chance of 0
        /// - else 1 - 10
        /// </summary>
        /// <param name="weapon">The weapon to assign the precision value</param>
        private static void RandomizeWeaponPrecision(WeaponItem weapon)
        {
            if (Globals.RNGGetNextBoolean(80))
            {
                weapon.AddedPrecision = 0;
            }

            else
            {
                weapon.AddedPrecision = Range.GetRandomValue(1, 10);
            }
        }
        /// <summary>
        /// Assigns a random AOE value to the weapon
        /// - 80% chance of 0
        /// - Else, value from 1 - 4
        /// </summary>
        /// <param name="weapon">The weapon to assign the AOE to</param>
        private static void RandomizeWeaponAOE(WeaponItem weapon)
        {
            if (Globals.RNGGetNextBoolean(80))
            {
                weapon.AddedAOE = 0;
            }

            else
            {
                weapon.AddedAOE = Range.GetRandomValue(1, 4);
            }
        }
        /// <summary>
        /// Assigns a random weapon knockback
        /// - 5% chance of 1.6 - 2.0
        /// - else 0.5 - 1.6
        /// </summary>
        /// <param name="weapon">The weapon to set the knockback for</param>
        private static void RandomizeWeaponKnockback(WeaponItem weapon)
        {
            if (Globals.RNGGetNextBoolean(5))
            {
                weapon.Knockback = Range.GetRandomValue(16, 20) / 10d;
            }

            else
            {
                weapon.Knockback = Range.GetRandomValue(5, 16) / 10d;
            }
        }
        /// <summary>
        /// Randomizes the threshold that the monster must hit in order to move toward the player
        /// - 5% chance of it being a large number
        /// </summary>
        /// <param name="monster">The monster to set the value of</param>
        private static void RandomizeMoveTowardPlayerThreshold(Monster monster)
        {
            if (Globals.RNGGetNextBoolean(5))
            {
                monster.MovesTowardPlayerThreshold = Range.GetRandomValue(8, 12);
            }

            else
            {
                monster.MovesTowardPlayerThreshold = Range.GetRandomValue(0, 4);
            }
        }
Example #15
0
        /// <summary>
        /// Generates the bundle for the given season
        /// </summary>
        /// <param name="season">The season</param>
        /// <param name="color">The color to use</param>
        private void GenerateSeasonBundle(Seasons season, BundleColors color)
        {
            string seasonString = Globals.GetTranslation($"seasons-{season.ToString().ToLower()}");

            seasonString = $"{seasonString[0].ToString().ToUpper()}{seasonString.Substring(1)}";

            Name = Globals.GetTranslation("bundle-fishtank-seasonal", new { season = seasonString });
            List <RequiredItem> potentialItems = RequiredItem.CreateList(FishItem.Get(season));

            RequiredItems        = Globals.RNGGetRandomValuesFromList(potentialItems, 8);
            MinimumRequiredItems = Math.Min(Range.GetRandomValue(6, 8), RequiredItems.Count);
            Color = color;
        }
Example #16
0
        /// <summary>
        /// Generates a random reward out of all of the items
        /// </summary>
        protected void GenerateRandomReward()
        {
            Item reward = Globals.RNGGetRandomValueFromList(ItemList.Items.Values.Where(x =>
                                                                                        x.Id != (int)ObjectIndexes.TransmuteAu && x.Id != (int)ObjectIndexes.TransmuteFe).ToList());
            int numberToGive = Range.GetRandomValue(1, 25);

            if (!reward.CanStack)
            {
                numberToGive = 1;
            }

            Reward = new RequiredItem(reward.Id, numberToGive);
        }
Example #17
0
        /// <summary>
        /// Gets what a price for an item might be just based on its difficulty to obtain
        /// </summary>
        /// <param name="multiplier">The multiplier for the price - will add or subtract this as a percentage</param>
        /// <returns>The computed price</returns>
        public int GetPriceForObtainingDifficulty(double multiplier)
        {
            int basePrice = 0;

            switch (DifficultyToObtain)
            {
            case ObtainingDifficulties.NoRequirements:
                basePrice = 1000;
                break;

            case ObtainingDifficulties.SmallTimeRequirements:
                basePrice = 5000;
                break;

            case ObtainingDifficulties.MediumTimeRequirements:
                basePrice = 7500;
                break;

            case ObtainingDifficulties.LargeTimeRequirements:
                basePrice = 10000;
                break;

            case ObtainingDifficulties.UncommonItem:
                basePrice = 2500;
                break;

            case ObtainingDifficulties.RareItem:
                basePrice = 20000;
                break;

            case ObtainingDifficulties.EndgameItem:
                basePrice = 20000;
                break;

            case ObtainingDifficulties.NonCraftingItem:
                basePrice = 5000;
                break;

            default:
                Globals.ConsoleError($"Tried to get a base price for an item with an unrecognized ObtainingDifficulty: {Name}");
                return(100);
            }

            int   smallerBasePrice = basePrice / 10;           // Guarantees that the price will be an even number
            Range range            = new Range(
                (int)(smallerBasePrice - (smallerBasePrice * multiplier)),
                (int)(smallerBasePrice * (multiplier + 1))
                );

            return(range.GetRandomValue() * 10);
        }
Example #18
0
        /// <summary>
        /// Randomizes boots - currently only changes defense and immunity
        /// </summary>
        /// <returns />
        public static Dictionary <int, string> Randomize()
        {
            Boots.Clear();
            WeaponAndArmorNameRandomizer nameRandomizer = new WeaponAndArmorNameRandomizer();
            List <string> descriptions = NameAndDescriptionRandomizer.GenerateBootDescriptions(BootData.AllBoots.Count);

            Dictionary <int, string> bootReplacements = new Dictionary <int, string>();
            List <BootItem>          bootsToUse       = new List <BootItem>();

            for (int i = 0; i < BootData.AllBoots.Count; i++)
            {
                BootItem originalBoot = BootData.AllBoots[i];
                int      statPool     = Globals.RNGGetIntWithinPercentage(originalBoot.Defense + originalBoot.Immunity, 30);
                int      defense      = Range.GetRandomValue(0, statPool);
                int      immunity     = statPool - defense;

                if ((defense + immunity) == 0)
                {
                    if (Globals.RNGGetNextBoolean())
                    {
                        defense = 1;
                    }

                    else
                    {
                        immunity = 1;
                    }
                }

                BootItem newBootItem = new BootItem(
                    originalBoot.Id,
                    nameRandomizer.GenerateRandomBootName(),
                    descriptions[i],
                    originalBoot.NotActuallyPrice,
                    defense,
                    immunity,
                    originalBoot.ColorSheetIndex
                    );

                bootsToUse.Add(newBootItem);
                Boots.Add(newBootItem.Id, newBootItem);
            }

            foreach (BootItem bootToAdd in bootsToUse)
            {
                bootReplacements.Add(bootToAdd.Id, bootToAdd.ToString());
            }

            WriteToSpoilerLog(bootsToUse);
            return(bootReplacements);
        }
        /// <summary>
        /// Generates the bundle for foraging items
        /// </summary>
        /// <param name="season">The season</param>
        /// <param name="color">The color of the bundle</param>
        private void GenerateForagingBundle(Seasons season, BundleColors color)
        {
            string seasonString = Globals.GetTranslation($"seasons-{season.ToString().ToLower()}");

            seasonString = $"{seasonString[0].ToString().ToUpper()}{seasonString.Substring(1)}";

            Name = Globals.GetTranslation($"bundle-crafting-foraging", new { season = seasonString });
            List <RequiredItem> potentialItems = RequiredItem.CreateList(ItemList.GetForagables(season));
            int numberOfChoices = Math.Min(potentialItems.Count, 8);

            RequiredItems        = Globals.RNGGetRandomValuesFromList(potentialItems, numberOfChoices);
            MinimumRequiredItems = Range.GetRandomValue(4, numberOfChoices);
            Color = color;
        }
Example #20
0
        /// <summary>
        /// Populates the bundle with the name, required items, minimum required, and color
        /// </summary>
        protected override void Populate()
        {
            int moneyAmount = 0;

            BundleType = Globals.RNGGetAndRemoveRandomValueFromList(RoomBundleTypes);
            int bundleNameFlavorID = 1;

            switch (BundleType)
            {
            case BundleTypes.Vault2500:
                bundleNameFlavorID = Range.GetRandomValue(1, 7);
                moneyAmount        = Range.GetRandomValue(500, 3500);
                break;

            case BundleTypes.Vault5000:
                bundleNameFlavorID = Range.GetRandomValue(1, 6);
                moneyAmount        = Range.GetRandomValue(4000, 7000);
                break;

            case BundleTypes.Vault10000:
                bundleNameFlavorID = Range.GetRandomValue(1, 6);
                moneyAmount        = Range.GetRandomValue(7500, 12500);
                break;

            case BundleTypes.Vault25000:
                bundleNameFlavorID = Range.GetRandomValue(1, 7);
                moneyAmount        = Range.GetRandomValue(20000, 30000);
                break;

            default:
                return;
            }

            RequiredItems = new List <RequiredItem> {
                new RequiredItem()
                {
                    MoneyAmount = moneyAmount
                }
            };

            string moneyString      = moneyAmount.ToString("N0", new CultureInfo(Globals.ModRef.Helper.Translation.Locale));
            string bundleNameFlavor = Globals.GetTranslation($"{BundleType.ToString()}-{bundleNameFlavorID}");

            Name            = $"{Globals.GetTranslation("vault-money-format", new { moneyString })}: {bundleNameFlavor}";
            ImageNameSuffix = $"-{bundleNameFlavorID}";

            Color = Globals.RNGGetRandomValueFromList(
                Enum.GetValues(typeof(BundleColors)).Cast <BundleColors>().ToList());
        }
        /// <summary>
        /// Gets a list of randomly generated growth stages
        /// </summary>
        /// <param name="numberOfStages"></param>
        /// <returns>A list of integers, totaling up to a max of 12</returns>
        private static List <int> GetRandomGrowthStages(int numberOfStages)
        {
            if (numberOfStages <= 0)
            {
                Globals.ConsoleError("Tried to pass an invalid number of growth stages when randomizing crops.");
                return(new List <int>());
            }

            int        maxValuePerStage = 12 / numberOfStages;
            List <int> growthStages     = new List <int>();

            for (int i = 0; i < numberOfStages; i++)
            {
                growthStages.Add(Range.GetRandomValue(1, maxValuePerStage));
            }

            return(growthStages);
        }
        /// <summary>
        /// Creates a bundle with random items
        /// </summary>
        protected void PopulateRandomBundle()
        {
            BundleType = Globals.RNGGetRandomValueFromList(_randomBundleTypes);
            List <RequiredItem> potentialItems = new List <RequiredItem>();

            switch (BundleType)
            {
            case BundleTypes.AllRandom:
                Name           = Globals.GetTranslation("bundle-random-all");
                potentialItems = RequiredItem.CreateList(ItemList.Items.Values.Where(x =>
                                                                                     x.DifficultyToObtain <ObtainingDifficulties.Impossible &&
                                                                                                           x.Id> -4)
                                                         .ToList());
                RequiredItems        = Globals.RNGGetRandomValuesFromList(potentialItems, 8);
                MinimumRequiredItems = 4;
                break;

            case BundleTypes.AllLetter:
                string letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
                string randomLetter;
                do
                {
                    randomLetter = letters[Range.GetRandomValue(0, letters.Length - 1)].ToString();
                    letters.Replace(randomLetter, "");
                    potentialItems = RequiredItem.CreateList(
                        ItemList.Items.Values.Where(x =>
                                                    (
                                                        (x.OverrideDisplayName == null && x.Name.StartsWith(randomLetter, StringComparison.InvariantCultureIgnoreCase)) ||
                                                        (x.OverrideDisplayName != null && x.OverrideDisplayName.StartsWith(randomLetter, StringComparison.InvariantCultureIgnoreCase))
                                                    ) &&
                                                    x.Id > -4
                                                    ).ToList()
                        );
                } while (potentialItems.Count < 4);
                Name                 = Globals.GetTranslation("bundle-random-letter", new { letter = randomLetter });
                ImageNameSuffix      = randomLetter;
                RequiredItems        = Globals.RNGGetRandomValuesFromList(potentialItems, 8);
                MinimumRequiredItems = 3;
                break;
            }

            Color = Globals.RNGGetRandomValueFromList(
                Enum.GetValues(typeof(BundleColors)).Cast <BundleColors>().ToList());
        }
        /// <summary>
        /// Gets a random item drop - starts at noreqs and has a 50% chance to continue down the rarity chain
        /// - No req = 1/2, 5-8% drop rate
        /// - Small time req = 1/4, 4-6% drop rate
        /// - Med time req = 1/8, 3-5% drop rate
        /// - Large time req = 1/16, 2-4% drop rate
        /// - Uncommon = 1/32, 1-2% drop rate
        /// - Rare = 1/64, 0.1-0.5% drop rate
        /// </summary>
        /// <returns>The random item drop</returns>
        private static ItemDrop GetRandomItemDrop()
        {
            double probability = 0;
            Item   item        = null;

            if (Globals.RNGGetNextBoolean())
            {
                item        = ItemList.GetRandomItemAtDifficulty(ObtainingDifficulties.NoRequirements);
                probability = Range.GetRandomValue(5, 8) / 100d;
            }

            else if (Globals.RNGGetNextBoolean())
            {
                item        = ItemList.GetRandomItemAtDifficulty(ObtainingDifficulties.SmallTimeRequirements);
                probability = Range.GetRandomValue(4, 6) / 100d;
            }

            else if (Globals.RNGGetNextBoolean())
            {
                item        = ItemList.GetRandomItemAtDifficulty(ObtainingDifficulties.MediumTimeRequirements);
                probability = Range.GetRandomValue(3, 5) / 100d;
            }

            else if (Globals.RNGGetNextBoolean())
            {
                item        = ItemList.GetRandomItemAtDifficulty(ObtainingDifficulties.LargeTimeRequirements);
                probability = Range.GetRandomValue(2, 4) / 100d;
            }

            else if (Globals.RNGGetNextBoolean())
            {
                item        = ItemList.GetRandomItemAtDifficulty(ObtainingDifficulties.UncommonItem);
                probability = Range.GetRandomValue(1, 2) / 100d;
            }

            else
            {
                item        = ItemList.GetRandomItemAtDifficulty(ObtainingDifficulties.RareItem);
                probability = Range.GetRandomValue(1, 5) / 1000d;
            }

            return(new ItemDrop(item.Id, probability));
        }
        /// <summary>
        /// Randomize the weapon crit stats
        /// - 1% chance of a 0.1% crit with a multiplier of 100
        /// - 4% chance of 8-12% crit with a multiplier of 3 - 3.1x
        /// - Else, 2-3% crit with a multiplier of 3 - 4x
        /// </summary>
        /// <param name="weapon">The weapon to randomize</param>
        private static void RandomizeWeaponCrits(WeaponItem weapon)
        {
            if (Globals.RNGGetNextBoolean(1))
            {
                weapon.CritChance     = 0.001;
                weapon.CritMultiplier = 100;
            }

            else if (Globals.RNGGetNextBoolean(4))
            {
                weapon.CritChance     = Range.GetRandomValue(8, 12) / 100d;
                weapon.CritMultiplier = Range.GetRandomValue(30, 31) / 10d;
            }

            else
            {
                weapon.CritChance     = Range.GetRandomValue(20, 30) / 1000d;
                weapon.CritMultiplier = Range.GetRandomValue(30, 40) / 10d;
            }
        }
Example #25
0
        /// <summary>
        /// Sets the diggable item info on the given data
        /// </summary>
        /// <param name="locationData">The location data</param>
        private static void SetExtraDiggableItemInfo(LocationData locationData)
        {
            ObtainingDifficulties difficulty = GetRandomItemDifficulty();
            double probability = 0;

            switch (difficulty)
            {
            case ObtainingDifficulties.NoRequirements:
                probability = (double)Range.GetRandomValue(30, 60) / 100;
                break;

            case ObtainingDifficulties.SmallTimeRequirements:
                probability = (double)Range.GetRandomValue(30, 40) / 100;
                break;

            case ObtainingDifficulties.MediumTimeRequirements:
                probability = (double)Range.GetRandomValue(20, 30) / 100;
                break;

            case ObtainingDifficulties.LargeTimeRequirements:
                probability = (double)Range.GetRandomValue(10, 20) / 100;
                break;

            case ObtainingDifficulties.UncommonItem:
                probability = (double)Range.GetRandomValue(5, 15) / 100;
                break;

            case ObtainingDifficulties.RareItem:
                probability = (double)Range.GetRandomValue(1, 5) / 100;
                break;

            default:
                Globals.ConsoleError($"Attempting to get a diggable item with invalid difficulty: {difficulty}");
                difficulty  = ObtainingDifficulties.NoRequirements;
                probability = (double)Range.GetRandomValue(30, 60) / 100;
                break;
            }

            locationData.ExtraDiggingItem       = ItemList.GetRandomItemAtDifficulty(difficulty);
            locationData.ExtraDiggingItemRarity = probability;
        }
Example #26
0
        /// <summary>
        /// Gets a random fish difficulty value
        /// </summary>
        /// <returns>
        /// 25% Easy: 15 - 30
        /// 45% Moderate: 31 - 50
        /// 25% Difficult: 51 - 75
        /// 5% WTF: 76 - 95
        /// 0% Legendary: 96 - 110
        /// </returns>
        private static int GenerateRandomFishDifficulty()
        {
            int difficultyRange = Range.GetRandomValue(1, 100);

            if (difficultyRange < 26)
            {
                return(Range.GetRandomValue(15, 30));
            }
            else if (difficultyRange < 71)
            {
                return(Range.GetRandomValue(31, 50));
            }
            else if (difficultyRange < 96)
            {
                return(Range.GetRandomValue(51, 75));
            }
            else
            {
                return(Range.GetRandomValue(76, 95));
            }
        }
Example #27
0
        /// <summary>
        /// Generates the reward for the bundle
        /// </summary>
        protected override void GenerateReward()
        {
            List <RequiredItem> potentialRewards = new List <RequiredItem>
            {
                new RequiredItem((int)ObjectIndexes.GoldBar, Range.GetRandomValue(5, 25)),
                new RequiredItem((int)ObjectIndexes.IridiumBar, Range.GetRandomValue(1, 5)),
                new RequiredItem((int)ObjectIndexes.SolidGoldLewis),
                new RequiredItem((int)ObjectIndexes.HMTGF),
                new RequiredItem((int)ObjectIndexes.PinkyLemon),
                new RequiredItem((int)ObjectIndexes.Foroguemon),
                new RequiredItem((int)ObjectIndexes.GoldenPumpkin),
                new RequiredItem((int)ObjectIndexes.GoldenMask),
                new RequiredItem((int)ObjectIndexes.GoldenRelic),
                new RequiredItem((int)ObjectIndexes.GoldBrazier),
                new RequiredItem((int)ObjectIndexes.TreasureChest),
                new RequiredItem((int)ObjectIndexes.Lobster, Range.GetRandomValue(5, 25)),
                new RequiredItem((int)ObjectIndexes.LobsterBisque, Range.GetRandomValue(5, 25))
            };

            Reward = Globals.RNGGetRandomValueFromList(potentialRewards);
        }
        /// <summary>
        /// Assigns the weapon's speed
        /// - 5% chance of max speed
        /// - 10% chance of slow speed (-16 to -1)
        /// - 50% chance of 0
        /// - Else, value from -8 to 8
        /// </summary>
        /// <param name="weapon">The weapon to set the speed for</param>
        private static void RandomizeWeaponSpeed(WeaponItem weapon)
        {
            if (Globals.RNGGetNextBoolean(5))
            {
                weapon.Speed = 308;
            }

            else if (Globals.RNGGetNextBoolean(10))
            {
                weapon.Speed = Range.GetRandomValue(-16, -1);
            }

            else if (Globals.RNGGetNextBoolean())
            {
                weapon.Speed = 0;
            }

            else
            {
                weapon.Speed = Range.GetRandomValue(-8, 8);
            }
        }
        /// <summary>
        /// Randomizes the weapon drop info (where you receive weapons in mine containers).
        /// This does not affect galaxy items.
        /// - If you currently can't receive the weapon in the mines, set its base floor based on its max damage
        ///   - less than 10: floor between 1 and 20
        ///   - less than 30: floor between 21 and 60
        ///   - less than 50: floor between 61 and 100
        ///   - else: floor between 110 and 110
        /// - else, set the base floor to be + or - 10 floors of the original value
        ///
        /// In either case, set the min floor to be between 10 and 30 floors lower than the base
        /// </summary>
        /// <param name="weapon">The weapon to set drop info for</param>
        private static void RandomizeWeaponDropInfo(WeaponItem weapon)
        {
            if (!weapon.ShouldRandomizeDropInfo())
            {
                return;
            }

            int baseMineLevel = weapon.BaseMineLevelDrop;

            if (baseMineLevel == -1)
            {
                int maxDamage = weapon.Damage.MaxValue;
                if (maxDamage < 10)
                {
                    baseMineLevel = Range.GetRandomValue(1, 20);
                }
                else if (maxDamage < 30)
                {
                    baseMineLevel = Range.GetRandomValue(21, 60);
                }
                else if (maxDamage < 50)
                {
                    baseMineLevel = Range.GetRandomValue(61, 100);
                }
                else
                {
                    baseMineLevel = Range.GetRandomValue(101, 110);
                }
            }

            else
            {
                baseMineLevel = FixMineLevelValue(baseMineLevel + Range.GetRandomValue(-10, 10));
            }

            weapon.BaseMineLevelDrop = baseMineLevel;
            weapon.MinMineLevelDrop  = FixMineLevelValue(baseMineLevel - Range.GetRandomValue(10, 30), true);
        }
Example #30
0
        /// <summary>
        /// Populates the bundle with the name, required items, minimum required, and color
        /// </summary>
        protected override void Populate()
        {
            BundleType = Globals.RNGGetAndRemoveRandomValueFromList(RoomBundleTypes);
            List <RequiredItem> potentialItems = new List <RequiredItem>();

            switch (BundleType)
            {
            case BundleTypes.FishTankSpringFish:
                GenerateSeasonBundle(Seasons.Spring, BundleColors.Green);
                break;

            case BundleTypes.FishTankSummerFish:
                GenerateSeasonBundle(Seasons.Summer, BundleColors.Red);
                break;

            case BundleTypes.FishTankFallFish:
                GenerateSeasonBundle(Seasons.Fall, BundleColors.Orange);
                break;

            case BundleTypes.FishTankWinterFish:
                GenerateSeasonBundle(Seasons.Winter, BundleColors.Cyan);
                break;

            case BundleTypes.FishTankOceanFood:
                Name           = Globals.GetTranslation("bundle-fishtank-ocean-food");
                potentialItems = RequiredItem.CreateList(new List <int>
                {
                    (int)ObjectIndexes.CrispyBass,
                    (int)ObjectIndexes.FriedEel,
                    (int)ObjectIndexes.AlgaeSoup,
                    (int)ObjectIndexes.CrabCakes,
                    (int)ObjectIndexes.SpicyEel,
                    (int)ObjectIndexes.PaleBroth,
                    (int)ObjectIndexes.Sashimi,
                    (int)ObjectIndexes.MakiRoll,
                    (int)ObjectIndexes.TomKhaSoup,
                    (int)ObjectIndexes.BakedFish,
                    (int)ObjectIndexes.TroutSoup,
                    (int)ObjectIndexes.Chowder,
                    (int)ObjectIndexes.LobsterBisque,
                    (int)ObjectIndexes.DishOTheSea,
                    (int)ObjectIndexes.FishStew,
                    (int)ObjectIndexes.FriedCalamari,
                    (int)ObjectIndexes.SalmonDinner,
                    (int)ObjectIndexes.FishTaco
                });
                RequiredItems        = Globals.RNGGetRandomValuesFromList(potentialItems, 8);
                MinimumRequiredItems = 4;
                Color = BundleColors.Yellow;
                break;

            case BundleTypes.FishTankLegendary:
                Name                 = Globals.GetTranslation("bundle-fishtank-legendary");
                RequiredItems        = RequiredItem.CreateList(FishItem.GetLegendaries().Cast <Item>().ToList());
                MinimumRequiredItems = Range.GetRandomValue(3, 4);
                Color                = BundleColors.Red;
                break;

            case BundleTypes.FishTankLocation:
                List <Locations> locations = new List <Locations>
                {
                    Locations.Town,
                    Locations.Mountain,
                    Locations.Desert,
                    Locations.Woods,
                    Locations.Forest,
                    Locations.NightMarket,
                    Locations.Beach
                };
                Locations location       = Globals.RNGGetRandomValueFromList(locations);
                string    locationString = Globals.GetTranslation($"fish-{location.ToString().ToLower()}-location");

                Name                 = Globals.GetTranslation("bundle-fishtank-location", new { location = locationString });
                RequiredItems        = RequiredItem.CreateList(Globals.RNGGetRandomValuesFromList(FishItem.Get(location), 8));
                MinimumRequiredItems = Math.Min(RequiredItems.Count, Range.GetRandomValue(2, 4));
                Color                = BundleColors.Blue;
                break;

            case BundleTypes.FishTankRainFish:
                Name          = Globals.GetTranslation("bundle-fishtank-rain-fish");
                RequiredItems = RequiredItem.CreateList(
                    Globals.RNGGetRandomValuesFromList(FishItem.Get(Weather.Rainy), 8)
                    );
                MinimumRequiredItems = Math.Min(RequiredItems.Count, 4);
                Color = BundleColors.Blue;
                break;

            case BundleTypes.FishTankNightFish:
                Name          = Globals.GetTranslation("bundle-fishtank-night-fish");
                RequiredItems = RequiredItem.CreateList(
                    Globals.RNGGetRandomValuesFromList(FishItem.GetNightFish(), 8)
                    );
                MinimumRequiredItems = Math.Min(RequiredItems.Count, 4);
                Color = BundleColors.Purple;
                break;

            case BundleTypes.FishTankQualityFish:
                Name           = Globals.GetTranslation("bundle-fishtank-quality-fish");
                potentialItems = RequiredItem.CreateList(
                    Globals.RNGGetRandomValuesFromList(FishItem.Get(), 8)
                    );
                potentialItems.ForEach(x => x.MinimumQuality = ItemQualities.Gold);
                RequiredItems        = potentialItems;
                MinimumRequiredItems = 4;
                Color = BundleColors.Yellow;
                break;

            case BundleTypes.FishTankBeachForagables:
                Name          = Globals.GetTranslation("bundle-fishtank-beach-foragables");
                RequiredItems = RequiredItem.CreateList(
                    Globals.RNGGetRandomValuesFromList(ItemList.GetUniqueBeachForagables(), 6)
                    );
                Color = BundleColors.Yellow;
                break;

            case BundleTypes.FishTankFishingTools:
                Name           = Globals.GetTranslation("bundle-fishtank-fishing-tools");
                potentialItems = new List <RequiredItem>
                {
                    new RequiredItem((int)ObjectIndexes.Spinner, 1),
                    new RequiredItem((int)ObjectIndexes.DressedSpinner, 1),
                    new RequiredItem((int)ObjectIndexes.TrapBobber, 1),
                    new RequiredItem((int)ObjectIndexes.CorkBobber, 1),
                    new RequiredItem((int)ObjectIndexes.LeadBobber, 1),
                    new RequiredItem((int)ObjectIndexes.TreasureHunter, 1),
                    new RequiredItem((int)ObjectIndexes.Bait, 25, 50),
                    new RequiredItem((int)ObjectIndexes.WildBait, 10, 20)
                };
                RequiredItems = Globals.RNGGetRandomValuesFromList(potentialItems, 4);
                Color         = BundleColors.Blue;
                break;

            case BundleTypes.FishTankUnique:
                Name = Globals.GetTranslation("bundle-fishtank-unique");

                List <Item> nightFish  = FishItem.Get(Locations.NightMarket);
                List <Item> minesFish  = FishItem.Get(Locations.UndergroundMine);
                List <Item> desertFish = FishItem.Get(Locations.Desert);
                List <Item> woodsFish  = FishItem.Get(Locations.Woods);

                RequiredItems = new List <RequiredItem>
                {
                    new RequiredItem(Globals.RNGGetRandomValueFromList(nightFish)),
                    new RequiredItem(Globals.RNGGetRandomValueFromList(minesFish)),
                    new RequiredItem(Globals.RNGGetRandomValueFromList(desertFish)),
                    new RequiredItem(Globals.RNGGetRandomValueFromList(woodsFish))
                };
                MinimumRequiredItems = Range.GetRandomValue(RequiredItems.Count - 1, RequiredItems.Count);
                Color = BundleColors.Cyan;
                break;

            case BundleTypes.FishTankColorBlue:
                Name = Globals.GetTranslation("bundle-fishtank-blue");

                potentialItems = RequiredItem.CreateList(new List <int>
                {
                    (int)ObjectIndexes.Aquamarine,
                    (int)ObjectIndexes.Diamond,
                    (int)ObjectIndexes.FrozenTear,
                    (int)ObjectIndexes.DwarfScrollIII,
                    (int)ObjectIndexes.ElvishJewelry,
                    (int)ObjectIndexes.GlassShards,
                    (int)ObjectIndexes.Anchovy,
                    (int)ObjectIndexes.Tuna,
                    (int)ObjectIndexes.Sardine,
                    (int)ObjectIndexes.Bream,
                    (int)ObjectIndexes.Salmon,
                    (int)ObjectIndexes.Herring,
                    (int)ObjectIndexes.Squid,
                    (int)ObjectIndexes.IcePip,
                    (int)ObjectIndexes.Sturgeon,
                    (int)ObjectIndexes.Albacore,
                    (int)ObjectIndexes.MidnightSquid,
                    (int)ObjectIndexes.SpookFish,
                    (int)ObjectIndexes.Glacierfish,
                    (int)ObjectIndexes.Clam,
                    (int)ObjectIndexes.Periwinkle,
                    (int)ObjectIndexes.JojaCola,
                    (int)ObjectIndexes.BrokenGlasses,
                    (int)ObjectIndexes.BrokenCD,
                    (int)ObjectIndexes.BlueberryTart,
                    (int)ObjectIndexes.Sugar,
                    (int)ObjectIndexes.BasicRetainingSoil,
                    (int)ObjectIndexes.QualityRetainingSoil,
                    (int)ObjectIndexes.RainbowShell,
                    (int)ObjectIndexes.BlueSlimeEgg,
                    (int)ObjectIndexes.CrystalFruit,
                    (int)ObjectIndexes.SturdyRing,
                    (int)ObjectIndexes.AquamarineRing,
                    (int)ObjectIndexes.FrozenGeode,
                    (int)ObjectIndexes.Opal,
                    (int)ObjectIndexes.Aerinite,
                    (int)ObjectIndexes.Kyanite,
                    (int)ObjectIndexes.GhostCrystal,
                    (int)ObjectIndexes.Celestine,
                    (int)ObjectIndexes.Soapstone,
                    (int)ObjectIndexes.Slate,
                    (int)ObjectIndexes.Spinner,
                    (int)ObjectIndexes.WarpTotemBeach,
                    (int)ObjectIndexes.Battery
                });
                RequiredItems        = Globals.RNGGetRandomValuesFromList(potentialItems, 8);
                MinimumRequiredItems = Range.GetRandomValue(3, 6);
                Color = BundleColors.Blue;
                break;

            case BundleTypes.FishTankColorPurple:
                Name           = Globals.GetTranslation("bundle-fishtank-purple");
                potentialItems = RequiredItem.CreateList(new List <int>
                {
                    (int)ObjectIndexes.Amethyst,
                    (int)ObjectIndexes.AncientDrum,
                    (int)ObjectIndexes.SuperCucumber,
                    (int)ObjectIndexes.PumpkinSoup,
                    (int)ObjectIndexes.RootsPlatter,
                    (int)ObjectIndexes.IridiumBar,
                    (int)ObjectIndexes.Wine,
                    (int)ObjectIndexes.IridiumOre,
                    (int)ObjectIndexes.SeaUrchin,
                    (int)ObjectIndexes.SweetPea,
                    (int)ObjectIndexes.WildPlum,
                    (int)ObjectIndexes.Blackberry,
                    (int)ObjectIndexes.Crocus,
                    (int)ObjectIndexes.Vinegar,
                    (int)ObjectIndexes.PurpleMushroom,
                    (int)ObjectIndexes.SpeedGro,
                    (int)ObjectIndexes.DeluxeSpeedGro,
                    (int)ObjectIndexes.IridiumBand,
                    (int)ObjectIndexes.AmethystRing,
                    (int)ObjectIndexes.FireOpal,
                    (int)ObjectIndexes.Fluorapatite,
                    (int)ObjectIndexes.Obsidian,
                    (int)ObjectIndexes.FairyStone,
                    (int)ObjectIndexes.BlackberryCobbler,
                    (int)ObjectIndexes.IridiumSprinkler,
                    (int)ObjectIndexes.DressedSpinner
                });
                RequiredItems        = Globals.RNGGetRandomValuesFromList(potentialItems, 8);
                MinimumRequiredItems = Range.GetRandomValue(3, 6);
                Color = BundleColors.Purple;
                break;
            }
        }