    001    package net.minecraftforge.common;
    002
    003    import java.util.*;
    004
    005    import net.minecraft.src.*;
    006
    007    public class ChestGenHooks
    008    {
    009        //Currently implemented categories for chests/dispensers, Dungeon loot is still in DungeonHooks
    010        public static final String MINESHAFT_CORRIDOR       = "mineshaftCorridor";
    011        public static final String PYRAMID_DESERT_CHEST     = "pyramidDesertyChest";
    012        public static final String PYRAMID_JUNGLE_CHEST     = "pyramidJungleChest";
    013        public static final String PYRAMID_JUNGLE_DISPENSER = "pyramidJungleDispenser";
    014        public static final String STRONGHOLD_CORRIDOR      = "strongholdCorridor";
    015        public static final String STRONGHOLD_LIBRARY       = "strongholdLibrary";
    016        public static final String STRONGHOLD_CROSSING      = "strongholdCrossing";
    017        public static final String VILLAGE_BLACKSMITH       = "villageBlacksmith";
    018        public static final String BONUS_CHEST              = "bonusChest";
    019
    020        private static final HashMap<String, ChestGenHooks> chestInfo = new HashMap<String, ChestGenHooks>();
    021        private static boolean hasInit = false;
    022        static
    023        {
    024            init();
    025        }
    026
    027        private static void init()
    028        {
    029            if (hasInit)
    030            {
    031                return;
    032            }
    033            addInfo(MINESHAFT_CORRIDOR,       StructureMineshaftPieces.mineshaftChestContents,                         3,  7);
    034            addInfo(PYRAMID_DESERT_CHEST,     ComponentScatteredFeatureDesertPyramid.itemsToGenerateInTemple,          2,  7);
    035            addInfo(PYRAMID_JUNGLE_CHEST,     ComponentScatteredFeatureJunglePyramid.junglePyramidsChestContents,      2,  7);
    036            addInfo(PYRAMID_JUNGLE_DISPENSER, ComponentScatteredFeatureJunglePyramid.junglePyramidsDispenserContents,  2,  2);
    037            addInfo(STRONGHOLD_CORRIDOR,      ComponentStrongholdChestCorridor.strongholdChestContents,                2,  4);
    038            addInfo(STRONGHOLD_LIBRARY,       ComponentStrongholdLibrary.strongholdLibraryChestContents,               1,  5);
    039            addInfo(STRONGHOLD_CROSSING,      ComponentStrongholdRoomCrossing.strongholdRoomCrossingChestContents,                           1,  5);
    040            addInfo(VILLAGE_BLACKSMITH,       ComponentVillageHouse2.villageBlacksmithChestContents,                   3,  9);
    041            addInfo(BONUS_CHEST,              WorldServer.bonusChestContent,                                          10, 10);
    042        }
    043
    044        private static void addInfo(String category, WeightedRandomChestContent[] items, int min, int max)
    045        {
    046            chestInfo.put(category, new ChestGenHooks(category, items, min, max));
    047        }
    048
    049        /**
    050         * Retrieves, or creates the info class for the specified category.
    051         *
    052         * @param category The category name
    053         * @return A instance of ChestGenHooks for the specified category.
    054         */
    055        public static ChestGenHooks getInfo(String category)
    056        {
    057            if (!chestInfo.containsKey(category))
    058            {
    059                chestInfo.put(category, new ChestGenHooks(category));
    060            }
    061            return chestInfo.get(category);
    062        }
    063
    064        /**
    065         * Generates an array of items based on the input min/max count.
    066         * If the stack can not hold the total amount, it will be split into
    067         * stacks of size 1.
    068         *
    069         * @param rand A random number generator
    070         * @param source Source item stack
    071         * @param min Minimum number of items
    072         * @param max Maximum number of items
    073         * @return An array containing the generated item stacks
    074         */
    075        public static ItemStack[] generateStacks(Random rand, ItemStack source, int min, int max)
    076        {
    077            int count = min + (rand.nextInt(max - min + 1));
    078
    079            ItemStack[] ret;
    080            if (source.getItem() == null)
    081            {
    082                ret = new ItemStack[0];
    083            }
    084            else if (count > source.getItem().getItemStackLimit())
    085            {
    086                ret = new ItemStack[count];
    087                for (int x = 0; x < count; x++)
    088                {
    089                    ret[x] = source.copy();
    090                    ret[x].stackSize = 1;
    091                }
    092            }
    093            else
    094            {
    095                ret = new ItemStack[1];
    096                ret[0] = source.copy();
    097                ret[0].stackSize = count;
    098            }
    099            return ret;
    100        }
    101
    102        //shortcut functions, See the non-static versions below
    103        public static WeightedRandomChestContent[] getItems(String category){ return getInfo(category).getItems(); }
    104        public static int getCount(String category, Random rand){ return getInfo(category).getCount(rand); }
    105        public static void addItem(String category, WeightedRandomChestContent item){ getInfo(category).addItem(item); }
    106        public static void removeItem(String category, ItemStack item){ getInfo(category).removeItem(item); }
    107
    108        private String category;
    109        private int countMin = 0;
    110        private int countMax = 0;
    111        private ArrayList<WeightedRandomChestContent> contents = new ArrayList<WeightedRandomChestContent>();
    112
    113        public ChestGenHooks(String category)
    114        {
    115            this.category = category;
    116        }
    117
    118        public ChestGenHooks(String category, WeightedRandomChestContent[] items, int min, int max)
    119        {
    120            this(category);
    121            for (WeightedRandomChestContent item : items)
    122            {
    123                contents.add(item);
    124            }
    125            countMin = min;
    126            countMax = max;
    127        }
    128
    129        /**
    130         * Adds a new entry into the possible items to generate.
    131         *
    132         * @param item The item to add.
    133         */
    134        public void addItem(WeightedRandomChestContent item)
    135        {
    136            contents.add(item);
    137        }
    138
    139        /**
    140         * Removes all items that match the input item stack, Only metadata and item ID are checked.
    141         * If the input item has a metadata of -1, all metadatas will match.
    142         *
    143         * @param item The item to check
    144         */
    145        public void removeItem(ItemStack item)
    146        {
    147            Iterator<WeightedRandomChestContent> itr = contents.iterator();
    148            while(itr.hasNext())
    149            {
    150                WeightedRandomChestContent cont = itr.next();
    151                if (item.isItemEqual(cont.itemStack) || (item.getItemDamage() == -1 && item.itemID == cont.itemStack.itemID))
    152                {
    153                    itr.remove();
    154                }
    155            }
    156        }
    157
    158        /**
    159         * Gets an array of all random objects that are associated with this category.
    160         *
    161         * @return The random objects
    162         */
    163        public WeightedRandomChestContent[] getItems()
    164        {
    165            return contents.toArray(new WeightedRandomChestContent[contents.size()]);
    166        }
    167
    168        /**
    169         * Gets a random number between countMin and countMax.
    170         *
    171         * @param rand A RNG
    172         * @return A random number where countMin <= num <= countMax
    173         */
    174        public int getCount(Random rand)
    175        {
    176            return countMin < countMax ? countMin + rand.nextInt(countMax - countMin) : countMin;
    177        }
    178
    179        //Accessors
    180        public int getMin(){ return countMin; }
    181        public int getMax(){ return countMax; }
    182        public void setMin(int value){ countMin = value; }
    183        public void setMax(int value){ countMax = value; }
    184    }