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