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 }