/// <summary>
        /// Generates an array of items based on loot chance matrix.
        /// </summary>
        /// <param name="matrix">Loot chance matrix.</param>
        /// <param name="playerEntity">Player entity.</param>
        /// <returns>DaggerfallUnityItem array.</returns>
        public static DaggerfallUnityItem[] GenerateRandomLoot(LootChanceMatrix matrix, PlayerEntity playerEntity)
        {
            // Notes: The first part of the DF Chronicles explanation of how loot is generated does not match the released game.
            // It says the chance for each item category is the matrix amount * the level of the NPC. Actual behavior in the
            // released game is (matrix amount * PC level) for the first 4 item categories (temperate plants, warm plants,
            // miscellaneous monster, warm monster), and just matrix amount for the categories after that.
            // The second part of the DF Chronicles explanation (roll repeatedly for items from a category, each time at halved
            // chance), matches the game.
            // In classic, since a 0-99 roll is compared to whether it is less or greater than item chance,
            // even a 0% chance category has a 1/100 chance to appear, and the chance values are effectively
            // 1 higher than what the loot tables show.
            float chance;
            List <DaggerfallUnityItem> items = new List <DaggerfallUnityItem>();

            // Reseed random
            Random.InitState(items.GetHashCode());

            // Random gold
            int goldCount = Random.Range(matrix.MinGold, matrix.MaxGold + 1) * playerEntity.Level;

            if (goldCount > 0)
            {
                items.Add(ItemBuilder.CreateGoldPieces(goldCount));
            }

            // Random weapon
            chance = matrix.WP;
            while (Dice100.SuccessRoll((int)chance))
            {
                items.Add(ItemBuilder.CreateRandomWeapon(playerEntity.Level));
                chance *= 0.5f;
            }

            // Random armor
            chance = matrix.AM;
            while (Dice100.SuccessRoll((int)chance))
            {
                items.Add(ItemBuilder.CreateRandomArmor(playerEntity.Level, playerEntity.Gender, playerEntity.Race));
                chance *= 0.5f;
            }

            // Random ingredients
            RandomIngredient(matrix.C1 * playerEntity.Level, ItemGroups.CreatureIngredients1, items);
            RandomIngredient(matrix.C2 * playerEntity.Level, ItemGroups.CreatureIngredients2, items);
            RandomIngredient(matrix.C3, ItemGroups.CreatureIngredients3, items);
            RandomIngredient(matrix.P1 * playerEntity.Level, ItemGroups.PlantIngredients1, items);
            RandomIngredient(matrix.P2 * playerEntity.Level, ItemGroups.PlantIngredients2, items);
            RandomIngredient(matrix.M1, ItemGroups.MiscellaneousIngredients1, items);
            RandomIngredient(matrix.M2, ItemGroups.MiscellaneousIngredients2, items);

            // Random magic item
            chance = matrix.MI;
            while (Dice100.SuccessRoll((int)chance))
            {
                items.Add(ItemBuilder.CreateRandomMagicItem(playerEntity.Level, playerEntity.Gender, playerEntity.Race));
                chance *= 0.5f;
            }

            // Random clothes
            chance = matrix.CL;
            while (Dice100.SuccessRoll((int)chance))
            {
                items.Add(ItemBuilder.CreateRandomClothing(playerEntity.Gender, playerEntity.Race));
                chance *= 0.5f;
            }

            // Random books
            chance = matrix.BK;
            while (Dice100.SuccessRoll((int)chance))
            {
                items.Add(ItemBuilder.CreateRandomBook());
                chance *= 0.5f;
            }

            // Random religious item
            chance = matrix.RL;
            while (Dice100.SuccessRoll((int)chance))
            {
                items.Add(ItemBuilder.CreateRandomReligiousItem());
                chance *= 0.5f;
            }

            return(items.ToArray());
        }
