    001    package net.minecraftforge.common;
    002
    003    import java.util.ArrayList;
    004    import java.util.Random;
    005
    006    import net.minecraft.item.Item;
    007    import net.minecraft.item.ItemStack;
    008    import net.minecraft.util.WeightedRandom;
    009    import net.minecraft.util.WeightedRandomItem;
    010
    011    public class DungeonHooks
    012    {
    013        private static int dungeonLootAttempts = 8;
    014        private static ArrayList<DungeonMob> dungeonMobs = new ArrayList<DungeonMob>();
    015        private static ArrayList<DungeonLoot> dungeonLoot = new ArrayList<DungeonLoot>();
    016        /**
    017         * Set the number of item stacks that will be attempted to be added to each Dungeon chest.
    018         * Note: Due to random number generation, you will not always get this amount per chest.
    019         * @param number The maximum number of item stacks to add to a chest.
    020         */
    021        public static void setDungeonLootTries(int number)
    022        {
    023            dungeonLootAttempts = number;
    024        }
    025
    026        /**
    027         * @return The max number of item stacks found in each dungeon chest.
    028         */
    029        public static int getDungeonLootTries()
    030        {
    031            return dungeonLootAttempts;
    032        }
    033
    034        /**
    035         * Adds a mob to the possible list of creatures the spawner will create.
    036         * If the mob is already in the spawn list, the rarity will be added to the existing one,
    037         * causing the mob to be more common.
    038         *
    039         * @param name The name of the monster, use the same name used when registering the entity.
    040         * @param rarity The rarity of selecting this mob over others. Must be greater then 0.
    041         *        Vanilla Minecraft has the following mobs:
    042         *        Spider   100
    043         *        Skeleton 100
    044         *        Zombie   200
    045         *        Meaning, Zombies are twice as common as spiders or skeletons.
    046         * @return The new rarity of the monster,
    047         */
    048        public static float addDungeonMob(String name, int rarity)
    049        {
    050            if (rarity <= 0)
    051            {
    052                throw new IllegalArgumentException("Rarity must be greater then zero");
    053            }
    054
    055            for (DungeonMob mob : dungeonMobs)
    056            {
    057                if (name.equals(mob.type))
    058                {
    059                    return mob.itemWeight += rarity;
    060                }
    061            }
    062
    063            dungeonMobs.add(new DungeonMob(rarity, name));
    064            return rarity;
    065        }
    066
    067        /**
    068         * Will completely remove a Mob from the dungeon spawn list.
    069         *
    070         * @param name The name of the mob to remove
    071         * @return The rarity of the removed mob, prior to being removed.
    072         */
    073        public static int removeDungeonMob(String name)
    074        {
    075            for (DungeonMob mob : dungeonMobs)
    076            {
    077                if (name.equals(mob.type))
    078                {
    079                    dungeonMobs.remove(mob);
    080                    return mob.itemWeight;
    081                }
    082            }
    083            return 0;
    084        }
    085
    086        /**
    087         * Gets a random mob name from the list.
    088         * @param rand World generation random number generator
    089         * @return The mob name
    090         */
    091        public static String getRandomDungeonMob(Random rand)
    092        {
    093            DungeonMob mob = (DungeonMob)WeightedRandom.getRandomItem(rand, dungeonMobs);
    094            if (mob == null)
    095            {
    096                return "";
    097            }
    098            return mob.type;
    099        }
    100
    101        /**
    102         * Adds a item stack to the dungeon loot list with a stack size
    103         * of 1.
    104         *
    105         * @param item The ItemStack to be added to the loot list
    106         * @param rarity The relative chance that this item will spawn, Vanilla has
    107         *          most of its items set to 1. Like the saddle, bread, silk, wheat, etc..
    108         *          Rarer items are set to lower values, EXA: Golden Apple 0.01
    109         */
    110        public static void addDungeonLoot(ItemStack item, int rarity)
    111        {
    112            addDungeonLoot(item, rarity, 1, 1);
    113        }
    114
    115        /**
    116         * Adds a item stack, with a range of sizes, to the dungeon loot list.
    117         * If a stack matching the same item, and size range, is already in the list
    118         * the rarities will be added together making the item more common.
    119         *
    120         * @param item The ItemStack to be added to the loot list
    121         * @param rarity The relative chance that this item will spawn, Vanilla has
    122         *          most of its items set to 1. Like the saddle, bread, silk, wheat, etc..
    123         *          Rarer items are set to lower values, EXA: Golden Apple 0.01
    124         * @param minCount When this item does generate, the minimum number that is in the stack
    125         * @param maxCount When this item does generate, the maximum number that can bein the stack
    126         * @return The new rarity of the loot.
    127         */
    128        public static float addDungeonLoot(ItemStack item, int rarity, int minCount, int maxCount)
    129        {
    130            for (DungeonLoot loot : dungeonLoot)
    131            {
    132                if (loot.equals(item, minCount, maxCount))
    133                {
    134                    return loot.itemWeight += rarity;
    135                }
    136            }
    137
    138            dungeonLoot.add(new DungeonLoot(rarity, item, minCount, maxCount));
    139            return rarity;
    140        }
    141        /**
    142         * Removes a item stack from the dungeon loot list, this will remove all items
    143         * as long as the item stack matches, it will not care about matching the stack
    144         * size ranges perfectly.
    145         *
    146         * @param item The item stack to remove
    147         */
    148        public static void removeDungeonLoot(ItemStack item)
    149        {
    150            removeDungeonLoot(item, -1, 0);
    151        }
    152
    153        /**
    154         * Removes a item stack from the dungeon loot list. If 'minCount' parameter
    155         * is greater then 0, it will only remove loot items that have the same exact
    156         * stack size range as passed in by parameters.
    157         *
    158         * @param item The item stack to remove
    159         * @param minCount The minimum count for the match check, if less then 0,
    160         *          the size check is skipped
    161         * @param maxCount The max count used in match check when 'minCount' is >= 0
    162         */
    163        public static void removeDungeonLoot(ItemStack item, int minCount, int maxCount)
    164        {
    165            ArrayList<DungeonLoot> lootTmp = (ArrayList<DungeonLoot>)dungeonLoot.clone();
    166            if (minCount < 0)
    167            {
    168                for (DungeonLoot loot : lootTmp)
    169                {
    170                    if (loot.equals(item))
    171                    {
    172                        dungeonLoot.remove(loot);
    173                    }
    174                }
    175            }
    176            else
    177            {
    178                for (DungeonLoot loot : lootTmp)
    179                {
    180                    if (loot.equals(item, minCount, maxCount))
    181                    {
    182                        dungeonLoot.remove(loot);
    183                    }
    184                }
    185            }
    186        }
    187
    188        /**
    189         * Gets a random item stack to place in a dungeon chest during world generation
    190         * @param rand World generation random number generator
    191         * @return The item stack
    192         */
    193        public static ItemStack getRandomDungeonLoot(Random rand)
    194        {
    195            DungeonLoot ret = (DungeonLoot)WeightedRandom.getRandomItem(rand, dungeonLoot);
    196            if (ret != null)
    197            {
    198                return ret.generateStack(rand);
    199            }
    200            return null;
    201        }
    202
    203        public static class DungeonLoot extends WeightedRandomItem
    204        {
    205            private ItemStack itemStack;
    206            private int minCount = 1;
    207            private int maxCount = 1;
    208
    209            /**
    210             * @param item A item stack
    211             * @param min Minimum stack size when randomly generating
    212             * @param max Maximum stack size when randomly generating
    213             */
    214            public DungeonLoot(int weight, ItemStack item, int min, int max)
    215            {
    216                super(weight);
    217                this.itemStack = item;
    218                minCount = min;
    219                maxCount = max;
    220            }
    221
    222            /**
    223             * Grabs a ItemStack ready to be added to the dungeon chest,
    224             * the stack size will be between minCount and maxCount
    225             * @param rand World gen random number generator
    226             * @return The ItemStack to be added to the chest
    227             */
    228            public ItemStack generateStack(Random rand)
    229            {
    230                ItemStack ret = this.itemStack.copy();
    231                ret.stackSize = minCount + (rand.nextInt(maxCount - minCount + 1));
    232                return ret;
    233            }
    234
    235            public boolean equals(ItemStack item, int min, int max)
    236            {
    237                return (min == minCount && max == maxCount && item.isItemEqual(this.itemStack));
    238            }
    239
    240            public boolean equals(ItemStack item)
    241            {
    242                return item.isItemEqual(this.itemStack);
    243            }
    244        }
    245
    246        public static class DungeonMob extends WeightedRandomItem
    247        {
    248            public String type;
    249            public DungeonMob(int weight, String type)
    250            {
    251                super(weight);
    252                this.type = type;
    253            }
    254
    255            @Override
    256            public boolean equals(Object target)
    257            {
    258                if (target instanceof DungeonMob)
    259                {
    260                    return this.type.equals(((DungeonMob)target).type);
    261                }
    262                return false;
    263            }
    264        }
    265
    266        public void addDungeonLoot(DungeonLoot loot)
    267        {
    268            dungeonLoot.add(loot);
    269        }
    270
    271        public boolean removeDungeonLoot(DungeonLoot loot)
    272        {
    273            return dungeonLoot.remove(loot);
    274        }
    275
    276        static
    277        {
    278            addDungeonMob("Skeleton", 100);
    279            addDungeonMob("Zombie",   200);
    280            addDungeonMob("Spider",   100);
    281
    282            addDungeonLoot(new ItemStack(Item.saddle),          100      );
    283            addDungeonLoot(new ItemStack(Item.ingotIron),       100, 1, 4);
    284            addDungeonLoot(new ItemStack(Item.bread),           100      );
    285            addDungeonLoot(new ItemStack(Item.wheat),           100, 1, 4);
    286            addDungeonLoot(new ItemStack(Item.gunpowder),       100, 1, 4);
    287            addDungeonLoot(new ItemStack(Item.silk),            100, 1, 4);
    288            addDungeonLoot(new ItemStack(Item.bucketEmpty),     100      );
    289            addDungeonLoot(new ItemStack(Item.appleGold),       001      );
    290            addDungeonLoot(new ItemStack(Item.redstone),        050, 1, 4);
    291            addDungeonLoot(new ItemStack(Item.record13),        005      );
    292            addDungeonLoot(new ItemStack(Item.recordCat),       005      );
    293            addDungeonLoot(new ItemStack(Item.dyePowder, 1, 3), 100      );
    294        }
    295    }