Exemple #2
0
        /// <summary>
        /// Generates an array of items based on loot chance matrix.
        /// </summary>
        /// <param name="key">Starting loot table key. Used for special handling.</param>
        /// <param name="matrix">Loot chance matrix.</param>
        /// <param name="playerLevel">Level of player.</param>
        /// <returns>DaggerfallUnityItem array.</returns>
        public static DaggerfallUnityItem[] GenerateRandomLoot(string key, LootChanceMatrix matrix, PlayerEntity playerEntity)
        {
            float chance;
            List <DaggerfallUnityItem> items = new List <DaggerfallUnityItem>();

            // Random gold
            int goldCount = Random.Range(matrix.MinGold, matrix.MaxGold) * playerEntity.Level;

            if (goldCount > 0)
            {
                items.Add(ItemBuilder.CreateGoldPieces(goldCount));
            }

            // Random weapon
            chance = matrix.WP * playerEntity.Level;
            while (Random.Range(1, 100) < chance)
            {
                items.Add(ItemBuilder.CreateRandomWeapon(playerEntity.Level));
                chance *= 0.5f;
            }

            // Random armor
            chance = matrix.AM * playerEntity.Level;
            while (Random.Range(1, 100) < chance)
            {
                items.Add(ItemBuilder.CreateRandomArmor(playerEntity.Level, playerEntity.Gender, playerEntity.Race));
                chance *= 0.5f;
            }

            // Random ingredients
            RandomIngredient(matrix.C1 * playerEntity.Level, ItemGroups.CreatureIngredients1, items);
            RandomIngredient(matrix.C2 * playerEntity.Level, ItemGroups.CreatureIngredients2, items);
            RandomIngredient(matrix.C3 * playerEntity.Level, ItemGroups.CreatureIngredients3, items);
            RandomIngredient(matrix.P1 * playerEntity.Level, ItemGroups.PlantIngredients1, items);
            RandomIngredient(matrix.P2 * playerEntity.Level, ItemGroups.PlantIngredients2, items);
            RandomIngredient(matrix.M1 * playerEntity.Level, ItemGroups.MiscellaneousIngredients1, items);
            RandomIngredient(matrix.M2 * playerEntity.Level, ItemGroups.MiscellaneousIngredients2, items);

            // TEMP: Magic item chance is just another shot at armor or weapon for now
            chance = matrix.MI * playerEntity.Level;
            while (Random.Range(1, 100) < chance)
            {
                if (Random.value < 0.5f)
                {
                    items.Add(ItemBuilder.CreateRandomWeapon(playerEntity.Level));
                }
                else
                {
                    items.Add(ItemBuilder.CreateRandomArmor(playerEntity.Level, playerEntity.Gender, playerEntity.Race));
                }

                chance *= 0.5f;
            }

            // Random clothes
            chance = matrix.CL * playerEntity.Level;
            while (Random.Range(1, 100) < chance)
            {
                items.Add(ItemBuilder.CreateRandomClothing(playerEntity.Gender));
                chance *= 0.5f;
            }

            // Random religious item
            chance = matrix.RL * playerEntity.Level;
            while (Random.Range(1, 100) < chance)
            {
                items.Add(ItemBuilder.CreateRandomReligiousItem());
                chance *= 0.5f;
            }

            // Special humanoid handling
            // Daggerfall seems to always drop between 1-3 weapons and 2-5 armor pieces regardless of player level
            // This is probably totally off track, but for now generating closer results than loot table alone
            // TODO: Revisit humanoid loot tables later
            if (key == "HM")
            {
                // Create 1-3 weapons
                int count = Random.Range(1, 3);
                for (int i = 0; i < count; i++)
                {
                    items.Add(ItemBuilder.CreateRandomWeapon(playerEntity.Level));
                }

                // Create 2-5 armor pieces
                count = Random.Range(2, 5);
                for (int i = 0; i < count; i++)
                {
                    items.Add(ItemBuilder.CreateRandomArmor(playerEntity.Level, playerEntity.Gender, playerEntity.Race));
                }
            }

            return(items.ToArray());
        }